Skip to content

Repository files navigation

ZENIT

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, estimated ou simulated não representam operação real, não autorizam roçada e não podem alimentar treinamento de modelos nem relatórios oficiais.

Sumário

Objetivo e regras essenciais

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.

Estado atual

Fundação, dados e mapa

  • 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 bbox e 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.

Satélite e recomendação

  • 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_cached no 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.

Inspeção preparada

  • 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.

Planejamento e ensaio de roçada

  • 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.

Arquitetura do repositório

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.

Início rápido

Pré-requisitos

  • Python 3.12 a 3.14;
  • Node.js 22 ou superior;
  • Docker Engine com Docker Compose;
  • Flutter apenas para desenvolvimento do aplicativo móvel.

Configuração local

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 install

Subir a plataforma

docker compose up --build

Serviç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"

Como rodar cada parte do projeto

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.

1. Plataforma Completa (Docker Compose)

Suba a pilha inteira (PostgreSQL/PostGIS, MinIO, API FastAPI e Dashboard Next.js):

docker compose up --build

Serviç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)

2. Banco de Dados e Armazenamento (PostgreSQL + MinIO)

Se for desenvolver serviços locais fora do Docker, suba apenas a infraestrutura básica:

docker compose up postgres minio -d

3. Backend - API (FastAPI / Python)

A 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 OpenAPI

4. Frontend - Dashboard (Next.js / TypeScript)

O 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ção

5. Aplicativo Móvel (Flutter / Android)

O 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 run

Para 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+1

Testes, 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

6. CLIs e Scripts Utilitários

  • 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

Dados, proveniência e importação

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-07

Ele é restrito à geometria preparada e não operacional. Leia docs/architecture/satellite-discovery.md antes de alterar AOI ou período.

Banco de dados e migrações

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"
done

As migrações preservam uma evolução append-only:

  • 00010007: catálogo de fontes, staging, eixo/segmentos e fundação satelital;
  • 00080010: revisão de recomendações, identidade/RBAC e ordens de inspeção;
  • 00110014: sincronização móvel, ciclo demonstrativo e manifestos de foto;
  • 00150021: upload/revisão de mídia, resumo preparado e exportação auditada;
  • 00220027: proposta pós-inspeção, revisão e planejamento de roçada;
  • 00280037: 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.

Fluxos e APIs principais

Todas as rotas de escrita autenticadas derivam o ator do token verificado. As rotas abaixo usam o prefixo versionado /v1.

Consulta e análise

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.

Autenticação e 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 manager

Obtenha 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.

Aplicativo móvel e sincronização

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.

Mídia de inspeção preparada

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.

Resumo e proposta pós-inspeção

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.

Planejamento e ensaio 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.

Prévia NDVI local

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.py

O 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.

Desenvolvimento e validação

API Python

source .venv/bin/activate
ruff check .
pytest
python scripts/export_openapi.py --check
uvicorn zenit_api.main:app --app-dir services/api/src --reload

O 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.

Dashboard Next.js

Inicie a API e execute:

npm run dev --workspace @zenit/dashboard

Validação completa do dashboard:

npm run dashboard:lint
npm run dashboard:typecheck
npm run dashboard:test
npm run dashboard:build

O 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.

Aplicativo Flutter

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 test

O 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+1

Tráfego HTTP sem TLS só é permitido pelo manifesto Android de depuração.

Integração contínua

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.json

Quando 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.py

Use --expect-empty apenas em um banco recém-inicializado, como o da CI.

Segurança e limitações conhecidas

  • 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=true e DASHBOARD_PUBLIC_ORIGIN com 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-action e frame-ancestors, mas ainda não define script-src com 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 release nã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.

Documentação

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.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages