70 lines
4.6 KiB
Markdown
70 lines
4.6 KiB
Markdown
# Projeto Portaria
|
|
|
|
Portaria virtual para prédios residenciais e comerciais. O visitante escaneia um QR na entrada, o morador valida por videochamada e autoriza a entrada — com operador humano de retaguarda para quando ninguém atende.
|
|
|
|
**Este repositório contém, por enquanto, a especificação e os prompts de implementação.** Nenhum código de aplicação foi escrito ainda.
|
|
|
|
---
|
|
|
|
## Como usar
|
|
|
|
Leia `docs/` na ordem, depois execute `prompts/` fase por fase. Cada prompt referencia as seções dos documentos que precisa respeitar — os documentos são a fonte de verdade, os prompts são o roteiro.
|
|
|
|
**Não pule fases e não junte duas num prompt só.** O fatiamento existe porque as áreas de maior risco (WebRTC, notificação de chamada no iOS, LGPD) são exatamente as que um prompt monolítico implementa pela metade.
|
|
|
|
## Documentos
|
|
|
|
| Documento | Conteúdo |
|
|
|---|---|
|
|
| [`00-VISAO-E-PRODUTO`](docs/00-VISAO-E-PRODUTO.md) | Problema, personas, jornadas, planos comerciais, escopo, métricas |
|
|
| [`01-ARQUITETURA`](docs/01-ARQUITETURA.md) | **Espinha.** Stack, monorepo, os 7 padrões de robustez, ADRs |
|
|
| [`02-MODELO-DE-DADOS`](docs/02-MODELO-DE-DADOS.md) | Schema Postgres, outbox, fila, retenção, RLS preparada |
|
|
| [`03-FLUXOS-E-CONTRATOS`](docs/03-FLUXOS-E-CONTRATOS.md) | Máquinas de estado, REST, WebSocket, idempotência |
|
|
| [`04-DESIGN-SYSTEM-UX`](docs/04-DESIGN-SYSTEM-UX.md) | Tokens, telas, movimento, acessibilidade |
|
|
| [`05-INFRA-DOCKER`](docs/05-INFRA-DOCKER.md) | Compose, LiveKit, portas, banda, observabilidade, CI/CD |
|
|
| [`06-LGPD-E-SEGURANCA`](docs/06-LGPD-E-SEGURANCA.md) | Bases legais, modelo de ameaças, direitos do titular |
|
|
| [`07-REQUISITOS-DE-CAMPO`](docs/07-REQUISITOS-DE-CAMPO.md) | **Pré-requisitos contratuais de instalação**, não backlog |
|
|
|
|
## Fases
|
|
|
|
| Fase | Entrega |
|
|
|---|---|
|
|
| [0 — Bootstrap](prompts/FASE-0-bootstrap.md) | Monorepo, Docker, CI verde |
|
|
| [1 — Domínio e dados](prompts/FASE-1-dominio-e-dados.md) | `shared/` KMP, schema, outbox, fila, auth |
|
|
| [2 — API](prompts/FASE-2-backend-api.md) | REST, WebSocket, mídia, ciclo de vida da visita |
|
|
| [3 — Web do visitante](prompts/FASE-3-web-visitante.md) | PWA, ambos os funis, espera narrada |
|
|
| [4 — Chamada](prompts/FASE-4-chamada.md) | LiveKit, tokens, degradação graciosa |
|
|
| [5 — App do morador](prompts/FASE-5-app-morador.md) | Compose MP, FCM, PushKit/CallKit |
|
|
| [6 — Painel admin](prompts/FASE-6-painel-admin.md) | Auditoria, gestão, reconciliação |
|
|
| [7 — Escalonamento](prompts/FASE-7-escalonamento.md) | Fila de operador, app do operador, recado |
|
|
| [8 — Planos e LGPD](prompts/FASE-8-planos-e-lgpd.md) | Feature flags, retenção, direitos, SLOs |
|
|
| [9 — Hardening](prompts/FASE-9-hardening.md) | E2E, carga, falhas, segurança, piloto |
|
|
|
|
## Stack
|
|
|
|
**Backend** Spring Boot 3 + Kotlin · PostgreSQL 17 + PostGIS · jOOQ · Flyway
|
|
**Apps** Compose Multiplatform (Android + iOS) · **Web** Vite + React + TS
|
|
**Compartilhado** Kotlin Multiplatform (DTOs + máquina de estados)
|
|
**Mídia** LiveKit self-hosted + coturn · **Objetos** MinIO/S3
|
|
**Infra** Docker Compose + Traefik · OpenTelemetry + Prometheus + Grafana + Loki
|
|
|
|
## As decisões que mais importam
|
|
|
|
**O modelo é híbrido, não autônomo.** O morador é chamado primeiro — é a tese do produto. Mas a taxa de atendimento nunca é 100%, e o mercado consolidado usa operador humano 24h justamente por isso. Por isso vendemos dois planos, com o operador como retaguarda paga.
|
|
|
|
**Entrega tem funil próprio.** É a maioria do volume, e o entregador não espera videochamada. Foto do pacote, um toque, meta de 10s.
|
|
|
|
**A busca de unidade é cega.** A API nunca confirma se uma unidade existe — nem pelo corpo da resposta, nem pelo tempo. Sem isso, qualquer pessoa com o QR mapeia quem mora onde.
|
|
|
|
**A base legal é legítimo interesse, não consentimento.** Consentimento sob "aceite ou não entre" não é livre, e portanto não é válido. O que se faz é informar com clareza e arquivar a LIA.
|
|
|
|
**Sem reconhecimento facial.** Elevaria os dados a sensíveis, sem base legal disponível. Decisão jurídica, não limitação técnica.
|
|
|
|
**iOS exige PushKit + CallKit.** Notificação comum não faz o telefone tocar como chamada. Sem isso, o app não funciona como portaria.
|
|
|
|
**Wi-Fi e botão físico são contratuais.** Hall blindado não pega 4G, e nem todo visitante tem smartphone com bateria. Nenhum código resolve isso.
|
|
|
|
## Primeiro passo
|
|
|
|
Antes da FASE 4, derrube o maior risco técnico: suba `livekit-server` + `coturn` e feche uma chamada entre um navegador móvel em 4G real e um Android, medindo o tempo até o primeiro frame. É barato de testar e caro de descobrir tarde.
|