docs(C222): plano + design hi-fi — Central de Conteúdos — apagar uma peça (Related #1330)

This commit is contained in:
Francisco Solla 2026-09-24 22:27:51 -03:00
parent c9ab467f23
commit 21341627b6
2 changed files with 669 additions and 0 deletions

View file

@ -0,0 +1,561 @@
<!doctype html>
<html lang="pt-BR" data-theme="campaign">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<title>Design — C222 · Central de Conteúdos — apagar uma peça</title>
<style type="text/tailwindcss">
@theme inline {
--font-sans: Inter, ui-sans-serif, system-ui, sans-serif;
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-border: var(--sidebar-border);
--radius-sm: 0.25rem;
--radius-md: 0.375rem;
--radius-lg: 0.5rem;
--radius-xl: 0.75rem;
}
[data-theme='campaign'] {
--radius: 0.5rem;
--background: #ffffff;
--foreground: #1c1917;
--card: #ffffff;
--card-foreground: #1c1917;
--popover: #ffffff;
--popover-foreground: #1c1917;
--primary: #c51414;
--primary-foreground: #ffffff;
--secondary: #f5f5f4;
--secondary-foreground: #292524;
--muted: #f4f4f5;
--muted-foreground: #6b7280;
--accent: #f4f4f5;
--accent-foreground: #1c1917;
--destructive: #b42318;
--border: rgb(28 25 23 / 12%);
--input: rgb(28 25 23 / 16%);
--ring: #c51414;
--sidebar: #fafaf9;
--sidebar-foreground: #1c1917;
--sidebar-accent: #f5f5f4;
--sidebar-border: rgb(28 25 23 / 12%);
}
* {
box-sizing: border-box;
}
body {
font-family: Inter, ui-sans-serif, system-ui, sans-serif;
}
button,
a {
-webkit-tap-highlight-color: transparent;
}
.board {
background-color: #efeeec;
background-image: radial-gradient(rgb(28 25 23 / 8%) 0.7px, transparent 0.7px);
background-size: 16px 16px;
}
.scene-shadow {
box-shadow: 0 18px 52px rgb(28 25 23 / 10%);
}
.dialog-shadow {
box-shadow: 0 24px 80px rgb(28 25 23 / 25%);
}
</style>
</head>
<body class="board min-h-screen bg-background text-foreground antialiased">
<!-- Ícones inline seguem o grid e o stroke do Lucide. Não há SVG próprio. -->
<main class="mx-auto max-w-[1480px] space-y-16 px-4 py-10 md:px-8 md:py-14">
<header class="max-w-3xl">
<div
class="inline-flex min-h-6 items-center rounded-full bg-primary px-2.5 text-xs font-semibold text-primary-foreground"
>
C222 · design do gate
</div>
<h1 class="mt-4 text-3xl font-semibold tracking-tight">Apagar sem competir com o trabalho</h1>
<p class="mt-2 max-w-2xl text-sm leading-6 text-muted-foreground">
A saída definitiva fica disponível na lista e na ficha, mas permanece visualmente abaixo
da próxima ação. A confirmação cresce apenas quando existe um link público.
</p>
</header>
<nav aria-label="Índice de cenas" class="flex flex-wrap gap-2 text-xs">
<a href="#lista-desktop" class="rounded-full border border-border bg-card px-3 py-1.5 font-medium"
>A · Lista desktop</a
>
<a href="#lista-mobile" class="rounded-full border border-border bg-card px-3 py-1.5 font-medium"
>B · Lista mobile</a
>
<a href="#detalhe" class="rounded-full border border-border bg-card px-3 py-1.5 font-medium"
>C–D · Detalhe</a
>
<a href="#confirmacoes" class="rounded-full border border-border bg-card px-3 py-1.5 font-medium"
>E–F · Confirmações</a
>
<a href="#feedback" class="rounded-full border border-border bg-card px-3 py-1.5 font-medium"
>G–H · Erro e envio</a
>
</nav>
<!-- CENA A — LISTA DESKTOP -->
<section id="lista-desktop" aria-labelledby="lista-desktop-title">
<div class="mb-3 flex items-end justify-between gap-4">
<div>
<p class="text-xs font-medium text-muted-foreground">Cena A · desktop ~1280</p>
<h2 id="lista-desktop-title" class="mt-1 text-base font-semibold">
“Apagar” acompanha cada próxima ação sem virar o foco da linha
</h2>
</div>
<p class="hidden max-w-md text-right text-xs leading-5 text-muted-foreground md:block">
Abrir continua outline; Reprocessar continua primário. Apagar é ghost, destrutivo e
separado por respiro.
</p>
</div>
<div class="overflow-x-auto pb-4">
<div
class="scene-shadow mx-auto h-[780px] w-[1280px] overflow-hidden rounded-xl border border-border bg-background"
>
<div class="flex h-full">
<aside class="flex w-56 shrink-0 flex-col border-r border-sidebar-border bg-sidebar p-3">
<div class="flex h-12 items-center gap-2 px-2">
<div
class="grid size-8 place-items-center rounded-lg bg-primary text-sm font-bold text-primary-foreground"
>
S
</div>
<div>
<p class="text-sm font-semibold">Solla</p>
<p class="text-xs text-muted-foreground">Campanha</p>
</div>
</div>
<nav class="mt-4 space-y-1 text-sm" aria-label="Navegação ilustrativa">
<div class="flex h-9 items-center gap-2 rounded-md bg-sidebar-accent px-3 font-semibold">
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="m3 11 18-5v12L3 14v-3Z" />
<path d="M11.6 16.9 13 22H7l-1.3-7" />
</svg>
Comunicação
</div>
<div class="ml-4 border-l border-sidebar-border pl-3">
<div
class="mt-1 flex h-9 items-center rounded-md bg-card px-3 font-semibold text-primary ring-1 ring-border"
>
Conteúdos
</div>
</div>
</nav>
<p class="mt-auto border-t border-sidebar-border px-2 pt-4 text-xs text-muted-foreground">
Assessoria de comunicação
</p>
</aside>
<div class="min-w-0 flex-1">
<header class="flex h-16 items-center justify-between border-b border-border px-6">
<div>
<p class="text-xs text-muted-foreground">Comunicação</p>
<p class="text-sm font-medium">Central de Conteúdos</p>
</div>
<div class="size-8 rounded-full bg-secondary ring-1 ring-border"></div>
</header>
<div class="p-6">
<div class="flex items-start justify-between gap-4">
<div>
<h3 class="text-lg font-semibold">Conteúdos</h3>
<p class="mt-1 text-sm text-muted-foreground">
Peças que alimentam a Central pública. Rascunhos não aparecem no site.
</p>
</div>
<div class="flex items-center gap-2">
<button
type="button"
class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium"
>
Adicionar por link
</button>
<button
type="button"
class="inline-flex min-h-11 items-center justify-center rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground"
>
Enviar peças
</button>
</div>
</div>
<div class="mt-6 flex items-center gap-3">
<div class="relative flex-1">
<svg aria-hidden="true" class="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="11" cy="11" r="8" />
<path d="m21 21-4.3-4.3" />
</svg>
<input
readonly
aria-label="Buscar conteúdos"
placeholder="Buscar por título, tema ou cidade…"
class="h-11 w-full rounded-md border border-input bg-background pl-9 pr-3 text-sm outline-none placeholder:text-muted-foreground"
/>
</div>
<button
type="button"
class="inline-flex h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium"
>
Filtros
</button>
</div>
<div class="mt-5 overflow-hidden rounded-xl border border-border">
<table class="w-full table-fixed text-left text-sm">
<caption class="sr-only">
Quatro peças com estados de processamento, publicação, circulação e ações.
</caption>
<thead class="bg-stone-50 text-xs text-muted-foreground">
<tr class="border-b border-border">
<th class="w-[23%] p-3 font-medium">Peça</th>
<th class="w-[14%] p-3 font-medium">Processamento</th>
<th class="w-[12%] p-3 font-medium">Publicação</th>
<th class="w-[25%] p-3 font-medium">Circulação</th>
<th class="w-[26%] p-3 text-right font-medium">Próxima ação</th>
</tr>
</thead>
<tbody class="divide-y divide-border">
<tr>
<td class="p-3 align-middle">
<div class="flex items-center gap-3">
<span class="grid h-14 w-20 shrink-0 place-items-center rounded-md bg-gradient-to-br from-stone-200 to-stone-100 text-stone-500">
<svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="m16 13 5 3-5 3v-6Z" /><rect x="3" y="6" width="13" height="14" rx="2" />
</svg>
</span>
<div class="min-w-0">
<p class="font-semibold">Peça publicada</p>
<p class="mt-1 truncate text-xs text-muted-foreground">Vídeo · 02:14</p>
</div>
</div>
</td>
<td class="p-3">
<span class="inline-flex min-h-5 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span>
</td>
<td class="p-3">
<span class="inline-flex min-h-5 items-center rounded-full bg-rose-50 px-2 py-0.5 text-xs font-semibold text-rose-900 ring-1 ring-rose-200">Publicado</span>
</td>
<td class="p-3">
<div class="grid grid-cols-2 gap-x-3 gap-y-1 text-xs">
<span class="text-muted-foreground">Visualizações</span><b class="text-right">—</b>
<span class="text-muted-foreground">Downloads</span><b class="text-right">—</b>
</div>
</td>
<td class="p-3">
<div class="flex items-center justify-end gap-2">
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium">Abrir</button>
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-2.5 text-sm font-medium text-destructive hover:bg-red-50">
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>
Apagar
</button>
</div>
</td>
</tr>
<tr>
<td class="p-3"><p class="font-semibold">Peça em rascunho</p><p class="mt-1 text-xs text-muted-foreground">Card</p></td>
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span></td>
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 text-xs font-semibold text-muted-foreground">Rascunho</span></td>
<td class="p-3"><span class="text-xs text-muted-foreground">Ainda não publicada</span></td>
<td class="p-3">
<div class="flex items-center justify-end gap-2">
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium">Abrir</button>
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-2.5 text-sm font-medium text-destructive hover:bg-red-50">
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar
</button>
</div>
</td>
</tr>
<tr>
<td class="p-3"><p class="font-semibold">Peça com falha</p><p class="mt-1 text-xs text-muted-foreground">Áudio</p></td>
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-semibold text-red-700">Falhou</span></td>
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 text-xs font-semibold text-muted-foreground">Rascunho</span></td>
<td class="p-3"><span class="text-xs text-muted-foreground">Ainda não publicada</span></td>
<td class="p-3">
<div class="flex items-center justify-end gap-2">
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground">
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6v6h-6" /><path d="M20 12a8 8 0 1 0-2.34 5.66" /></svg>Reprocessar
</button>
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-2.5 text-sm font-medium text-destructive hover:bg-red-50">
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar
</button>
</div>
</td>
</tr>
<tr>
<td class="p-3"><p class="font-semibold">Peça em processamento</p><p class="mt-1 text-xs text-muted-foreground">Vídeo enviado</p></td>
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-amber-100 px-2 py-0.5 text-xs font-semibold text-amber-900">Processando</span><p class="mt-1 text-xs text-muted-foreground">Transcrevendo…</p></td>
<td class="p-3"><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 text-xs font-semibold text-muted-foreground">Rascunho</span></td>
<td class="p-3"><span class="text-xs text-muted-foreground">Ainda não publicada</span></td>
<td class="p-3">
<div class="flex items-center justify-end gap-2">
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium">Abrir</button>
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-2.5 text-sm font-medium text-destructive hover:bg-red-50">
<svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<p class="mt-3 text-xs text-muted-foreground">4 peças</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- CENA B — LISTA MOBILE -->
<section id="lista-mobile" aria-labelledby="lista-mobile-title">
<div class="mb-3">
<p class="text-xs font-medium text-muted-foreground">Cena B · mobile ~390</p>
<h2 id="lista-mobile-title" class="mt-1 text-base font-semibold">
Nos cards, apagar fica ao lado da ação rotineira — nunca acima dela
</h2>
</div>
<div
class="scene-shadow mx-auto w-full max-w-[390px] overflow-hidden rounded-[28px] border-[6px] border-stone-800 bg-background"
>
<div class="flex h-14 items-center justify-between bg-primary px-4 text-primary-foreground">
<button aria-label="Abrir menu" class="grid size-10 place-items-center rounded-lg">
<svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6h16M4 12h16M4 18h16" /></svg>
</button>
<span class="text-sm font-semibold">Conteúdos</span>
<div class="size-10"></div>
</div>
<div class="p-4">
<button type="button" class="inline-flex min-h-11 w-full items-center justify-center rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground">Enviar peças</button>
<button type="button" class="mt-2 inline-flex min-h-11 w-full items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium">Adicionar por link</button>
<input readonly aria-label="Buscar conteúdos" placeholder="Buscar conteúdos…" class="mt-3 h-11 w-full rounded-md border border-input bg-background px-3 text-base outline-none placeholder:text-muted-foreground" />
<div class="mt-4 space-y-3">
<article class="rounded-xl border border-border bg-card p-4">
<div class="flex items-start justify-between gap-3"><p class="text-sm font-semibold">Peça publicada</p><span class="inline-flex min-h-5 shrink-0 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span></div>
<div class="mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground"><span class="inline-flex min-h-5 items-center rounded-full bg-rose-50 px-2 py-0.5 font-semibold text-rose-900 ring-1 ring-rose-200">Publicado</span><span>Vídeo · 02:14</span></div>
<div class="mt-3 grid grid-cols-[1fr_auto] gap-2">
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-3 text-sm font-medium">Abrir</button>
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-3 text-sm font-medium text-destructive hover:bg-red-50"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button>
</div>
</article>
<article class="rounded-xl border border-border bg-card p-4">
<div class="flex items-start justify-between gap-3"><p class="text-sm font-semibold">Peça em rascunho</p><span class="inline-flex min-h-5 shrink-0 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span></div>
<div class="mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground"><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 font-semibold">Rascunho</span><span>Card</span></div>
<div class="mt-3 grid grid-cols-[1fr_auto] gap-2"><button type="button" class="min-h-11 rounded-lg border border-border text-sm font-medium">Abrir</button><button type="button" class="inline-flex min-h-11 items-center gap-1.5 rounded-lg px-3 text-sm font-medium text-destructive"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button></div>
</article>
<article class="rounded-xl border border-border bg-card p-4">
<div class="flex items-start justify-between gap-3"><p class="text-sm font-semibold">Peça com falha</p><span class="inline-flex min-h-5 shrink-0 items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-semibold text-red-700">Falhou</span></div>
<div class="mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground"><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 font-semibold">Rascunho</span><span>Áudio</span></div>
<button type="button" class="mt-3 inline-flex min-h-11 w-full items-center justify-center gap-1.5 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6v6h-6" /><path d="M20 12a8 8 0 1 0-2.34 5.66" /></svg>Reprocessar</button>
<button type="button" class="mt-2 inline-flex min-h-11 w-full items-center justify-center gap-1.5 rounded-lg text-sm font-medium text-destructive"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button>
</article>
<article class="rounded-xl border border-border bg-card p-4">
<div class="flex items-start justify-between gap-3"><p class="text-sm font-semibold">Peça em processamento</p><span class="inline-flex min-h-5 shrink-0 items-center rounded-full bg-amber-100 px-2 py-0.5 text-xs font-semibold text-amber-900">Processando</span></div>
<div class="mt-3 h-2 overflow-hidden rounded-full bg-muted"><div class="h-full w-1/2 rounded-full bg-primary"></div></div>
<p class="mt-2 text-xs text-muted-foreground">Transcrevendo…</p>
<div class="mt-3 grid grid-cols-[1fr_auto] gap-2"><button type="button" class="min-h-11 rounded-lg border border-border text-sm font-medium">Abrir</button><button type="button" class="inline-flex min-h-11 items-center gap-1.5 rounded-lg px-3 text-sm font-medium text-destructive"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button></div>
</article>
</div>
</div>
</div>
</section>
<!-- CENAS C–D — DETALHE DESKTOP E MOBILE -->
<section id="detalhe" aria-labelledby="detalhe-title">
<div class="mb-3 flex items-end justify-between gap-4">
<div>
<p class="text-xs font-medium text-muted-foreground">Cenas C–D · detalhe desktop e mobile</p>
<h2 id="detalhe-title" class="mt-1 text-base font-semibold">
A ação definitiva fecha a fila de ações do topo
</h2>
</div>
<p class="hidden max-w-md text-right text-xs leading-5 text-muted-foreground md:block">
Publicar, Despublicar ou Reprocessar preservam seu peso contextual. Anexar é secundário;
Apagar permanece ghost destrutivo.
</p>
</div>
<div class="overflow-x-auto pb-4">
<div class="scene-shadow mx-auto w-[1280px] overflow-hidden rounded-xl border border-border bg-background">
<div class="flex h-16 items-center justify-between border-b border-border px-8">
<div><p class="text-xs text-muted-foreground">Comunicação</p><p class="text-sm font-medium">Peça publicada</p></div>
<div class="size-8 rounded-full bg-secondary ring-1 ring-border"></div>
</div>
<div class="mx-auto max-w-5xl p-8">
<a href="#" class="inline-flex min-h-10 items-center gap-1 text-xs font-semibold text-primary">
<svg aria-hidden="true" class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 18-6-6 6-6" /></svg>Conteúdos
</a>
<div class="mt-2 flex items-start justify-between gap-5 border-b border-border pb-5">
<div class="min-w-0">
<h3 class="text-xl font-semibold">Peça publicada</h3>
<div class="mt-2 flex gap-2"><span class="inline-flex min-h-5 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span><span class="inline-flex min-h-5 items-center rounded-full bg-rose-50 px-2 py-0.5 text-xs font-semibold text-rose-900 ring-1 ring-rose-200">Publicado</span></div>
</div>
<div class="flex shrink-0 flex-wrap items-center justify-end gap-2">
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg border border-border bg-background px-3 text-sm font-medium"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13.5 3H12H8C6.9 3 6 3.9 6 5v14c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V8.5L13.5 3Z" /><path d="M13 3v6h6" /><path d="M12 18v-6" /><path d="m9 15 3 3 3-3" /></svg>Anexar</button>
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg border border-border bg-background px-3 text-sm font-medium"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 3l18 18" /><path d="M10.6 10.6A3 3 0 0 0 15 15" /><path d="M9.9 4.2A10.6 10.6 0 0 1 12 4c5.5 0 10 8 10 8a18 18 0 0 1-2 2.8" /><path d="M6.6 6.6C3.9 8.4 2 12 2 12s4.5 8 10 8a9.8 9.8 0 0 0 5.4-1.6" /></svg>Despublicar</button>
<button type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg px-3 text-sm font-medium text-destructive hover:bg-red-50"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button>
</div>
</div>
<div class="mt-6 grid grid-cols-[300px_1fr] gap-8">
<div><div class="grid aspect-video place-items-center rounded-xl border border-border bg-gradient-to-br from-stone-200 to-stone-100 text-xs font-semibold text-muted-foreground">Prévia da peça</div><dl class="mt-4 space-y-2 text-xs"><div class="flex justify-between"><dt class="text-muted-foreground">Origem</dt><dd>Arquivo</dd></div><div class="flex justify-between"><dt class="text-muted-foreground">Duração</dt><dd>02:14</dd></div></dl></div>
<div><div class="rounded-xl border border-border p-5"><p class="text-sm font-semibold">Circulação</p><div class="mt-4 grid grid-cols-4 gap-3"><div class="h-16 rounded-lg bg-muted"></div><div class="h-16 rounded-lg bg-muted"></div><div class="h-16 rounded-lg bg-muted"></div><div class="h-16 rounded-lg bg-muted"></div></div></div><div class="mt-6 border-t border-border pt-6"><div class="h-11 rounded-md border border-input"></div><div class="mt-3 h-24 rounded-md border border-input"></div></div></div>
</div>
<div class="mt-8 grid grid-cols-2 gap-4 border-t border-border pt-6">
<div class="rounded-xl border border-border bg-card p-4">
<p class="text-xs font-semibold">Variante · pronto e rascunho</p>
<div class="mt-3 flex items-center gap-2"><button type="button" class="inline-flex min-h-11 items-center rounded-lg border border-border px-3 text-sm font-medium">Anexar</button><button type="button" class="inline-flex min-h-11 items-center rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground">Publicar</button><button type="button" class="inline-flex min-h-11 items-center rounded-lg px-3 text-sm font-medium text-destructive">Apagar</button></div>
</div>
<div class="rounded-xl border border-border bg-card p-4">
<p class="text-xs font-semibold">Variante · falhou</p>
<div class="mt-3 flex items-center gap-2"><button type="button" class="inline-flex min-h-11 items-center rounded-lg border border-border px-3 text-sm font-medium">Anexar</button><button type="button" class="inline-flex min-h-11 items-center gap-1.5 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6v6h-6" /><path d="M20 12a8 8 0 1 0-2.34 5.66" /></svg>Reprocessar</button><button type="button" class="inline-flex min-h-11 items-center rounded-lg px-3 text-sm font-medium text-destructive">Apagar</button></div>
</div>
</div>
</div>
</div>
</div>
<div class="mt-8 grid items-start gap-8 lg:grid-cols-2">
<div>
<p class="mb-2 text-center text-xs font-medium text-muted-foreground">Mobile · publicado</p>
<div class="scene-shadow mx-auto w-full max-w-[390px] overflow-hidden rounded-[28px] border-[6px] border-stone-800 bg-background">
<div class="flex h-14 items-center justify-between bg-primary px-4 text-primary-foreground"><button aria-label="Abrir menu" class="grid size-10 place-items-center rounded-lg"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6h16M4 12h16M4 18h16" /></svg></button><span class="max-w-[230px] truncate text-sm font-semibold">Peça publicada</span><div class="size-10"></div></div>
<div class="p-4">
<a href="#" class="inline-flex min-h-11 items-center gap-1 text-xs font-semibold text-primary"><svg aria-hidden="true" class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 18-6-6 6-6" /></svg>Conteúdos</a>
<h3 class="mt-1 text-xl font-semibold">Peça publicada</h3>
<div class="mt-2 flex gap-2"><span class="inline-flex min-h-5 items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-semibold text-green-800">Pronto</span><span class="inline-flex min-h-5 items-center rounded-full bg-rose-50 px-2 py-0.5 text-xs font-semibold text-rose-900 ring-1 ring-rose-200">Publicado</span></div>
<div class="mt-4 grid grid-cols-2 gap-2"><button type="button" class="min-h-11 rounded-lg border border-border text-sm font-medium">Anexar</button><button type="button" class="min-h-11 rounded-lg border border-border text-sm font-medium">Despublicar</button><button type="button" class="col-span-2 inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg text-sm font-medium text-destructive"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button></div>
<div class="mt-5 grid aspect-video place-items-center rounded-xl border border-border bg-gradient-to-br from-stone-200 to-stone-100 text-xs font-semibold text-muted-foreground">Prévia da peça</div>
<div class="mt-5 h-28 rounded-xl border border-border"></div>
</div>
</div>
</div>
<div>
<p class="mb-2 text-center text-xs font-medium text-muted-foreground">Mobile · falhou</p>
<div class="scene-shadow mx-auto w-full max-w-[390px] overflow-hidden rounded-[28px] border-[6px] border-stone-800 bg-background">
<div class="flex h-14 items-center justify-between bg-primary px-4 text-primary-foreground"><button aria-label="Abrir menu" class="grid size-10 place-items-center rounded-lg"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6h16M4 12h16M4 18h16" /></svg></button><span class="max-w-[230px] truncate text-sm font-semibold">Peça com falha</span><div class="size-10"></div></div>
<div class="p-4">
<a href="#" class="inline-flex min-h-11 items-center gap-1 text-xs font-semibold text-primary"><svg aria-hidden="true" class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 18-6-6 6-6" /></svg>Conteúdos</a>
<h3 class="mt-1 text-xl font-semibold">Peça com falha</h3>
<div class="mt-2 flex gap-2"><span class="inline-flex min-h-5 items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-semibold text-red-700">Falhou</span><span class="inline-flex min-h-5 items-center rounded-full bg-muted px-2 py-0.5 text-xs font-semibold text-muted-foreground">Rascunho</span></div>
<button type="button" class="mt-4 inline-flex min-h-11 w-full items-center justify-center gap-1.5 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6v6h-6" /><path d="M20 12a8 8 0 1 0-2.34 5.66" /></svg>Reprocessar</button>
<button type="button" class="mt-2 min-h-11 w-full rounded-lg border border-border text-sm font-medium">Anexar</button>
<button type="button" class="mt-2 inline-flex min-h-11 w-full items-center justify-center gap-1.5 rounded-lg text-sm font-medium text-destructive"><svg aria-hidden="true" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18" /><path d="M8 6V4h8v2" /><path d="m19 6-1 14H6L5 6" /></svg>Apagar</button>
<div class="mt-5 grid aspect-video place-items-center rounded-xl border border-border bg-muted text-xs font-semibold text-muted-foreground">Sem prévia disponível</div>
<div class="mt-5 rounded-lg border border-red-200 bg-red-50 p-3 text-xs leading-5 text-red-800">O processamento não foi concluído. O arquivo foi preservado.</div>
</div>
</div>
</div>
</div>
</section>
<!-- CENAS E–F — CONFIRMAÇÕES -->
<section id="confirmacoes" aria-labelledby="confirmacoes-title">
<div class="mb-3">
<p class="text-xs font-medium text-muted-foreground">Cenas E–F · diálogos sempre visíveis</p>
<h2 id="confirmacoes-title" class="mt-1 text-base font-semibold">
O link público é nomeado somente quando será quebrado
</h2>
</div>
<div class="grid gap-6 lg:grid-cols-2">
<div class="relative flex min-h-[430px] items-center justify-center overflow-hidden rounded-xl border border-border bg-stone-200 p-4">
<div class="absolute inset-0 bg-foreground/35"></div>
<span class="absolute left-4 top-4 rounded-full bg-white/90 px-2.5 py-1 text-xs font-medium">Publicado</span>
<div role="dialog" aria-modal="true" aria-labelledby="published-title" class="dialog-shadow relative grid w-full max-w-sm gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10">
<div class="flex items-start gap-3">
<div class="grid size-9 shrink-0 place-items-center rounded-full bg-red-50 text-destructive"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg></div>
<div class="min-w-0"><h3 id="published-title" class="text-base font-medium">Apagar esta peça?</h3><p class="mt-2 text-sm leading-6 text-muted-foreground">O link público <span class="font-medium text-foreground">/conteudos/&lt;slug&gt;</span> deixa de funcionar para quem já recebeu. Esta ação não pode ser desfeita.</p></div>
</div>
<div class="-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t border-border bg-muted/50 p-4 sm:flex-row sm:justify-end">
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-4 text-sm font-medium">Cancelar</button>
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg bg-destructive px-4 text-sm font-medium text-white">Apagar</button>
</div>
</div>
</div>
<div class="relative flex min-h-[430px] items-center justify-center overflow-hidden rounded-xl border border-border bg-stone-200 p-4">
<div class="absolute inset-0 bg-foreground/35"></div>
<span class="absolute left-4 top-4 rounded-full bg-white/90 px-2.5 py-1 text-xs font-medium">Rascunho · processando · falhou</span>
<div role="dialog" aria-modal="true" aria-labelledby="draft-title" class="dialog-shadow relative grid w-full max-w-sm gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10">
<div class="flex items-start gap-3">
<div class="grid size-9 shrink-0 place-items-center rounded-full bg-red-50 text-destructive"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg></div>
<div class="min-w-0"><h3 id="draft-title" class="text-base font-medium">Apagar esta peça?</h3><p class="mt-2 text-sm leading-6 text-muted-foreground">Esta ação não pode ser desfeita.</p></div>
</div>
<div class="-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t border-border bg-muted/50 p-4 sm:flex-row sm:justify-end">
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-4 text-sm font-medium">Cancelar</button>
<button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg bg-destructive px-4 text-sm font-medium text-white">Apagar</button>
</div>
</div>
</div>
</div>
</section>
<!-- CENAS G–H — FEEDBACK -->
<section id="feedback" aria-labelledby="feedback-title">
<div class="mb-3">
<p class="text-xs font-medium text-muted-foreground">Cenas G–H · estados críticos do diálogo</p>
<h2 id="feedback-title" class="mt-1 text-base font-semibold">
Falha permanece no contexto; envio bloqueia os dois gestos
</h2>
</div>
<div class="grid gap-6 lg:grid-cols-2">
<div class="relative flex min-h-[470px] items-center justify-center overflow-hidden rounded-xl border border-border bg-stone-200 p-4">
<div class="absolute inset-0 bg-foreground/35"></div>
<span class="absolute left-4 top-4 rounded-full bg-white/90 px-2.5 py-1 text-xs font-medium">Erro ao apagar</span>
<div role="dialog" aria-modal="true" aria-labelledby="error-title" class="dialog-shadow relative grid w-full max-w-sm gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10">
<div class="flex items-start gap-3"><div class="grid size-9 shrink-0 place-items-center rounded-full bg-red-50 text-destructive"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg></div><div><h3 id="error-title" class="text-base font-medium">Apagar esta peça?</h3><p class="mt-2 text-sm leading-6 text-muted-foreground">Esta ação não pode ser desfeita.</p></div></div>
<div role="alert" class="grid w-full grid-cols-[auto_1fr] gap-x-2 rounded-lg border border-border bg-card px-2.5 py-2 text-left text-destructive"><svg aria-hidden="true" class="mt-0.5 size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg><p class="text-xs">Não foi possível apagar a peça.</p></div>
<div class="-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t border-border bg-muted/50 p-4 sm:flex-row sm:justify-end"><button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-4 text-sm font-medium">Cancelar</button><button type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg bg-destructive px-4 text-sm font-medium text-white">Apagar</button></div>
</div>
</div>
<div class="relative flex min-h-[470px] items-center justify-center overflow-hidden rounded-xl border border-border bg-stone-200 p-4">
<div class="absolute inset-0 bg-foreground/35"></div>
<span class="absolute left-4 top-4 rounded-full bg-white/90 px-2.5 py-1 text-xs font-medium">Enviando</span>
<div role="dialog" aria-modal="true" aria-labelledby="submitting-title" class="dialog-shadow relative grid w-full max-w-sm gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10">
<div class="flex items-start gap-3"><div class="grid size-9 shrink-0 place-items-center rounded-full bg-red-50 text-destructive"><svg aria-hidden="true" class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg></div><div><h3 id="submitting-title" class="text-base font-medium">Apagar esta peça?</h3><p class="mt-2 text-sm leading-6 text-muted-foreground">O link público <span class="font-medium text-foreground">/conteudos/&lt;slug&gt;</span> deixa de funcionar para quem já recebeu. Esta ação não pode ser desfeita.</p></div></div>
<div class="-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t border-border bg-muted/50 p-4 sm:flex-row sm:justify-end">
<button disabled type="button" class="inline-flex min-h-11 items-center justify-center rounded-lg border border-border bg-background px-4 text-sm font-medium opacity-50">Cancelar</button>
<button disabled type="button" class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-lg bg-destructive px-4 text-sm font-medium text-white opacity-70"><svg aria-hidden="true" class="size-4 animate-spin motion-reduce:animate-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 1 1-6.2-8.6" /></svg>Apagar</button>
</div>
</div>
</div>
</div>
</section>
</main>
</body>
</html>

View file

@ -0,0 +1,108 @@
# C222 — Central de Conteúdos — apagar uma peça
Status: rascunho
Atualizado em: 2026-09-24
Issue: #1330
Priority: P2
Impeccable: B — encaixe na Central de Conteúdos (lista + detalhe): ação de apagar com confirmação
Design UI: docs/plans/central-conteudos-apagar-peca-ui-design.html
Appetite: ~1 dia eng; um outcome verificável
Responsável: —
## Intenção
A Central de Conteúdos (C211) resolveu o garimpo: a assessoria envia, cataloga e publica as peças de campanha em `/campanha/comunicacao/conteudos`. Mas deixou um beco declarado — não existe nenhuma superfície de apagar; o `delete` ficou restrito ao admin do Payload como anti-goal aceito ("campanha nunca perde um arquivo por acidente"). Consequência: uma peça errada, duplicada ou que ninguém vai usar fica na Central e na pública para sempre; só um admin do Payload consegue removê-la, e a assessoria, que é quem sabe que a peça não presta, não tem como limpar a própria mesa.
O pedido humano reabre esse anti-goal de propósito — exatamente como o C183 (#1105, `docs/plans/biblioteca-cortes-apagar-e-falhas.md`) reabriu o "deletar corte não existe na UI" dos cortes do acervo. O pedido é direto: poder apagar uma peça de conteúdo, com confirmação explícita.
## Persona e fluxo
- **Persona / contexto:** assessoria de comunicação (`communicator`) e coordenação/candidatura, em `/campanha/comunicacao/conteudos`, na mesa ou no celular, sob prazo — quem não é da vertical (`advisor`, `leader`) segue negado.
- **Job principal:** "tirar da Central uma peça que não serve mais — errada, duplicada ou vencida — sem depender do admin do Payload".
- **Fluxo desejado:** abre a Central → vê a peça que não serve na lista (ou no detalhe) → "Apagar" → a confirmação avisa o efeito (se publicada, o link público morre para quem já recebeu) → confirma → a peça some da lista interna, some da Central pública e o arquivo privado sai junto.
- **Anti-goals de produto:** não virar lixeira/desfazer (soft delete) nem restauração; sem lote; sem editor de peça; sem métricas/telemetria de exclusão; sem dashboard nova; não mexer no kill switch de publicação (despublicar continua o gesto reversível e existente).
- **Reabertura de anti-goal (produto):** o C211 (`docs/plans/central-conteudos-ingestao.md`) declarou "sem delete na Central; só admin do Payload" como guardrail aceito. O pedido humano reabre de propósito. Ao apagar, respeitar o contrato público: uma peça publicada tem link `/conteudos/<slug>` já distribuível, então apagar é ação explícita e avisada — nunca em silêncio.
### Esboço de fluxo (B)
```text
[Central de Conteúdos: lista] → peça que não serve (na lista ou no detalhe)
→ [Apagar] → confirmação: "Apagar esta peça?" (avisa o link público se publicada)
→ confirma → some da lista interna, some da Central pública, arquivo privado sai junto
[outcome: Central limpa, sem peça fantasma e sem arquivo órfão]
```
### Design UI (B)
- Design UI (gate): `docs/plans/central-conteudos-apagar-peca-ui-design.html` — encaixe na lista (ação por linha, junto de Abrir/Reprocessar) e no detalhe; a distribuição exata das cenas é do design.
## Objetivo e aceite
- A Central (lista e detalhe) permite apagar uma peça, com confirmação explícita; após apagar, a peça some da Central e não aparece na pública.
- Apagar peça publicada avisa, no diálogo, que o link `/conteudos/<slug>` deixa de funcionar para quem já recebeu; despublicar continua a alternativa reversível (não é pré-requisito).
- "Apagar" existe em qualquer estado — inclusive `processando` (saída de quem quer cancelar um processamento travado) e `falhou`. _(assumido — validar no gate)_
- O arquivo privado da peça sai junto (mídia exclusiva da peça, sem resíduo no storage); os contadores de circulação morrem com a peça — não há dashboard a limpar. _(assumido — validar no gate)_
- **Quem pode apagar:** a mesma audiência da vertical que hoje cria/edita/publica (`communicator`, `coordinator`, `candidate`) + admin do Payload; `advisor`/`leader` negados (fail-closed).
- Apagar é definitivo (hard delete, sem lixeira/desfazer) e por peça, sem lote na v1.
## Dados (intenção)
- **Vou apresentar dados?** Não — é uma decisão de estado do item (apagar), não um painel.
- **Decisões desbloqueadas:** a assessoria decide o que sai da Central; nenhuma leitura agregada nova.
- **Forma:** _adiada ao plano de implementação_ — restrição de produto: sem contador de exclusão, sem auditoria exposta, sem telemetria de "peças apagadas".
## Dados da decisão (literais)
- **Ação:** `Apagar` (na lista e no detalhe).
- **Diálogo:** título `Apagar esta peça?` · botões `Cancelar` / `Apagar`.
- **Corpo (peça publicada):** `O link público /conteudos/<slug> deixa de funcionar para quem já recebeu. Esta ação não pode ser desfeita.`
- **Corpo (rascunho/em processamento/falhou):** `Esta ação não pode ser desfeita.`
- **Estados:** processamento `processando` | `pronto` | `falhou`; publicação `rascunho` | `publicado` — apagar disponível em todos.
- **Rotas internas:** `/campanha/comunicacao/conteudos` (lista) e `/campanha/comunicacao/conteudos/[id]` (detalhe).
- **Contrato público:** peça publicada aparece em `/conteudos/<slug>` (S27) e serve a mídia em `/conteudos/<slug>/midia`; apagar quebra esses links para quem já recebeu — daí o aviso.
- **Acesso:** `communicator`, `coordinator`, `candidate` apagam; `advisor` e `leader` negados (fail-closed); admin do Payload mantém o delete.
## Direção no codebase (hipótese)
- **Áreas prováveis:** lista `src/app/(campaign)/campanha/(app)/comunicacao/conteudos/page.tsx` (`src/components/campaign/content/ContentPieceTable.tsx`, `ContentPieceCardList.tsx`) e detalhe `.../conteudos/[id]/page.tsx`; access em `src/collections/ContentPiece.ts` (o `delete` a reabrir) e predicados em `src/utilities/access/contentPieces.ts`; leitura pública em `src/utilities/content/contentPieceReads.ts`; mídia privada `src/collections/ContentMedia.ts`.
- **Precedente a olhar:** C183 — `src/components/campaign/speech/SpeechCutDeleteDialog.tsx` (AlertDialog, aviso do link público, botão destructive) e `docs/plans/biblioteca-cortes-apagar-e-falhas.md`; cascata de mídia própria em `src/collections/Speech.ts` (`deleteSpeechAssets`).
- **Risco de acoplamento:** a lista pública é cacheada (tag `contentPieces`) e hoje só o `afterChange` a busta — apagar precisa refletir na pública sem peça fantasma; o job de processamento tolera a row sumida (cancelar em `processando` não pode derrubar o worker); eventos de circulação (`ContentEvent`, C213) referenciam a peça por `subjectId` texto, sem FK — órfãos inertes, não limpar.
## Dependências
- Nenhuma — o C211 está entregue; o S27 é o contrato público a respeitar.
## Fora de escopo
- Lote (apagar várias peças), lixeira/desfazer e restauração (soft delete).
- Limpar eventos órfãos de circulação (C213) — são inertes e não aparecem em lugar nenhum após a peça sumir.
- Métricas/telemetria de exclusão e dashboard nova.
- Apagar mídia compartilhada de outra peça (não existe) e qualquer mudança na página pública além de a peça sumir.
- Mexer no kill switch de publicação: despublicar continua o gesto reversível; editor de peça fica de fora.
## Rabbit holes de produto
- **"Já que apaga, deixa uma lixeira pra desfazer."** Se alguém "só completar": soft delete, retenção e restauração. **Corte neste item:** apagar é definitivo, com confirmação; sem lixeira.
- **"Já que apaga, apaga em lote."** Se alguém "só completar": seleção múltipla, confirmação em massa, progresso. **Corte neste item:** uma peça por vez (v1); lote é item próprio se o uso pedir.
- **"Já que apaga, limpa os eventos órfãos."** Se alguém "só completar": varredura/reconciliação de `ContentEvent`. **Corte neste item:** eventos órfãos são inertes; sem faxina de analytics.
## Questões em aberto (produto)
- **Apagar em qualquer estado ou bloquear `processando`?** **Opções:** A) qualquer estado, inclusive `processando` (cancelar job travado) | B) só depois de `pronto`/`falhou`. **Recomendação:** A — quem quer cancelar um processamento travado precisa da saída; o job tolera a row sumida. _(assumido — validar no gate)_
- **Ação na lista ou só no detalhe?** **Opções:** A) só no detalhe | B) na lista (junto de Abrir/Reprocessar) e no detalhe. **Recomendação:** B — a limpeza acontece na lista e a confirmação evita o clique errado. _(assumido — validar no gate)_
- **Arquivo privado sai junto ou fica órfão adiado?** **Opções:** A) sai junto com a peça | B) fica órfão, como no C183. **Recomendação:** A — aqui a mídia é exclusiva da peça (o público serve o mesmo objeto), então resíduo não faz sentido; o "como" fica para o plano de implementação. _(assumido — validar no gate)_
- **Publicada, apagar é definitivo ou redireciona para "Despublicar"?** **Opções:** A) apaga de vez com aviso | B) só despublica. **Recomendação:** A — despublicar é reversível e já existe; quem quer apagar quer remover de vez. _(assumido — validar no gate)_
## Referências
- GitHub Issue: #1330
- Design UI (gate): `docs/plans/central-conteudos-apagar-peca-ui-design.html`
- Precedente: `docs/plans/biblioteca-cortes-apagar-e-falhas.md` (C183, #1105) · `src/components/campaign/speech/SpeechCutDeleteDialog.tsx`
- Planos irmãos: `docs/plans/central-conteudos-ingestao.md` (C211, anti-goal reaberto) · `docs/plans/central-conteudos-publica.md` (S27, contrato do link) · `docs/plans/central-conteudos-analytics.md` (C213, eventos)
- Arquivos-pista: `src/collections/ContentPiece.ts` · `src/collections/ContentMedia.ts` · `src/utilities/access/contentPieces.ts` · `src/utilities/content/contentPieceReads.ts` · `src/components/campaign/content/ContentPieceTable.tsx` · `src/components/campaign/content/ContentPieceCardList.tsx` · `src/app/(campaign)/campanha/(app)/comunicacao/conteudos/page.tsx` e `[id]/page.tsx`
- Testes a tocar: `tests/int/contentPiece.int.spec.ts` · `tests/e2e/campaignSpeechAcervo.e2e.spec.ts` (seção C211) · `tests/unit/speechCutDeleteDialog.unit.spec.tsx` (molde do diálogo)
- `AGENTS.md` — vertical Comunicação, fail-closed, mídia privada/S3
## Self-score (shaping)
5/5 — (1) fatia = um outcome verificável (apagar uma peça e ela sumir da Central e da pública, sem resíduo de arquivo); (2) appetite ~1 dia declarado e o escopo cabe (encaixe na lista/detalhe, sem lote/lixeira/telemetria); (3) persona, job e aceite em linguagem de usuário, com a reabertura do anti-goal e o contrato do link público explícitos; (4) direção no codebase é hipótese com precedente nomeado, sem contrato; (5) zero decisão dura de engenharia (formato da ação, cascata de mídia e bust de cache ficam para o plano de implementação — aqui só se declara quem pode apagar e o efeito de produto).