| backend | ||
| frontend | ||
| .gitignore | ||
| AULA_1.html | ||
| AULA_1.MD | ||
| docker-compose.yml | ||
| Makefile | ||
| README.md | ||
panorama-br
API REST de dados territoriais e socioeconômicos do Brasil (IBGE, Wikidata, Wikipédia), para consumo pelos WebApps da disciplina de Frameworks.
Documentação da API, modelo de dados e rotas: backend/README.md.
Configuração
backend/.env é a única fonte de configuração. Porta, imagens Docker, nomes
de container, política de restart, caminho dos volumes e CORS saem todos de lá —
o Dockerfile e os dois docker-compose.yml não fixam nada.
Variável faltando faz o compose abortar com a mensagem de qual é, em vez de virar
string vazia.
- docker-compose.yml (raiz) → produção: banco + API
- backend/docker-compose.yml → dev: só o Postgres (a API roda local com
npm run dev)
make prod-config mostra o compose com tudo já resolvido a partir do .env.
CORS e acesso dos alunos
| Variável | Para que serve |
|---|---|
API_CORS |
É esta que define quem pode chamar a API pelo navegador. Lista separada por vírgula, ou * para qualquer origem. Vazio → em dev libera tudo, em produção bloqueia tudo. |
TRUSTED_ORIGINS |
Checagem de origin/CSRF do better-auth nas rotas /auth/*. Aceita curinga (*, *.vercel.app). Sem isso o login de outra origem volta 403 INVALID_ORIGIN. |
FRONTEND_URL |
Não tem relação com CORS — só monta o link /definir-senha?token= nos e-mails de reset de senha. |
Para a disciplina (cada aluno rodando o front onde quiser — localhost:3000,
:5173, deploy na Vercel…), o .env já vem com:
API_CORS=*
TRUSTED_ORIGINS=*
Com * a API devolve no Access-Control-Allow-Origin a origem do próprio
request (não o literal *), que é o que permite continuar mandando o cookie de
sessão junto — credentials: true e * literal são incompatíveis no navegador.
Duas coisas que precisam estar certas no servidor para o login funcionar de
qualquer origem: NODE_ENV=production (é o que liga secure +
sameSite=none no cookie, obrigatório em requisição cross-site) e HTTPS na URL
pública. COOKIE_DOMAIN fica vazio quando o front está em outro domínio.
Deixar TRUSTED_ORIGINS=* significa abrir mão da proteção de origem do
better-auth nas rotas de auth — aceitável para uma API de aula com
ROTAS_PUBLICAS=true, mas troque por uma lista se algum dia isso virar produção
de verdade.
Comandos
Modo Desenvolvimento
cd backend && npm installcp .env.example .envmake dev-infra-up→ Postgres dev (5081) + testes (5082)make dev-db-reset→ dropa, recria, trigger e seedsmake dev-api→ porta 5080, docs em/docsmake dev-test
Carga dos dados (dentro de backend/, na ordem):
npm run etl:populacao → etl:pib → etl:piramide → etl:malhas →
etl:wikidata → etl:wikipedia → etl:midia → npm run db:validate.
Observação: após colocar em produção use no lugar do db:push
npm run db:generate + npm run db:migrate.
Login demo: admin@example.com / 102030fs (também gestor@ e usuario@)
Deploy na VM (já no ar)
https://api.panorama-br.fslab.dev — docs em /docs, spec em /docs/openapi.json.
O projeto está em ~/panorama-br na VM de vm.env (fora do git). Redeploy:
make deploy # rsync do código + build + up na VM
make deploy-status # status dos containers
make deploy-logs # logs da API (follow)
make deploy-shell # shell na VM, já no diretório do projeto
make deploy-db-push # copia o banco LOCAL por cima do de produção (sobrescreve)
O make deploy nunca sobrescreve o backend/.env do servidor — ele existe
só lá, com NODE_ENV=production, URLs públicas, TRUST_PROXY=1 e segredos
próprios. Para mudar configuração em produção, edite o .env pelo
make deploy-shell e rode make prod-restart.
TLS e o roteamento de api.panorama-br.fslab.dev → VM:5080 são resolvidos na
infra do fslab, fora desta VM. Por isso TRUST_PROXY=1 (para o rate limit ver o
IP real) e por isso a API responde HTTP na 5080.
Modo Produção (passo a passo, primeira subida)
- Criar o
backend/.envno servidor e ajustar as linhas marcadas[PROD]no.env.example:NODE_ENV=production,BETTER_AUTH_SECRETnovo (openssl rand -hex 32),API_URL/BETTER_AUTH_URLcom a URL pública,TRUST_PROXY=1se houver reverse proxy na frente make prod-check→ avisa se algo essencial ficou de foramake prod-build→ cria a imagem da APImake prod-up→ sobe banco + APImake prod-db-sync→ cria a estrutura (push) + trigger de históricomake prod-db-seed→ hierarquia territorial, capitais, indicadores, papéis/usuáriosmake prod-etl→ carga dos indicadores + malhas + mídia (idempotente e retomável)make prod-db-validate→ checklist de validação pós-carga
Se for adotar migrations, já na primeira subida troque o passo 5 por:
npm run db:generate no dev (migration inicial) → commit → make prod-db-migrate
(um banco criado via push não aceita a primeira migration depois — ela tentaria
recriar as tabelas).
Quando alterar models:
- no dev,
npm run db:generate(gera a migration embackend/drizzle/) → commit make prod-buildmake prod-upmake prod-db-migrate
Os dados do Postgres ficam em ${DATA_DIR}/postgres e o cache cru do ETL em
${DATA_DIR}/raw — ambos montados como volume, fora do git. O Postgres é
publicado só em 127.0.0.1 (POSTGRES_BIND); para acessar de fora, túnel SSH.
make help lista todos os alvos (logs, restart, status, shell…).