Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d88b5a9
docs(spec): corrige afirmações que ainda negavam o backend Serverpod
hbgit Sep 11, 2026
0447345
feat: conecta os apps ao backend real e centraliza a configuração em …
hbgit Sep 11, 2026
0b1f6fe
feat: liga a sincronização de visitas e cifra a fila no aparelho do ACS
hbgit Sep 12, 2026
601d5f4
fix(acs): separa os avisos de infraestrutura e faz o app conectar ao …
hbgit Sep 12, 2026
42e904b
fix(acs): retenta a primeira conexão ao broker em vez de desistir
hbgit Sep 12, 2026
da74d84
fix(acs): flutter build apk falha sem a senha do broker, em vez de co…
hbgit Sep 12, 2026
463fbb1
doc: update AGENTS.md
hbgit Sep 12, 2026
7db32c5
fix(acs): preserve visit notes through offline queue and sync
hbgit Sep 12, 2026
29b3e0a
feat(acs): torna o mapa operacional e preserva notas no fluxo offline
hbgit Sep 12, 2026
d366b8b
feat(acs): tornar rota e geofencing funcionais no fluxo de visitas
hbgit Sep 12, 2026
b6067a3
test(acs): adicionar testes de mapa e geofencing no emulator
hbgit Sep 13, 2026
edb8bab
feat(acs): permitir visita após escalonamento de alerta vermelho
hbgit Sep 13, 2026
b856585
build(acs): configurar injeção segura da chave do Google Maps
hbgit Sep 13, 2026
033b06a
refactor(acs): renomear package Android para br.com.prismrr.sinalacs.acs
hbgit Sep 13, 2026
891eac4
test(acs): validar Google Maps com chave de compilação no emulator
hbgit Sep 13, 2026
82bc5fa
feat: abre o caminho de rotina para registrar visitas e fecha territó…
hbgit Sep 13, 2026
b35c618
chore(admin): adicionar tema e tokens visuais do backoffice
vinimartinsufrr Sep 11, 2026
752ceeb
feat(admin): adicionar camada de dados isolada (AdminDataSource + mock)
vinimartinsufrr Sep 11, 2026
a2b349e
feat(admin): implementar app navegável (login, indicadores, microárea…
vinimartinsufrr Sep 11, 2026
09f0b51
test(admin): adicionar testes de widget por tela e do data source mock
vinimartinsufrr Sep 11, 2026
c38cdb3
ci(admin): adicionar job admin-app ao workflow, espelhando acs-app/pa…
vinimartinsufrr Sep 11, 2026
c96918f
docs(admin): documentar telas do backoffice, no formato de telas-acs.md
vinimartinsufrr Sep 11, 2026
09f035f
fix(admin): corrigir overflow em telas estreitas e import faltante no…
vinimartinsufrr Sep 11, 2026
043b992
chore(admin): versionar pubspec.lock, seguindo a convenção dos outros…
vinimartinsufrr Sep 11, 2026
fa51900
chore(admin): adicionar suporte a Flutter Web (flutter create --platf…
vinimartinsufrr Sep 11, 2026
244099a
fix(admin): remover uso decorativo de amarelo/verde (releitura da issue)
vinimartinsufrr Sep 11, 2026
0dc1651
docs(admin): documentar por que o login não chama auth.developmentLogin
vinimartinsufrr Sep 13, 2026
457b192
docs(admin): atualizar telas-admin.md sobre login (não valida campos)
vinimartinsufrr Sep 13, 2026
42b6377
docs(admin): adicionar screenshots reais das 5 telas
vinimartinsufrr Sep 13, 2026
40fbe27
docs: add UX and accessibility assessment report and evidence assets
sarahw3b Sep 14, 2026
8c5215a
feat: cadeia de hash em audit_logs e estado terminal para visita recu…
hbgit Sep 14, 2026
a7c5675
docs: add lgpd_data_audit.md
GuilhermeAlmeidadaLuz Sep 14, 2026
d9293ab
fix(admin): responder aos achados da revisão automática do PR (Copilot)
vinimartinsufrr Sep 15, 2026
5c00d77
test(admin): adicionar testes de erro/retry e regressão dos filtros
vinimartinsufrr Sep 15, 2026
cecb9cc
fix(admin): tratar os 2 comentários inline restantes da revisão do PR
vinimartinsufrr Sep 15, 2026
549cb21
test(admin): regressão dos 2 achados finais (gate de login, filtro di…
vinimartinsufrr Sep 15, 2026
1a5f0f5
Merge pull request #6 from hbgit/docs/ux-accessibility-assessment
hbgit Sep 15, 2026
ee03398
Merge branch 'feat/serverpod' into develop
hbgit Sep 15, 2026
64e5543
fix(a11y): reauditar e corrigir contraste, alvo de toque e status WCA…
hbgit Sep 15, 2026
73447d6
docs(ux): adicionar plano de testes de UX/UI baseado em spec/ui_desig…
hbgit Sep 15, 2026
17dc567
Merge pull request #5 from hbgit/feat/admin-backoffice
hbgit Sep 15, 2026
2270907
docs: atualizar CLAUDE.md e AGENTS.md com o estado real do projeto
hbgit Sep 15, 2026
c0ee03d
create and documentation of security assessment
Rosialdo Sep 15, 2026
cb9d5bf
Update assessment
Rosialdo Sep 15, 2026
7d27c08
Merge pull request #10 from hbgit/security/cibersec-analysis
hbgit Sep 16, 2026
3515426
feat(admin): adicionar suporte Android e layout compacto ao backoffice
hbgit Sep 16, 2026
a9dcbc5
fix(admin): corrigir contraste WCAG 1.4.3 de red/accent como texto
hbgit Sep 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Configuração do SinalACS — modelo.
#
# NÃO edite este arquivo com valores reais: ele é versionado. Gere o seu `.env`
# com segredos aleatórios próprios da sua máquina:
#
# ./scripts/dev/bootstrap_env.sh
#
# O `.env` é lido automaticamente pelo `docker compose` para substituir as
# `${VARIÁVEIS}` do docker-compose.yml, e é ignorado pelo git (.gitignore).
#
# Todo segredo abaixo é declarado no compose como `${VAR:?...}`: se faltar, o
# `docker compose` falha dizendo qual variável está ausente, em vez de subir a
# stack com uma senha embutida. Era exatamente esse o problema anterior.
#
# ATENÇÃO ao trocar senhas de uma stack que já rodou:
# · POSTGRES_PASSWORD só vale na PRIMEIRA inicialização do volume. Para
# trocar, apague ./pg_data/ antes de subir.
# · As senhas MQTT são regravadas a cada boot pelo mosquitto-init, então
# trocá-las aqui basta.

# ---------------------------------------------------------------------------
# Google Maps Android SDK · consumido por: apps/acs
#
# Crie uma chave restrita no Google Cloud Console, habilite Maps SDK for
# Android, restrinja por package name/SHA-1 e mantenha o valor apenas no `.env`.
# O script de execução injeta a chave por dart-define e no manifest Android.
# Nunca versione uma chave real neste arquivo.
# ---------------------------------------------------------------------------
GOOGLE_MAPS_API_KEY=

# ---------------------------------------------------------------------------
# Postgres da stack local · consumido por: postgres, serverpod, database-seed
# ---------------------------------------------------------------------------
POSTGRES_USER=sinalacs_user
POSTGRES_DB=sinalacs_db
# openssl rand -hex 32
POSTGRES_PASSWORD=

# ---------------------------------------------------------------------------
# Postgres do harness de teste do Serverpod
#
# Sobe com `docker compose --profile test up -d postgres-test`, na porta 9090,
# como backend/sinalacs_server/config/test.yaml espera. O bootstrap grava este
# mesmo valor em backend/sinalacs_server/config/passwords.yaml — os dois PRECISAM
# coincidir: se divergirem, o Serverpod falha ao carregar a config e chama
# exit(1), que não dá flush no stdout, e a suíte inteira morre sem uma linha de
# log sequer.
# ---------------------------------------------------------------------------
# openssl rand -hex 32
TEST_DATABASE_PASSWORD=

# ---------------------------------------------------------------------------
# Broker MQTT · consumido por: mosquitto-init (cria os usuários), serverpod
#
# Dois usuários, com ACLs distintas em infra/docker/mosquitto/aclfile:
# backend → readwrite em sinalacs/v1/#
# acs-area-12 → read no tópico da microárea, write nos ACKs
# ---------------------------------------------------------------------------
# openssl rand -hex 32
MQTT_BACKEND_PASSWORD=
# openssl rand -hex 32
MQTT_ACS_PASSWORD=

# SANs adicionais no certificado do broker. Necessário para validar em aparelho
# físico na LAN, já que o certificado padrão só cobre mosquitto, localhost,
# 127.0.0.1 e 10.0.2.2 (o host visto do emulador Android).
# MQTT_CERT_SAN_EXTRA=IP:192.168.0.10
MQTT_CERT_SAN_EXTRA=

# ---------------------------------------------------------------------------
# Segredos da aplicação · consumido por: serverpod
# ---------------------------------------------------------------------------
# Chave HMAC que assina os tokens de auth.developmentLogin. O token carrega o
# papel e a microárea, então quem conhece este valor pode forjar um acesso de
# ACS para qualquer território. Nunca reaproveite entre ambientes.
# openssl rand -hex 32
JWT_SECRET=

# ---------------------------------------------------------------------------
# Cadeia de hash de audit_logs · consumido por: serverpod
#
# Chave HMAC que encadeia cada linha de audit_logs à anterior (ver
# backend/sinalacs_server/lib/src/application/audit/). Detecta edição, remoção
# ou reordenação de linhas — inclusive por quem tem acesso de escrita direto ao
# Postgres, que é por isso que este segredo NÃO pode ser derivado do
# JWT_SECRET nem reaproveitado dele.
#
# ATENÇÃO: rotacionar este valor invalida a verificação de TUDO que já foi
# gravado na trilha até aqui — ao contrário do JWT_SECRET, que pode ser trocado
# livremente. Trocar exige aceitar que a cadeia anterior à troca não verifica
# mais contra o segredo novo.
# openssl rand -hex 32
AUDIT_CHAIN_SECRET=

# ---------------------------------------------------------------------------
# Comportamento · consumido por: serverpod
# ---------------------------------------------------------------------------
# development | staging | production. Fora de development, o servidor recusa
# subir com JWT_SECRET ausente, vazio ou igual ao fallback de desenvolvimento.
APP_ENV=development

# Gate de auth.developmentLogin. Com false, a chamada falha como se a rota não
# existisse. É o único mecanismo de autenticação do protótipo — não é
# autenticação institucional.
ENABLE_DEV_LOGIN=true

# ---------------------------------------------------------------------------
# Apps Flutter · NÃO são lidos do .env
#
# Os apps resolvem estes valores em tempo de COMPILAÇÃO, via --dart-define, com
# defaults em apps/*/lib/core/network/backend_config.dart.
#
# Para o ACS, use o script — ele lê MQTT_ACS_PASSWORD daqui, copia a CA do
# broker para os assets e preenche tudo:
#
# ./scripts/dev/run_acs.sh
# ./scripts/dev/run_acs.sh --build
#
# O que ele passa:
#
# --dart-define=SINALACS_HOST=http://10.0.2.2:8080/
# --dart-define=SINALACS_MQTT_HOST=10.0.2.2
# --dart-define=SINALACS_MQTT_USER=acs-area-12
# --dart-define=SINALACS_MQTT_PASSWORD=<MQTT_ACS_PASSWORD>
#
# O default de 10.0.2.2 é o host da máquina visto de dentro do emulador Android.
#
# SINALACS_MQTT_PASSWORD **não tem default**: o broker usa um segredo por
# máquina, então nenhum valor embutido acertaria — o app compilado sem ele
# avisa que falta a senha, em vez de dizer "sem conexão com a central".
#
# AVISO: SINALACS_MQTT_PASSWORD vira uma CONSTANTE NO BINÁRIO — String.fromEnvironment
# é resolvido na compilação, e o valor é extraível de qualquer APK. Em produção a
# credencial do broker não pode viajar no app. A correção é credencial por
# dispositivo / mTLS, registrada como lacuna conhecida.
# ---------------------------------------------------------------------------
71 changes: 67 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ jobs:
defaults:
run:
working-directory: backend
env:
# Senha do Postgres efêmero deste job. NÃO é um segredo: o banco existe só
# dentro do runner, some ao fim do job e nunca é alcançável de fora.
#
# O que importa é que este valor não seja compartilhado com mais nada.
# Antes era a MESMA senha do config/passwords.yaml local — que o
# .gitignore protege e que é idêntica nos blocos development, test,
# staging e production. O segredo protegido pelo .gitignore estava, na
# prática, publicado aqui.
#
# Declarado uma vez e referenciado nos dois lugares: o serviço abaixo e a
# geração do passwords.yaml. Eram dois literais mantidos iguais à mão, e
# divergir fazia a suíte morrer sem log nenhum.
CI_POSTGRES_PASSWORD: ci-ephemeral-not-a-secret

services:
# Banco que o harness de teste do Serverpod espera, conforme
# sinalacs_server/config/test.yaml. O harness aplica as migrações sozinho
Expand All @@ -20,7 +35,7 @@ jobs:
image: postgres:15-alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ZGib82sxRnAaTto3iglbPkARA1qZUv0W
POSTGRES_PASSWORD: ${{ env.CI_POSTGRES_PASSWORD }}
POSTGRES_DB: sinalacs_test
ports:
- 9090:5432
Expand All @@ -41,11 +56,12 @@ jobs:
# Serverpod não carrega a senha do banco, falha ainda no carregamento de
# config e chama exit(1); como o exit() do Dart não dá flush no stdout, a
# mensagem de erro se perde e a falha fica totalmente silenciosa (exit 1,
# zero linhas de log). A senha tem que ser a mesma do serviço postgres
# acima: se as duas divergirem, o harness volta a falhar sem log nenhum.
# zero linhas de log).
#
# Localmente, quem gera este arquivo é scripts/dev/bootstrap_env.sh.
- name: Cria config/passwords.yaml para o harness de teste
run: |
printf "test:\n database: '%s'\n" 'ZGib82sxRnAaTto3iglbPkARA1qZUv0W' \
printf "test:\n database: '%s'\n" "$CI_POSTGRES_PASSWORD" \
> sinalacs_server/config/passwords.yaml
# Suíte completa: 16 testes herméticos em test/unit, que usam fakes das
# interfaces AlertPublisher e AlertStore, mais 9 de integração que sobem o
Expand Down Expand Up @@ -90,3 +106,50 @@ jobs:
- run: flutter pub get
- run: flutter analyze
- run: flutter test

admin-app:
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/admin
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.44.8'
- run: flutter pub get
- run: flutter analyze
- run: flutter test

# Único job do repositório que executa o Gradle. `flutter analyze` e
# `flutter test` não enxergam namespace inconsistente, AGP/Kotlin
# incompatíveis, MainActivity em pacote errado nem merge de manifest
# quebrado — erros que só apareceriam quando alguém tentasse compilar.
#
# É o app admin e não o ACS porque `apps/acs/android/app/build.gradle.kts`
# tem a guarda que faz o build falhar sem SINALACS_MQTT_PASSWORD: cobri-lo
# aqui exigiria compilar um APK que a própria guarda declara inútil.
admin-android-build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/admin
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.44.8'
# Sem cache, cada execução rebaixa ~200MB de Gradle e AGP.
- uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-admin-${{ hashFiles('apps/admin/android/**/*.gradle.kts', 'apps/admin/android/gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: gradle-admin-
- run: flutter pub get
- run: flutter build apk --debug
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,17 @@ coverage/
# Environment
.env
.env.*
# ...menos o modelo, que é documentação e precisa ser versionado. Sem esta
# exceção o padrão .env.* acima o engoliria.
!.env.example

# Docker / local runtime
pg_data/
infra/docker/mosquitto/runtime/

# Grafo de conhecimento (saída regenerável do graphify)
graphify-out/

# Asset de desenvolvimento: CA do broker MQTT, copiada por
# scripts/dev/sync_dev_ca.sh a partir do runtime regerável do Mosquitto.
apps/acs/assets/certs/
Loading
Loading