Arquitetura — Visão Geral
Diagrama de contexto (C4 Level 1)
┌─────────────────────────────────────────────────────────────────┐
│ Comprador │
│ (via WhatsApp) │
└───────────────────────────┬─────────────────────────────────────┘
│ mensagem
▼
┌─────────────────────────────────────────────────────────────────┐
│ Evolution API │
│ (gateway WhatsApp → webhook) │
└───────────────────────────┬─────────────────────────────────────┘
│ POST /webhook
▼
┌───────────────────────────────────────────────────────────────────────────────┐
│ Galgal (este sistema) │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────────────┐ │
│ │ galgal/api │ │ galgal/web │ │ apps/broker-web │ │
│ │ (FastAPI) │ │ (FastHTML) │ │ (Next.js) │ │
│ │ :8000 │ │ :8080 │ │ :3000 │ │
│ │ │ │ │ │ │ │
│ │ 50+ endpoints │ │ /chat playground│ │ Portal público │ │
│ │ OpenAPI /docs │ │ streaming UI │ │ Dashboard corretor │ │
│ └────────┬─────────┘ └────────┬─────────┘ └────────────┬─────────────┘ │
│ │ │ │ │
│ └──────────────────────┴───────────────────────────┘ │
│ │ │
│ ┌─────────────▼──────────────┐ │
│ │ Componentes Polylith │ │
│ │ agent · property · broker │ │
│ │ auth · lead · db · scraper │ │
│ └─────────────┬───────────────┘ │
└─────────────────────────────────┼─────────────────────────────────────────── ┘
│
┌─────────────▼───────────────┐
│ Neon PostgreSQL │
│ (106 imóveis, 1496 fotos) │
└──────────────────────────────┘
Polylith — Regras de separação
O projeto usa Python Polylith com namespace galgal. As camadas são:
| Camada | Onde | Regra |
|---|---|---|
| components | components/galgal/ |
Lógica reutilizável. Sem HTTP, sem main, sem instâncias de app |
| bases | bases/galgal/ |
Entry points (FastAPI app, FastHTML app). Delegam para components |
| projects | projects/ |
Só pyproject.toml + Dockerfile. Zero código Python |
Proibido: components importando bases. uv run poly check valida isso.
4 serviços Docker
graph LR
Internet --> Traefik
Traefik -- "api.viacorretor.com.br" --> api["api\n(FastAPI :8000)"]
Traefik -- "app.viacorretor.com.br" --> web["web\n(FastHTML :8080)"]
Traefik -- "viacorretor.com.br" --> broker["broker-web\n(Next.js :3000)"]
Traefik -- "admin.viacorretor.com.br" --> nocodb["nocodb\n(NocoDB)"]
api --> Neon[(Neon PostgreSQL)]
web --> Neon
broker -- "REST /v1/*" --> api
nocodb --> Neon
Componentes Python — dependências
galgal/api ──uses──► galgal/property
──uses──► galgal/broker
──uses──► galgal/lead
──uses──► galgal/auth
──uses──► galgal/db
──uses──► galgal/core
galgal/web ──uses──► galgal/agent
──uses──► galgal/property
──uses──► galgal/db
galgal/agent ──uses──► galgal/property (via tools)
──uses──► galgal/db
galgal/scraper ──uses──► galgal/db
Fluxo de uma mensagem do comprador (agente)
1. Comprador envia msg no WhatsApp
2. Evolution API → POST /webhook na galgal/api
3. galgal/api → chama galgal/agent.chat(msg, history, phase, deps)
4. galgal/agent:
a. _get_agent(phase) → prompt base + 4 exemplos da fase atual
b. LLM (OpenRouter) raciocina, decide usar tool ou responder
c. tools.buscar_imoveis() → galgal/property.repo.list_properties(db)
d. LLM gera resposta final
5. galgal/agent.interpret() → classifica fase + intenção do comprador
6. session.advance_phase() → atualiza phase da sessão (FSM determinístico)
7. Resposta volta via Evolution API → WhatsApp