Plataforma de monitoramento da vegetação rodoviária que conecta dados geoespaciais e de satélite, recomendações explicáveis, decisão humana, trabalho de campo e relatórios auditáveis.
Limite atual: o repositório implementa um MVP demonstrativo. Dados e fluxos marcados como
prepared,estimatedousimulatednão representam operação real, não autorizam roçada e não podem alimentar treinamento de modelos nem relatórios oficiais.
- Objetivo e regras essenciais
- Estado atual
- Arquitetura do repositório
- Início rápido
- Como rodar cada parte do projeto
- Dados, proveniência e importação
- Banco de dados e migrações
- Fluxos e APIs principais
- Desenvolvimento e validação
- Segurança e limitações conhecidas
- Documentação
O ZENIT busca fechar este ciclo:
dados rodoviários + imagem de satélite + histórico
→ análise por segmento e zona
→ recomendação explicável
→ revisão e decisão humana
→ ordem e coleta móvel offline
→ fotos, medições e sincronização
→ histórico e relatório
As regras de domínio que não podem ser flexibilizadas são:
- analisar segmentos de 100 m, separando margem esquerda, margem direita, canteiro central e áreas especiais;
- usar 30 cm como limite geral e 10 cm em áreas especiais ou operacionais;
- preservar as classes históricas: N1 abaixo de 10 cm, N2 entre 10 e 30 cm e N3 acima de 30 cm;
- encaminhar baixa confiança normalmente para inspeção;
- nunca permitir que a IA autorize uma roçada silenciosamente;
- preservar decisões humanas, versões de regras/modelos, trilha de auditoria e proveniência;
- distinguir dados reais, estimados, preparados, simulados e inconclusivos;
- nunca usar dados demonstrativos ou simulados para treinamento ou relatório oficial.
As planilhas fornecidas têm data de referência 2025-03-28. Elas não descrevem a condição atual da vegetação e não formam uma série de crescimento.
- Monorepo com FastAPI/Python, Next.js/TypeScript, Flutter, PostgreSQL/PostGIS, MinIO e Docker Compose.
- Catálogo imutável de fontes, checksums, linhagem e importações idempotentes.
- Parsers tipados para KMZ/KML e planilhas, com anomalias documentadas.
- Eixo candidato derivado dos marcos e dividido em 309 segmentos geométricos.
- API GeoJSON por
bboxe dashboard de corredor somente leitura.
O eixo candidato é apenas para desenvolvimento. Como não foi fornecido um eixo
rodoviário oficial e os marcos contêm inversões e lacunas conhecidas, ele é
marcado como estimated, needs_validation e
eligible_for_operations=false.
- Catálogo de cenas e ativos com checksum, execuções versionadas, zonas, métricas de qualidade e recomendações explicáveis.
- Descoberta normalizada de Sentinel Hub Catalog e INPE BDC STAC.
- Cinco aquisições Sentinel persistidas somente como metadados
discovered. - Validação estatística de uma AOI preparada de 100 m, mantida como inconclusiva/inspeção porque o eixo e o buffer não são oficiais e NDVI não é altura.
- Recorte NDVI de 5 × 11 pixels, com checksum e linhagem, disponível apenas
como camada preparada e
partially_cachedno dashboard. - Baseline de regras com qualidade, explicação, confiança e revisão humana.
Nenhuma cena-fonte completa foi baixada ou aprovada para uso operacional. O recorte NDVI não representa altura, condição atual ou autorização de roçada.
- Identidade local de MVP e RBAC de gestor/supervisor por rodovia.
- Fila de recomendações e decisões imutáveis de aceitar, rejeitar ou ajustar.
- Ordem de inspeção preparada com três pontos estimados na linha central.
- Aplicativo Android offline-first com login inicial online, vault AES-256, ciclo demonstrativo, três medições, fotos e sincronização idempotente.
- Upload AES-256-GCM, recuperação autorizada e revisão humana de fotos.
- Resumo preparado com mínimo, média, máximo e contagens N1/N2/N3.
- Exportação CSV determinística e auditada.
Todo esse fluxo permanece preparado, com localização simulada, sem execução de campo e inelegível para relatório oficial.
- Proposta pós-inspeção e revisão humana separada.
- Ordem de roçada não executável, recursos candidatos, avaliação manual de prontidão e decisão exclusiva de planejamento.
- Ensaio móvel simulado com confirmação, início em ponto estimado, pausa/retomada equilibradas e finalização.
- Três alturas pós-serviço simuladas e não verificadas, separadas das medições de inspeção.
- Uma foto pós-serviço por ponto, guardada no vault criptografado.
- Manifestos sincronizados antes dos bytes; upload explícito e retomável após aceitação dos três manifestos.
- Recibo imutável do conteúdo criptografado, ainda marcado como simulado, não localizado, não validado e não operacional.
- Recuperação autorizada da versão exata, com descriptografia, verificação de integridade e evento de acesso imutável.
- Fila autenticada e revisão humana append-only de qualidade e visibilidade da régua, sob política própria e ainda simulada.
- Resumo pós-serviço simulado, gerado somente com três medições digitadas e três revisões visuais aceitas, sem transformar foto em altura ou conclusão.
- Histórico gerencial somente leitura do ensaio e das alturas brutas.
Ainda não existem conclusão de roçada validada nem atualização operacional do mapa/histórico. Os resumos pós-serviço atuais são exclusivamente simulados e não comprovam execução ou eficácia.
| Caminho | Responsabilidade |
|---|---|
apps/dashboard |
Dashboard de gestão em Next.js |
apps/mobile |
Aplicativo Android offline-first em Flutter |
services/api |
API FastAPI e casos de uso de domínio |
services/geospatial-worker |
Processamento geoespacial e de satélite |
services/ai-worker |
Regras explicáveis e futuros modelos candidatos |
packages/contracts |
Contratos compartilhados de API e eventos |
infra |
Compose, infraestrutura e migrações SQL |
data |
Entradas locais, manifestos e produtos derivados |
docs |
Arquitetura, decisões e relatórios de qualidade |
O dashboard mantém a fila de fotos de inspeção em /photo-reviews e a fila
separada de fotos pós-serviço simuladas em /mowing-photo-reviews.
- Python 3.12 a 3.14;
- Node.js 22 ou superior;
- Docker Engine com Docker Compose;
- Flutter apenas para desenvolvimento do aplicativo móvel.
Copie .env.example para .env antes de personalizar o ambiente. As senhas de
exemplo são apenas padrões de desenvolvimento e nunca devem ser usadas em
produção.
cp -n .env.example .env
python -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
npm installdocker compose up --buildServiços locais:
| Serviço | Endereço |
|---|---|
| Dashboard | http://localhost:3000 |
| API | http://localhost:8000 |
| Healthcheck | http://localhost:8000/health |
| PostgreSQL/PostGIS | localhost:5432 |
| MinIO Console | http://localhost:9001 |
O healthcheck retorna sucesso somente quando PostgreSQL e MinIO respondem. A
fila é declarada como not_configured porque não há broker no MVP. O timeout de
cada probe é configurado por HEALTH_PROBE_TIMEOUT_SECONDS, com padrão local de
um segundo. O dashboard expõe http://localhost:3000/api/health e só fica
saudável no Compose quando consegue validar esse contrato pela rede interna.
Nesta estação, o Docker roda em modo rootless. Em um novo shell, os binários locais podem ser selecionados assim:
export PATH="$PWD/.tools/docker/bin:$PATH"
export DOCKER_HOST="unix:///run/user/$(id -u)/docker.sock"Esta seção explica detalhadamente como executar cada componente do sistema, seja de forma orquestrada (tudo junto via Docker) ou individualmente para desenvolvimento e depuração local.
Suba a pilha inteira (PostgreSQL/PostGIS, MinIO, API FastAPI e Dashboard Next.js):
docker compose up --buildServiços disponibilizados:
- Dashboard Next.js:
http://localhost:3000 - API FastAPI:
http://localhost:8000(Healthcheck:http://localhost:8000/health) - MinIO Console:
http://localhost:9001(Usuário:zenit, Senha:change_me) - PostgreSQL / PostGIS:
localhost:5432(Usuário:zenit, Banco:zenit)
Se for desenvolver serviços locais fora do Docker, suba apenas a infraestrutura básica:
docker compose up postgres minio -dA API (services/api) gerencia endpoints REST/GeoJSON, autenticação, política de revisão e persistência.
# 1. Ativar o ambiente virtual e instalar dependências em modo editável
source .venv/bin/activate
python -m pip install -e '.[dev]'
# 2. Iniciar a API em modo de desenvolvimento (com reload automático)
uvicorn zenit_api.main:app --app-dir services/api/src --reload- API Base:
http://localhost:8000 - Documentação interativa Swagger:
http://localhost:8000/docs - Healthcheck:
http://localhost:8000/health
Testes e verificações:
ruff check . # Verificação de linting
pytest # Testes unitários e de integração
python scripts/export_openapi.py --check # Validação do contrato OpenAPIO Dashboard (apps/dashboard) oferece a interface de gestão de corredor, filas de inspeção e aprovação.
# 1. Instalar dependências (executado na raiz do repositório)
npm install
# 2. Executar em modo de desenvolvimento
npm run dev --workspace @zenit/dashboard- Acesso local:
http://localhost:3000
Testes e verificações:
npm run dashboard:lint # Lint e regras de acessibilidade JSX
npm run dashboard:typecheck # Validação de tipos TypeScript
npm run dashboard:test # Suíte de testes do Dashboard
npm run dashboard:build # Build para produçãoO app móvel (apps/mobile) é uma aplicação Android offline-first para o trabalho de campo.
cd apps/mobile
# 1. Obter dependências do Flutter
../../.tools/flutter/bin/flutter --no-version-check --suppress-analytics pub get --enforce-lockfile
# 2. Executar no emulador Android ou dispositivo conectado
../../.tools/flutter/bin/flutter runPara conectar em um servidor API específico (o padrão no emulador é http://10.0.2.2:8000):
../../.tools/flutter/bin/flutter run \
--dart-define=ZENIT_API_BASE_URL=http://10.0.2.2:8000 \
--dart-define=ZENIT_APP_VERSION=1.0.0+1Testes, análise e build do APK:
cd apps/mobile
../../.tools/flutter/bin/flutter analyze # Análise estática do código
../../.tools/flutter/bin/flutter test # Testes do app Flutter
../../.tools/flutter/bin/dart format --output=none --set-exit-if-changed lib test # Checar formatação
../../.tools/flutter/bin/flutter build apk --debug # Gerar APK debug demonstrativo-
Criar usuário gestor local (
zenit-user):source .venv/bin/activate zenit-user \ --email manager@example.test \ --display-name "Gestor local do MVP" \ --road-code SP021 \ --role manager
-
Importador de dados brutos (
zenit-import):source .venv/bin/activate zenit-import --help -
Descoberta de imagens de satélite (
zenit-satellite):source .venv/bin/activate zenit-satellite --segment-index 195 --zone left --from-date 2026-07-01 --to-date 2026-08-07 -
Renderizar prévia NDVI estática:
python scripts/render_cached_ndvi_preview.py
-
Validação de smoke test da stack ativa:
python scripts/verify_mvp_stack.py
-
Validação do manifesto do APK:
python scripts/verify_release_evidence.py docs/release-evidence/android-mvp-debug-apk-2026-08-14.json
Coloque os arquivos fornecidos em data/raw/. Esse diretório contém evidências
locais imutáveis: não altere os originais e não os adicione ao Git. Consulte
data/README.md para nomes esperados e regras de manuseio.
Cada importação ou produto derivado deve registrar checksum e linhagem. O
arquivo classificacao_rocada.kmz deve ser normalizado sem modificar o original;
mapeamentos de atributos inferidos permanecem pendentes de validação.
Use zenit-import para importar uma fonte imutável por vez. Exemplos completos
estão em
docs/architecture/source-ingestion.md.
O fluxo Sentinel preparado e idempotente para a AOI de validação é:
zenit-satellite \
--segment-index 195 \
--zone left \
--from-date 2026-07-01 \
--to-date 2026-08-07Ele é restrito à geometria preparada e não operacional. Leia
docs/architecture/satellite-discovery.md
antes de alterar AOI ou período.
O banco atual exige as migrações 0001 a 0038, sempre em ordem numérica. Um
volume novo do Compose executa todas automaticamente por
/docker-entrypoint-initdb.d. Volumes existentes não são atualizados por esse
mecanismo.
Para uma atualização controlada, aplique somente as migrações ainda ausentes. Para um banco vazio fora da inicialização automática, execute:
for migration in infra/migrations/*.sql; do
docker compose exec -T postgres \
psql -v ON_ERROR_STOP=1 -U zenit -d zenit < "$migration"
doneAs migrações preservam uma evolução append-only:
0001–0007: catálogo de fontes, staging, eixo/segmentos e fundação satelital;0008–0010: revisão de recomendações, identidade/RBAC e ordens de inspeção;0011–0014: sincronização móvel, ciclo demonstrativo e manifestos de foto;0015–0021: upload/revisão de mídia, resumo preparado e exportação auditada;0022–0027: proposta pós-inspeção, revisão e planejamento de roçada;0028–0037: ensaio simulado, medições, fotos, acesso, revisão, resumo, exportação, exceção pós-serviço e decisão humana da exceção.0038: limitação persistente e auditada de tentativas de login local.
Decisões detalhadas e invariantes de cada etapa estão em
docs/decisions.
Todas as rotas de escrita autenticadas derivam o ator do token verificado. As
rotas abaixo usam o prefixo versionado /v1.
| Método e rota | Finalidade |
|---|---|
GET /health |
Prontidão da API, PostgreSQL e MinIO; fila explicitamente ausente |
GET /v1/roads/SP021/segments?... |
Segmentos GeoJSON por bbox |
GET /v1/segments/{id}/satellite-observations |
Evidências persistidas do segmento |
POST /v1/analysis/preview |
Prévia não persistente do baseline |
GET /v1/recommendations |
Fila de recomendações |
Exemplo de consulta do eixo estimado:
GET /v1/roads/SP021/segments?min_lon=-46.84&min_lat=-23.64&max_lon=-46.72&max_lat=-23.40
A resposta é GeoJSON EPSG:4326 e mantém os rótulos estimated,
needs_validation e eligible_for_operations=false. Consulte
docs/data-quality/km-axis-quality.md.
No baseline, NDVI sozinho nunca se transforma em estimativa de altura. Dados de
baixa qualidade ou não reais retornam inconclusive e inspect. Altura real
acima do limite aplicável retorna mowing_review, que ainda exige decisão
humana.
Crie um usuário local após a migração 0009; nenhuma credencial padrão é
versionada:
zenit-user \
--email manager@example.test \
--display-name "Gestor local do MVP" \
--road-code SP021 \
--role managerObtenha um token de 30 minutos:
POST /v1/auth/token
Content-Type: application/x-www-form-urlencoded
username=manager%40example.test&password=<senha-local>
Cada token emitido possui uma sessão persistente vinculada ao jti. A API
recusa tokens sem sessão ativa e registra a revogação append-only no logout:
POST /v1/auth/logout
Authorization: Bearer <access-token>
Tokens emitidos antes da migração 0039 exigem novo login. O dashboard confirma
a revogação antes de apagar seus cookies; o aplicativo móvel sempre remove o
acesso local e informa quando estava offline e não pôde confirmar a revogação.
Por padrão, cinco falhas em 15 minutos bloqueiam temporariamente o identificador
por 15 minutos. O banco armazena somente um digest HMAC e eventos append-only;
os limites são configuráveis pelas variáveis AUTH_LOGIN_* documentadas em
docs/security/local-login-throttle.md.
Rotas centrais do fluxo gerencial:
| Método e rota | Finalidade |
|---|---|
GET /v1/auth/me |
Identidade e papéis do usuário |
POST /v1/auth/logout |
Revogar a sessão bearer atual |
POST /v1/recommendations/{id}/decisions |
Aceitar, rejeitar ou ajustar recomendação |
POST /v1/work-orders |
Criar ordem preparada de inspeção |
GET /v1/work-orders |
Listar ordens acessíveis ao ator |
GET /v1/photo-review-queue |
Fila autorizada de revisão de fotos |
Decisões rejeitadas ou ajustadas exigem justificativa. Ajustes também exigem
adjusted_recommendation. Nenhuma resposta autoriza trabalho de campo.
Registre o identificador lógico do aparelho antes da sincronização:
POST /v1/mobile/devices
Authorization: Bearer <access-token>
Content-Type: application/json
{"device_id":"<device-uuid>","platform":"android","app_version":"1.0.0+1"}
POST /v1/sync/batch recebe lotes idempotentes e retorna accepted,
rejected, conflicts e next_sync_cursor. O aplicativo retém eventos locais
até obter resultado persistente. Conflitos preservam as duas versões.
O contrato aceita, em superfícies separadas:
- ciclo preparado de inspeção e três medições;
- manifestos de fotos de inspeção;
- ciclo de ensaio de roçada explicitamente simulado;
- três medições pós-serviço simuladas;
- manifestos separados das fotos pós-serviço.
Metadados de manifesto nunca provam que o servidor recebeu os bytes.
POST /v1/media/{photo_id}
GET /v1/media/{photo_id}
POST /v1/media/{photo_id}/reviews
O upload aceita JPEG/PNG de até 25 MiB, confere assinatura, tamanho, checksum, ator, dispositivo e papel na rodovia. A API criptografa os bytes com AES-256-GCM antes do MinIO privado e versionado. Recuperação e revisão repetem as verificações de acesso e deixam trilha append-only.
Mesmo uma foto aceita permanece preparada e inelegível para operação, treinamento ou relatório oficial.
POST /v1/work-orders/{work_order_id}/prepared-summary
GET /v1/prepared-inspection-summaries
POST /v1/prepared-inspection-summaries/{summary_id}/exports
POST /v1/prepared-inspection-summaries/{summary_id}/post-inspection-proposal
POST /v1/prepared-post-inspection-proposals/{proposal_id}/decisions
O resumo exige ciclo finalizado, três medições e três revisões efetivamente
aceitas. Seus agregados vêm das medições digitadas, não das fotos. Uma violação
do limite produz mowing_review, nunca autorização de roçada.
O histórico de ensaio também informa, por ponto, se a foto pós-serviço simulada aguarda revisão ou possui uma decisão visual registrada. Esse status não altera as medições e não representa conclusão de roçada.
POST /v1/prepared-mowing-orders
GET /v1/prepared-mowing-orders
POST /v1/prepared-mowing-orders/{id}/resource-plans
POST /v1/prepared-mowing-orders/{id}/readiness-assessments
POST /v1/prepared-mowing-orders/{id}/planning-approvals
GET /v1/prepared-mowing-rehearsals
POST /v1/mowing-media/{photo_id}
GET /v1/mowing-media/{photo_id}
POST /v1/mowing-media/{photo_id}/reviews
GET /v1/mowing-photo-review-queue
POST /v1/prepared-mowing-orders/{mowing_order_id}/post-service-summary
GET /v1/prepared-mowing-post-service-summaries
POST /v1/prepared-mowing-post-service-summaries/{summary_id}/exports
POST /v1/prepared-mowing-post-service-summaries/{summary_id}/exceptions
GET /v1/prepared-mowing-post-service-exceptions
POST /v1/prepared-mowing-post-service-exceptions/{exception_id}/decisions
Recursos são referências candidatas; clima e segurança são declarações manuais
preparadas; approved_for_planning não é aprovação operacional. O ensaio não
usa GPS real, não despacha equipe e não declara serviço concluído.
O upload pós-serviço só ocorre após aceitação dos três manifestos. O aplicativo
persiste cada recibo antes de avançar e retoma apenas fotos não confirmadas. A
resposta permanece simulated, uploaded_unverified, not_validated,
not_collected e inelegível para execução, treinamento e relatório oficial.
Na recuperação, a API revalida o papel atual na rodovia, descriptografa a
versão exata, confere tamanho/SHA-256 e registra o acesso antes da entrega.
A fila e as decisões humanas permanecem separadas da inspeção; uma aceitação
confirma apenas qualidade visual e régua visível, sem validar altura ou roçada.
O dashboard permite solicitar, consultar, revisar exceções humanas e exportar
CSV dos resumos pós-serviço simulados tanto em /mowing-post-service-summaries
quanto no contexto de /photo-reviews; essa agregação permanece simulada,
idempotente, auditada e não atualiza mapa, histórico operacional nem relatório
oficial.
Uma exceção pós-serviço simulada pode apontar necessidade de inspeção de
seguimento quando a máxima digitada ainda excede 10 cm em área especial ou
30 cm nas demais zonas; ela exige revisão humana e não autoriza campo. A decisão
humana da exceção é append-only, pode aceitar, rejeitar ou ajustar apenas para
monitor/inspect_follow_up, e continua inelegível para mapa, histórico
operacional, relatório oficial e treinamento de modelo.
O recorte Sentinel-2 de 5 × 11 pixels pode ser consultado na prévia NDVI em cache. Quando o cache ignorado estiver disponível, regenere a página sem rede ou pacotes externos:
python scripts/render_cached_ndvi_preview.pyO renderizador verifica os checksums do GeoTIFF e dos metadados antes de gravar a prévia e o manifesto de linhagem. Não há raster RGB de cor verdadeira em cache.
source .venv/bin/activate
ruff check .
pytest
python scripts/export_openapi.py --check
uvicorn zenit_api.main:app --app-dir services/api/src --reloadO contrato OpenAPI versionado é gerado diretamente
pela aplicação FastAPI. Após uma alteração intencional de endpoint ou modelo,
execute python scripts/export_openapi.py, revise o diff e mantenha o gate
--check aprovado. O exportador recusa rotas de aplicação fora de /v1,
identificadores de operação duplicados e valores sensíveis conhecidos.
Todas as respostas da API incluem X-Correlation-ID. Erros HTTP, de validação
e internos seguem o envelope estável code, message, details e
correlation_id; falhas inesperadas não retornam detalhes internos. O contrato
e seus limites estão em
API error and correlation contract.
Inicie a API e execute:
npm run dev --workspace @zenit/dashboardValidação completa do dashboard:
npm run dashboard:lint
npm run dashboard:typecheck
npm run dashboard:test
npm run dashboard:buildO lint inclui as regras de acessibilidade JSX do Next.js. A suíte também mantém um baseline de acessibilidade para skip link, alvo principal único, foco de teclado, movimento reduzido e contraste do texto secundário nas superfícies principais.
O servidor do dashboard usa INTERNAL_API_URL, cujo padrão é
http://localhost:8000. O token bearer fica em cookie HttpOnly no servidor;
mutações exigem token CSRF, Origin exata e cookie SameSite=Strict.
Todas as rotas recebem o
baseline de headers HTTP, incluindo
anti-clickjacking, nosniff, referrer restrito, isolamento de opener e bloqueio
de câmera, geolocalização e microfone.
No diretório apps/mobile:
../../.tools/flutter/bin/flutter --no-version-check --suppress-analytics pub get --enforce-lockfile
../../.tools/flutter/bin/dart format --output=none --set-exit-if-changed lib test
../../.tools/flutter/bin/flutter --no-version-check --suppress-analytics analyze
../../.tools/flutter/bin/flutter --no-version-check --suppress-analytics testO emulador usa http://10.0.2.2:8000 por padrão. Builds de produção devem
fornecer uma URL HTTPS:
../../.tools/flutter/bin/flutter run \
--dart-define=ZENIT_API_BASE_URL=https://api.example.test \
--dart-define=ZENIT_APP_VERSION=1.0.0+1Tráfego HTTP sem TLS só é permitido pelo manifesto Android de depuração.
A CI valida Python, dashboard, Flutter, o APK demonstrativo e um ambiente Compose novo. O APK deve conter a URL reservada, package/version e SDKs esperados, três ABIs Flutter e uma assinatura debug v2 válida. O smoke test confere schema PostGIS, healthcheck, resposta satelital vazia com proveniência, proteção das rotas de escrita e a renderização identificável do dashboard/login sem exigir arquivos brutos ou credenciais de provedores.
O manifesto versionado do APK também possui um gate independente para schema, proveniência, hashes e bloqueios de uso operacional:
python scripts/verify_release_evidence.py \
docs/release-evidence/android-mvp-debug-apk-2026-08-14.jsonQuando o APK ignorado estiver disponível, acrescente
--artifact apps/mobile/build/app/outputs/flutter-apk/app-debug.apk para
conferir o tamanho e o SHA-256 do binário contra o manifesto.
Com o stack ativo, os mesmos contratos HTTP da CI podem ser verificados localmente sem credenciais:
python scripts/verify_mvp_stack.pyUse --expect-empty apenas em um banco recém-inicializado, como o da CI.
- A autenticação local do MVP possui limitação persistente de tentativas e revogação individual de sessão, mas ainda não oferece identidade corporativa, refresh token, recuperação de senha, MFA, encerramento administrativo global ou controles adaptativos. Não deve ser exposta diretamente à internet.
- Staging e produção devem usar HTTPS,
DASHBOARD_COOKIE_SECURE=trueeDASHBOARD_PUBLIC_ORIGINcom a origem pública exata. - A chave AES-256-GCM fica fora do object storage. Perder essa chave torna as mídias irrecuperáveis; custódia, rotação, backup e recuperação precisam ser definidos antes de um piloto.
- Ainda faltam política de retenção/legal hold, tratamento de EXIF, verificação por decoder/malware e controles completos de privacidade.
- A CSP atual protege
base-uri,form-actioneframe-ancestors, mas ainda não definescript-srccom nonce. HSTS depende do proxy TLS de produção. - Não há GPS real, despacho, rastreamento, execução de roçada ou aprovação operacional.
- O mapa e o histórico ainda não são atualizados com um resultado pós-roçada.
- Não existe relatório operacional oficial; os resumos atuais são preparados e simulados.
- A variante Android
releasenão possui assinatura configurada; somente o APK debug demonstrativo passa pelo gate atual de entrega. - A cena satelital completa e o eixo rodoviário oficial continuam pendentes.
- Manual mestre do projeto
- Prontidão do MVP demonstrativo
- Contrato OpenAPI
- Baseline de acessibilidade
- Baseline de headers HTTP
- Baseline de limitação do login local
- Decisões arquiteturais
- Relatórios de qualidade dos dados
- Arquitetura
- Aplicativo móvel
- Regras para agentes de desenvolvimento
O histórico detalhado de cada incremento deve permanecer nos ADRs. Este README é a referência de entrada para executar o projeto, entender seus limites e localizar os contratos atuais.