O que este diretório é e como operá-lo. Contexto de design/decisões:
docs/. Processo de implementação do v1:docs/13-diario-v1.md.
Comandos (da raiz do repositório)#
node site/build/build.mjs # compila tudo → site/dist/ (falha se qualquer verificação reprovar)
node site/build/serve.mjs # dev em http://localhost:8123 — USE ESTE (tem HTTP Range;
# python http.server NÃO tem, e sem Range o vídeo não faz seek)
sh site/build/gera-media.sh # derivados do v1 (poster, sprites, waveform, VTT) — só quando o
# vídeo/SRT mudar; requer o MP4 na raiz e ffmpeg
sh site/build/gera-media-v2.sh # derivados do v2 (fundos de capítulo, posters de evento, imagens
# da Jornada, p.13 do Groix) — requer ffmpeg e pdftoppm
sh site/build/gera-media-v3.sh # derivados do v3 (clipes de voz A01-A12, room tone, imagens)
node site/build/build.mjs # Google Analytics (G-TPW530Y78R) já embutido — só ativa em
# zeide.fpripas.com; GA_ID="" desliga, GA_ID=G-... substitui
Zero dependências (decisão 34): nada de npm install — Node ≥ 18 e pronto.
O vídeo#
O MP4 (1,25 GB) nunca entra no git. No dev, o build cria um symlink dist/media/mojsie-1997.mp4 → arquivo na raiz. Na VPS, subir o arquivo UMA vez (scp) e apontar o nginx (abaixo).
Deploy na VPS#
Desenho fechado com o Tobi/main em 02/09/2026; nada executado ainda. O contrato completo (caminhos, papéis, nginx, monitoramento, pendências) está em
docs/17-deployment.md. Não improvise a partir deste resumo.
Regra que governa tudo: o Tobi/main é o único que altera configuração da VPS (nginx, TLS/certbot, permissões, systemd). Este lado gera conteúdo estático e verifica.
Caminhos canônicos:
| Caminho | O quê |
|---|---|
/var/www/zeide.fpripas.com/ | web root do nginx (fpripas:fpripas, dirs 0755, files 0644) |
/var/www/zeide-media/mojsie-1997.mp4 | o vídeo de 1,25 GB — fora do web root, fora do rsync |
/home/fpripas/prod/zeide/staging/dist | onde eu entrego o artefato (+ SHA256SUMS) |
/home/fpripas/prod/zeide/rollback/ | uma release anterior, só uma |
Site slug: zeide-fpripas-com. Sem porta, sem backend, sem systemd unit.
- Primeira publicação: eu entrego em
staging/; o Tobi faz o preflight Tier 2, instala nginx + TLS e promove. - Atualizações depois: Tier 0 via helper de caminhos fixos que o Tobi vai escrever,
skills/shared-webserver-ops/scripts/deploy-zeide-fpripas-com.sh(deploy/verify/rollback). - Canal de pedido: sessão
agent:main:zeide-deploy(formato emdocs/17-deployment.md§9).
Acesso: ssh tobi-vm. O openclaw real está no Homebrew — precisa de export PATH=/home/linuxbrew/.linuxbrew/bin:$PATH.
Detalhe do nginx que não pode ser trocado por engano: try_files $uri $uri/ =404, nunca fallback para index.html — isto não é SPA e o 404 tem que dar 404.
Rotas (v3 — o site completo)#
/ home (prólogo na 1ª visita + foto-objeto + portas) · /entrevista/ · /jornada/ · /memorial/ (14 telas, a voz dele) · /arquivos/ (v4, decisão 40: navegador + visualizador — /arquivos/{pecas,fotos,documentos,cadernos,voz}/<id>/, 274 páginas PT+EN; derivadas geradas no build em public/media/arq/, fora do git — requer ffmpeg e pdftoppm) · /pessoas/ · /nao-sabemos/ · /guia/ · /sobre/ · /calendario.ics · espelhos EN com slugs traduzidos (/en/archives/, /en/people/, /en/unknown/, /en/glossary/, /en/guide/, /en/about/) · busca global (⌘K ou /) em todas · deep links: /entrevista/#t=55m43s · /jornada/#e-groix · /arquivo/#d-D07 · /pessoas/#p-frania · /#abertura (repetir o prólogo).
Estrutura#
| Caminho | O quê |
|---|---|
build/build.mjs | o gerador (Node puro) — parse dos .md → HTML/JSON + verificações |
build/lib/parse-transcricao.mjs | parser das transcrições (preservação verbatim garantida) |
build/gera-media.sh + -v2.sh + peaks.py + thumbs_vtt.py | derivados do vídeo (11 §3–4) |
build/data/timeline.mjs | OS DADOS da Jornada: capítulos, 61 eventos curados, o fio (editar AQUI) |
build/data/memorial.mjs · mapa.mjs · secoes.mjs | os dados do v3: telas, fuga/trens, Arquivo/Pessoas/Não-sabemos |
build/lib/hebreu.mjs | calendário hebraico próprio (yahrzeits do ics) — validado no build |
build/serve.mjs | dev server com Range |
src/css/site.css · docs/tokens.css | estilos (tokens = fonte da verdade visual) |
src/js/comum.js · entrevista.js · jornada.js · home.js | JS por página (≤11 KB gzip/página; orçamento 30) |
src/i18n/{pt,en}.json | strings de UI |
public/fonts/ · public/media/ | assets commitados (fontes woff2; derivados pequenos) |
dist/ | saída (gitignored — sempre regenerável) |
Invariantes (não quebrar)#
- O build falha se: o parser achar problema,
[?]se perder, JS > 30 KB gzip, ou um nome da listaSENTINELAS(build/arquivos.mjs) vazar para fora da/entrevista/— é a cerca de redação dos nascidos depois de 1950 (decisão 40). Flavio Pripas é a exceção. - Atenção, isto mudou: a antiga denylist de
pesquisa/pedidos-prontos.mdnão existe mais. A decisão 40 (02/09/2026) publica os cadernos.mdna íntegra, inclusive os pedidos prontos (/arquivos/cadernos/pedidos-prontos/, live desde 02/09/2026). Se a intenção mudar, o caminho é tirar a entrada deCADERNOSembuild/data/arquivos.mjs, não ressuscitar a denylist. - Verbatim é sagrado: o parser não altera um caractere; sha256 dos fontes fica em
dist/build-info.json. - Tudo self-hosted: sem CDN, sem font externa, sem third-party no caminho crítico (GA async é o único opcional, e só na área pública).