Class: Moderate::NoticesController

Inherits:
ApplicationController show all
Defined in:
app/controllers/moderate/notices_controller.rb

Overview

The PUBLIC, regulator-facing DSA “notice and action” intake form.

The EU Digital Services Act, Article 16, requires every hosting service serving EU users to offer a PUBLIC, ELECTRONIC mechanism for ANYONE (not just logged-in users) to flag illegal content, and to ACKNOWLEDGE receipt of that notice. This controller is that mechanism — the “Report illegal content (EU)” form you see at the bottom of X / YouTube / Reddit. It is separate from the in-app “Report” button (that’s the host’s BYOUI report controller) and from the admin queue. See: eur-lex.europa.eu/eli/reg/2022/2065/oj (Article 16)

The controller is intentionally boring: it does HTTP only. All the Trust & Safety work — the Art. 16 field validations, the immutable evidence snapshot, the durable acknowledgement (Art. 16(4)), dropping the row into ‘Moderate::Report.pending`, and firing the `notice_received` confirmation-of- receipt event — lives in the model/service (`Moderate::Services::IntakeNotice` building a `Moderate::Report` with `intake_kind: “dsa”`), never here.

A notice is NOT a fourth table: it is a ‘Moderate::Report` with `intake_kind: “dsa”`, sharing the same queue, snapshot, appeal window, and Art. 24 transparency counters as an in-app report. One queue, two front doors.

Instance Method Summary collapse

Instance Method Details

#createObject

POST /notices — validate + persist as a DSA-kind Report, fire the confirmation of receipt, and show the submitter a success page. On failure we re-render the form with the model’s validation errors and a 422 (standard Rails; lets Turbo replace the form in place).



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/controllers/moderate/notices_controller.rb', line 62

def create
  @intake = Moderate::Services::IntakeNotice.new(
    attributes: notice_params,
    reporter: current_notifier
  )

  if @intake.save
    redirect_to(
      new_notice_path,
      notice: t("moderate.notices.received", default: "Notice received. We have logged your report and will review it."),
      status: :see_other
    )
  else
    @report = @intake.report
    @identity_locked = identity_locked?
    render :new, status: :unprocessable_entity
  end
end

#newObject

GET /notices/new — the form, prefilled (and partially locked) from the request.

X-style deep link: a host can link to this form from a piece of content with the reported-content details already in the query string (content_url, content_type, content_author, content_id — see #prefill_attributes), so the notifier doesn’t have to copy-paste the URL of what they’re flagging. We ALSO prefill the notifier’s identity from Devise ‘current_user` when someone happens to be logged in (the form is still public/anonymous-friendly). The view locks the auto-prefilled IDENTITY fields so they can’t be tampered with, while the reported-content fields stay fully editable. DSA Art. 16(2)(b)/©.



53
54
55
56
# File 'app/controllers/moderate/notices_controller.rb', line 53

def new
  @report = Moderate::Report.new(prefill_attributes)
  @identity_locked = identity_locked?
end