TermoFlow roda como uma stack completa: Frontend (SPA) → Middleware (GraphQL gateway) → Backend (API REST), com PostgreSQL e MongoDB como datastores.
| Módulo | Porta (Docker) | O que faz | Docs |
|---|---|---|---|
apps/frontend |
3000 |
SPA React (CRA) + Ant Design servida via Nginx. Faz proxy de /api/* para o middleware (evita CORS). |
apps/frontend/README.md |
apps/middleware |
4000 |
Gateway GraphQL com hardening (rate limit, API key opcional, limites de query). Resolve upstreamGet para chamadas GET ao backend (com allowlist de paths). |
apps/middleware/README.md |
apps/backend |
3001 |
API REST (Express + Prisma) com regras multi-tenant (via headers) e auditoria (Mongo). | apps/backend/README.md |
- O navegador acessa a SPA em
http://localhost:3000. - A SPA faz
POSTde GraphQL parahttp://localhost:3000/api/graphql(por padrão). - O Nginx do frontend faz proxy de
/api/*para o middleware (http://middleware:4000/*), então/api/graphqlvira/graphql. - O middleware valida a requisição (tamanho, limites, rate limit, API key opcional) e resolve a query.
- A query
upstreamGet(path: "/items")(por exemplo) vira umGETno backend (UPSTREAM_BASE_URL + path), somente se opathestiver dentro deUPSTREAM_ALLOWED_PATH_PREFIXES. - O middleware repassa headers de contexto (ex.:
x-tenant-id,x-user-id,x-company-id) para o backend. - O backend exige
x-tenant-idex-user-id(UUID) e usa:- Postgres (Prisma) para dados (ex.:
items,organizations). - MongoDB para auditoria (ex.:
POST /itemsgrava audit log).
- Postgres (Prisma) para dados (ex.:
Pré-requisitos: Docker + Docker Compose.
cd TermoFlow- Suba a stack:
docker compose up --build
- Primeira execução: aplique as migrations do Postgres (backend):
docker compose run --rm backend npx --yes prisma@5.22.0 migrate deploy
- URLs:
- Frontend:
http://localhost:3000/(GraphQL viahttp://localhost:3000/api/graphql) - Middleware GraphQL:
http://localhost:4000/graphql - Backend API:
http://localhost:3001 - Postgres:
localhost:5432, Mongo:localhost:27017
- Frontend:
- Frontend (build-time):
REACT_APP_GRAPHQL_URL,REACT_APP_TENANT_ID,REACT_APP_USER_ID(definidos comobuild.argsnodocker-compose.yml). - Middleware:
UPSTREAM_BASE_URL(no compose da raiz:http://backend:3000)UPSTREAM_ALLOWED_PATH_PREFIXES(no compose da raiz:/items,/organizations)API_KEY(opcional, protege o/graphql)
- Backend:
DATABASE_URL/MONGO_DATABASE_URLapontam parapostgresemongo(containers do compose).- Headers obrigatórios para rotas tenant-scoped:
x-tenant-idex-user-id(UUID).
Health do middleware:
curl -s http://localhost:4000/graphql \
-H "content-type: application/json" \
-d '{"query":"{ health { ok service version time } }"}'Lista items via GraphQL (proxy para GET /items do backend):
curl -s http://localhost:4000/graphql \
-H "content-type: application/json" \
-H "x-tenant-id: 11111111-1111-1111-1111-111111111111" \
-H "x-user-id: 22222222-2222-2222-2222-222222222222" \
-d '{"query":"{ upstreamGet(path:\"/items\") }"}'- Modelo canônico (multi-tenant):
apps/backend/docs/canonical-model.md - Convenções de UI / Central de Cadastramento:
apps/frontend/docs/central-cadastramento.md