# 08 — Anexos (seção 19: checklist de materiais) ## Contexto do projeto (leia sempre) Sistema web "Briefing de Site" da SeConectai: o cliente se cadastra e depois preenche o briefing de criação do site, com um botão **Ajuda** em cada pergunta que abre um popup com o texto do guia auxiliar. O dono (Tiago) acompanha tudo por um painel admin. **Stack fixa:** Next.js 14+ (App Router) + TypeScript, PostgreSQL 16, Prisma, Tailwind + shadcn/ui, React Hook Form + Zod, Auth.js v5 (Credentials, estratégia JWT), Docker Compose. Idioma da interface: pt-BR. **Regras gerais:** leia `00-arquitetura-briefing-site.md` e `99-progresso.md` antes de começar; não avance se a etapa anterior estiver incompleta; ao terminar, devolva o `99-progresso.md` atualizado. Não invente dependências fora da stack. Nada de senhas de clientes em lugar nenhum. ## Pré-requisito Etapa 07 concluída. ## Tarefa A seção 19 do briefing tem 15 itens do tipo `ANEXO` (logotipo, manual de identidade, fotos, vídeos, textos, catálogo, lista de serviços, depoimentos, cases, certificações, dados de contato, redes sociais, referências de sites, política/termos, domínio e hospedagem sem senhas). 1. Em cada item `ANEXO`: caixa "Estou enviando este material" (equivale ao ☐ do documento), campo de texto para links (Drive, Dropbox, YouTube) e área de upload de arquivos. 2. **Upload** via route handler com `multipart/form-data`: máximo `UPLOAD_MAX_MB` por arquivo e 20 arquivos por pergunta; permitir imagens (png, jpg, webp, svg), pdf, docx/doc, xlsx/xls, pptx, zip, mp4/mov; validar extensão **e** tipo MIME **e** conteúdo básico (magic bytes); nome do arquivo no disco = UUID (nunca o nome original); salvar em `UPLOAD_DIR` (volume Docker, **fora de `/public`**). 3. **Download** apenas via `/api/anexos/[id]`, autenticado: dono do briefing ou ADMIN. Cabeçalhos `Content-Disposition: attachment` e `X-Content-Type-Options: nosniff`. 4. Listar anexos com nome, tamanho e botão remover (somente em RASCUNHO). Barra de progresso por arquivo. 5. Aviso fixo na seção: "Não envie senhas. Informe apenas provedores e responsáveis." ## Critérios de aceite - [ ] Upload/remoção funcionam; arquivo inválido ou grande demais é recusado com mensagem clara. - [ ] Acessar a URL do arquivo sem login ou como outro cliente retorna 403/404. - [ ] Nenhum arquivo fica acessível por URL pública estática. - [ ] Briefing ENVIADO não aceita novos uploads/remoções. Atualize `99-progresso.md` (08).