# Arquitetura de Software

**Licença: AGPL-3.0** — escolhida porque fecha a brecha do serviço hospedado: quem rodar uma versão modificada como serviço em rede é obrigado a publicar o fonte. É a salvaguarda jurídica contra a captura do tipo plataforma.

## Princípios de projeto

1. **Local-first.** A padaria opera offline. Internet caiu, o PDV continua vendendo. Sincronização quando voltar. (Cooperativa de bairro não pode depender de nuvem.)
2. **Um servidor barato basta.** Tudo roda num mini-PC de R$ 1.500 na própria padaria. Sem mensalidade obrigatória de SaaS.
3. **Chato e sólido.** Stack conservadora, dependências mínimas, instalável por um estudante de extensão em uma tarde. O software vai ser mantido por décadas com mão de obra rotativa.
4. **Transparência como recurso.** Todo cooperado autentica e vê tudo (menos dados pessoais de terceiros). Não há papel "dono".
5. **Federação opcional.** A cooperativa funciona 100% sem a rede. A federação é um módulo que se liga.

## Stack de referência

| Camada | Escolha | Justificativa |
|---|---|---|
| Servidor local | Python (FastAPI) + SQLite → PostgreSQL se crescer | Simplicidade de manutenção; SQLite é imbatível em robustez local |
| PDV e painéis | PWA (HTML/JS, offline-first com service worker + IndexedDB) | Roda em qualquer navegador/tablet barato; sem app store |
| Sincronização interna | CRDTs simples (LWW por registro) entre PDV e servidor local | Vendas nunca se perdem com rede instável |
| Federação (rede) | ActivityPub-like sobre HTTPS: JSON assinado (Ed25519), pull-based | Sem servidor central obrigatório; a associação roda um agregador, mas qualquer nó pode agregar |
| Impressão fiscal | Integração NFC-e via biblioteca aberta por UF | Módulo isolado — a parte que mais muda |
| Backup | Cópia criptografada diária para 2 destinos (pendrive local + storage da rede) | |

## Módulos (monorepo)

```
forno-software/
├── core/            # domínio: produtos, receitas, estoque, cooperados, caixa
├── pdv/             # ponto de venda (PWA offline-first)
├── producao/        # plano de produção diário, receitas YAML, custo por receita
├── estoque/         # entradas, pontos de reposição, validade, inventário (S3*)
├── cooperados/          # cadastro, horas trabalhadas, escala (S2), retiradas
├── financas/        # caixa, DRE simplificado, sobras, painel aberto a cooperados
├── governanca/      # atas, votações em assembleia, registro de mediação
├── auditoria/       # trilhas imutáveis (append-only log), checklists RDC 216
├── indicadores/     # cálculo dos indicadores de 00-modelo/indicadores.md
├── federacao/       # publicação de agregados ao commons; compra conjunta
├── manutencao/      # cronograma preventivo de equipamentos
└── deploy/          # docker-compose, script de instalação, backup
```

## Modelo de dados (núcleo, SQL)

```sql
CREATE TABLE cooperado (id, nome, cpf_hash, admissao, situacao, quota_integralizada);
CREATE TABLE hora_trabalhada (id, cooperado_id, inicio, fim, frente, origem); -- origem: escala|manual
CREATE TABLE produto (id, nome, linha, preco, receita_versao, ativo);
CREATE TABLE receita (id, nome, versao, yaml, custo_direto_calc, atualizado_em);
CREATE TABLE insumo (id, nome, unidade, custo_medio, ponto_reposicao, fornecedor_id);
CREATE TABLE mov_estoque (id, insumo_id, qtde, tipo, lote, validade, ts); -- entrada|consumo|perda|inventario
CREATE TABLE venda (id, ts, pdv_id, total, forma_pgto, sincronizado);
CREATE TABLE venda_item (venda_id, produto_id, qtde, preco_unit);
CREATE TABLE producao_dia (data, produto_id, planejado, produzido, quebra);
CREATE TABLE caixa_evento (id, ts, tipo, valor, cooperado_a, cooperado_b); -- abertura|sangria|fechamento; 4 olhos
CREATE TABLE retirada (id, cooperado_id, competencia, horas, valor);
CREATE TABLE ata (id, orgao, data, texto, hash_anterior);           -- cadeia de hashes: imutável
CREATE TABLE auditoria_log (id, ts, ator, acao, payload, hash_anterior); -- append-only
```

## API (contratos principais)

```
POST /vendas                 # PDV → servidor (idempotente, aceita lote offline)
GET  /painel/financas        # aberto a qualquer cooperado autenticado
GET  /producao/plano?data=   # plano do dia (média móvel 28d + ajuste manual)
POST /governanca/votacao     # criação e apuração de votações de assembleia
GET  /indicadores/mes/{aaaa-mm}
POST /federacao/publicar     # gera payload agregado; exige aprovação da coordenação
GET  /federacao/benchmark    # posição da coop na distribuição da rede (anonimizada)
POST /federacao/compra-conjunta/intencao   # agrega demanda de insumos entre coops
```

## Protocolo de federação (resumo)

1. Cada cooperativa tem um par de chaves Ed25519; a pública é registrada na associação ao aderir à rede.
2. Mensalmente o módulo `indicadores` gera o payload agregado (`federacao/schema-indicadores.json`), a coordenação revisa e aprova, o nó assina e publica num endpoint próprio.
3. O agregador da associação faz *pull* dos endpoints, valida assinaturas, publica o benchmark anonimizado e a base da COF Aberta.
4. Revogação: a cooperativa simplesmente para de publicar. Não há mecanismo de coleta sem consentimento — o protocolo é pull sobre o que a coop escolheu expor.

## O que deliberadamente NÃO existe

- Conta de administrador da rede com acesso remoto às instâncias locais.
- Telemetria automática não revisada por humanos.
- Dependência de serviço proprietário para função essencial (pagamento por PIX usa API do banco escolhido pela coop, módulo isolado e substituível).
