veza/veza-backend-api/migrations/rollback/988_dmca_notices_down.sql

13 lines
474 B
MySQL
Raw Normal View History

feat(legal): DMCA notice handler + admin queue + 451 playback gate (W3 Day 14) End-to-end DMCA workflow. Public submission, admin queue, takedown flips track to is_public=false + dmca_blocked=true, playback paths return 451 Unavailable For Legal Reasons. Backend - migrations/988_dmca_notices.sql + rollback : table dmca_notices (id, status, claimant_*, work_description, infringing_track_id FK, sworn_statement_at, takedown_at, counter_notice_at, restored_at, audit_log JSONB, created_at, updated_at). Adds tracks.dmca_blocked BOOLEAN. Partial indexes for the pending queue + per-track lookup. Status enum constrained via CHECK. - internal/models/dmca_notice.go + DmcaBlocked field on Track. - internal/services/dmca_service.go : CreateNotice + ListPending + Takedown + Dismiss. Takedown is a single transaction that flips the track's flags AND appends an audit_log entry — partial state can't happen if the track was deleted between fetch and update. - internal/handlers/dmca_handler.go : POST /api/v1/dmca/notice (public), GET /api/v1/admin/dmca/notices (paginated), POST /:id/takedown, POST /:id/dismiss. sworn_statement=false → 400. Conflict → 409. Track gone after notice → 410. - internal/api/routes_legal.go : route registration. Admin chain : RequireAuth + RequireAdmin + RequireMFA (same as moderation routes). - internal/core/track/track_hls_handler.go : both StreamTrack + DownloadTrack now early-return 451 when track.DmcaBlocked. Owner cannot bypass — only an admin restoring the notice clears the gate. - internal/services/dmca_service_test.go : audit_log append helpers, malformed-JSON rejection, ordering preservation. Frontend - apps/web/src/features/legal/pages/DmcaNoticePage.tsx : public form at /legal/dmca/notice. Validates sworn-statement checkbox client-side. Receipt panel shows the notice ID after submission. - apps/web/src/services/api/dmca.ts : thin client (POST /dmca/notice). - routeConfig + lazy registry updated for the new route. - DmcaPage now links to /legal/dmca/notice instead of saying "form pending". E2E - tests/e2e/29-dmca-notice.spec.ts : 3 tests. (1) anonymous submit yields 201 + pending receipt. (2) sworn_statement=false rejected with 400. (3) admin takedown gates playback with 451 — gated behind E2E_DMCA_ADMIN=1 because admin path requires MFA-bearing seed. Acceptance (Day 14) : public submission produces a pending notice, admin takedown blocks playback at 451. Lab-side validation pending admin MFA seed for the e2e admin pathway. W3 progress : Redis Sentinel ✓ · MinIO distribué ✓ · CDN ✓ · DMCA ✓ · embed ⏳ Day 15. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 13:39:33 +00:00
-- 988_dmca_notices rollback.
-- Drops the dmca_notices table + the dmca_blocked column on tracks.
--
-- WARNING : rolling back loses the entire DMCA history. Only run in
-- dev / staging after re-applying or in a true rollback scenario.
DROP TRIGGER IF EXISTS dmca_notices_updated_at_trg ON public.dmca_notices;
DROP FUNCTION IF EXISTS dmca_notices_updated_at();
DROP TABLE IF EXISTS public.dmca_notices;
ALTER TABLE public.tracks
DROP COLUMN IF EXISTS dmca_blocked;