From bdaf3c7cbbd1e1da058cdccd47ce32bcc6f1ec41 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Fri, 18 Sep 2026 17:27:22 -0300 Subject: [PATCH] =?UTF-8?q?feat(C193):=20reel=20privado=20no=20CMS=20?= =?UTF-8?q?=E2=80=94=20modelo,=20upload=20privado=20e=20kill=20switch=20(C?= =?UTF-8?q?loses=20#1152)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + docs/changelog/2026-09-18-c193.md | 1 + docs/plans/reels-privado-hardening.md | 54 + docs/plans/reels-reel-privado-impl.md | 151 + .../comunicacao/acervo/[id]/poster/route.ts | 4 +- .../reels/[id]/media/[kind]/route.ts | 66 + src/app/(campaign)/campanha/actions/speech.ts | 18 +- src/collections/Reel.ts | 157 + src/collections/ReelMedia.ts | 44 + src/components/campaign/shell/nav.ts | 6 +- src/lib/campaignRoles.ts | 10 +- src/lib/reel.ts | 66 + src/lib/reelMedia.ts | 66 + src/lib/schemas/speechVod.ts | 2 +- src/migrations/20260918_201009_add_reel.json | 15963 ++++++++++++++++ src/migrations/20260918_201009_add_reel.ts | 82 + src/migrations/index.ts | 8 +- src/payload-types.ts | 121 + src/payload.config.ts | 7 + src/utilities/access/reels.ts | 34 + src/utilities/access/speeches.ts | 8 +- src/utilities/ai/tools/findSpeechExcerpts.ts | 4 +- src/utilities/campaignAccess.ts | 2 + src/utilities/campaignPageActor.ts | 4 +- src/utilities/reels/reelMediaResponse.ts | 173 + tests/int/reel.int.spec.ts | 290 + tests/unit/reel.unit.spec.ts | 136 + 27 files changed, 17450 insertions(+), 28 deletions(-) create mode 100644 docs/changelog/2026-09-18-c193.md create mode 100644 docs/plans/reels-privado-hardening.md create mode 100644 docs/plans/reels-reel-privado-impl.md create mode 100644 src/app/(campaign)/campanha/(app)/comunicacao/reels/[id]/media/[kind]/route.ts create mode 100644 src/collections/Reel.ts create mode 100644 src/collections/ReelMedia.ts create mode 100644 src/lib/reel.ts create mode 100644 src/lib/reelMedia.ts create mode 100644 src/migrations/20260918_201009_add_reel.json create mode 100644 src/migrations/20260918_201009_add_reel.ts create mode 100644 src/utilities/access/reels.ts create mode 100644 src/utilities/reels/reelMediaResponse.ts create mode 100644 tests/int/reel.int.spec.ts create mode 100644 tests/unit/reel.unit.spec.ts diff --git a/.gitignore b/.gitignore index 3a277512..44ce0c79 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ next-env.d.ts .env /media +/reelMedia # TSE open-data zip cache (pnpm db:seed:tse) /data/tse/ diff --git a/docs/changelog/2026-09-18-c193.md b/docs/changelog/2026-09-18-c193.md new file mode 100644 index 00000000..7d226fae --- /dev/null +++ b/docs/changelog/2026-09-18-c193.md @@ -0,0 +1 @@ +**C193 — Reel privado no CMS: modelo, arquivos privados e kill switch (2026-09-18):** a assessoria produz os Reels de tutorial fora do Teqo e eles não tinham onde existir. Entregou-se a base no `/campanha`: (1) **collection `reel`** (grupo `Comunicação`) com `title`, `feature` (lista fechada, começando `cards`), `status` `draft→published→unpublished`, e os artefatos como uploads 1:1 — `video` (MP4 sem áudio, primário, required), `videoWithAudio`, `narrationAudio`, `captions` (`.srt`), `cover` (required) — mais `transcript` em texto, `publishedAt` carimbado na transição para `published` e `createdBy` do ator; (2) **collection de upload privada `reelMedia`** separada de `media` (que é leitura pública por contrato, pinada no lockdown): `read/create/update/delete` só para `communicator`/`coordinator`/`candidate` + admin, registrada no plugin S3 (`reelMedia: true`) para não cair em disco efêmero em produção; (3) **rota autenticada de mídia** `GET /campanha/comunicacao/reels/[id]/media/[kind]` — sob `/campanha` de propósito, porque é o path do cookie `campaign-token` que `