docs: add UX and accessibility assessment report - #6
Conversation
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
There was a problem hiding this comment.
Note
Copilot was unable to run its full agentic suite in this review.
Pull request overview
This PR strengthens local/dev security and reliability by eliminating hardcoded secrets, introducing per-machine environment bootstrapping, and expanding end-to-end validation across backend + apps (including MQTT/TLS and visit sync).
Changes:
- Replace hardcoded dev credentials with
.envgeneration (bootstrap_env.sh) and enforce required secrets indocker-compose.ymland CI. - Improve MQTT/TLS dev ergonomics and correctness (SAN support, CA sync to Flutter assets, ACL fix), plus add e2e scripts/live checks.
- Add visits offline-sync RPC (
visits.sync) with Serverpod models, storage abstraction, and unit/integration tests; update app network facades/tests accordingly.
Reviewed changes
Copilot reviewed 90 out of 101 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| video/rpc_demo/watch_mqtt.sh | Loads MQTT password from .env and removes embedded default to match per-machine secrets. |
| spec/ux_accessibility_assessment.md | Adds UX/accessibility assessment spec and findings. |
| spec/test_plan.md | Updates test-plan narrative about contract guarantees and AsyncAPI scope. |
| spec/lgpd_design.md | Documents key-custody decision and on-device retention behavior for ACS app. |
| spec/PRD_system.md | Clarifies ABAC example is illustrative and links to real inline enforcement. |
| scripts/qa/e2e.sh | New end-to-end script to bring up stack, seed DB, sync CA, and run live checks/integration tests. |
| scripts/dev/sync_dev_ca.sh | New script to copy MQTT dev CA into ACS app assets with expiry checks. |
| scripts/dev/run_acs.sh | New wrapper to run/build ACS with secure dart-defines-from-file and CA sync. |
| scripts/dev/bootstrap_env.sh | New bootstrapper generating per-machine .env and Serverpod passwords.yaml for tests. |
| infra/docker/mosquitto/init.sh | Regenerates TLS certs with SAN support; rewrites passwordfile on every boot. |
| infra/docker/mosquitto/aclfile | Fixes ACS topic read ACL to match seeded microArea UUID topic. |
| docs/telas-acs.md | Documents UI conventions for severity coloring vs infrastructure warnings. |
| docker-compose.yml | Enforces required secrets from .env, adds postgres-test profile, and injects JWT secret. |
| backend/sinalacs_server/test/unit/visit_sync_service_test.dart | Adds unit tests for visit sync idempotency, conflicts, and authorization. |
| backend/sinalacs_server/test/unit/app_config_test.dart | Adds unit tests for JWT secret validation rules across envs. |
| backend/sinalacs_server/test/integration/test_tools/serverpod_test_tools.dart | Extends integration test tooling for new visits.sync endpoint. |
| backend/sinalacs_server/test/integration/red_alert_cycle_test.dart | Aligns integration config with updated AppConfig shape. |
| backend/sinalacs_server/lib/src/runtime/alert_runtime.dart | Wires VisitSyncService creation with ORM-backed store. |
| backend/sinalacs_server/lib/src/models/api/visit_sync_result.spy.yaml | New Serverpod API model for visit sync results. |
| backend/sinalacs_server/lib/src/models/api/visit_sync_entry.spy.yaml | New Serverpod API model for visit sync request entries. |
| backend/sinalacs_server/lib/src/infrastructure/database/orm_visit_store.dart | Adds ORM-backed VisitStore implementation. |
| backend/sinalacs_server/lib/src/generated/protocol.yaml | Registers visits.sync in generated protocol. |
| backend/sinalacs_server/lib/src/generated/endpoints.dart | Registers generated endpoint connector for visits. |
| backend/sinalacs_server/lib/src/generated/api/visit_sync_result.dart | Generated server model for VisitSyncResult. |
| backend/sinalacs_server/lib/src/generated/api/visit_sync_entry.dart | Generated server model for VisitSyncEntry. |
| backend/sinalacs_server/lib/src/endpoints/visits_endpoint.dart | New RPC endpoint implementing transactional visit sync. |
| backend/sinalacs_server/lib/src/config/app_config.dart | Removes DB URL from AppConfig and hardens JWT secret validation. |
| backend/sinalacs_server/lib/src/application/visits/visit_sync_service.dart | Implements core visit sync logic + conflict/idempotency handling. |
| backend/sinalacs_server/docker-compose.yaml | Removes old Serverpod template compose with plaintext secrets. |
| backend/sinalacs_client/lib/src/protocol/client.dart | Adds typed visits endpoint to generated client. |
| backend/sinalacs_client/lib/src/protocol/api/visit_sync_result.dart | Generated client model for VisitSyncResult. |
| backend/sinalacs_client/lib/src/protocol/api/visit_sync_entry.dart | Generated client model for VisitSyncEntry. |
| backend/DEPLOY.md | Updates deploy guidance re: rotated dev secrets and JWT_SECRET requirements. |
| apps/patient/tool/live_check.dart | Adds VM live check for patient app network layer against local stack. |
| apps/patient/test/support/fake_patient_backend.dart | Adds fake backend to keep patient widget tests hermetic. |
| apps/patient/test/patient_app_mvp_test.dart | Expands widget tests to cover login failure, triage RPC, idempotency retries. |
| apps/patient/test/encrypted_database_test.dart | Removes misleading encryption test that exercised unencrypted FFI path in CI. |
| apps/patient/pubspec.yaml | Adds sinalacs_client path dep, integration_test, and updates SDK constraint. |
| apps/patient/lib/core/privacy/location_hash.dart | Adds LGPD-friendly location hashing helper. |
| apps/patient/lib/core/network/idempotency.dart | Adds UUID-like idempotency key generator. |
| apps/patient/lib/core/network/backend_scope.dart | Adds DI scope for injecting patient backend in widgets/tests. |
| apps/patient/lib/core/network/backend_config.dart | Adds compile-time backend host config. |
| apps/patient/lib/core/network/backend_client.dart | Adds typed backend facade with Portuguese error translation. |
| apps/patient/lib/core/network/auth_session.dart | Adds JWT payload parsing for session metadata (role/microArea/exp). |
| apps/patient/lib/core/database/encrypted_database.dart | Removes patient encrypted DB implementation (scope moved to ACS app). |
| apps/patient/integration_test/backend_connection_test.dart | Adds real integration tests for patient ↔ backend RPC behaviors. |
| apps/patient/android/app/src/debug/res/xml/network_security_config.xml | Allows cleartext HTTP only for debug + localhost/10.0.2.2. |
| apps/patient/android/app/src/debug/AndroidManifest.xml | Wires debug-only network security config. |
| apps/patient/.flutter-plugins-dependencies | Updates generated plugin dependency lockfile (should not be committed). |
| apps/acs/tool/live_check.dart | Adds VM live check for ACS full cycle (RPC + MQTT/TLS + visit sync). |
| apps/acs/test/widget_test.dart | Makes ACS widget test hermetic by injecting backend/feed fakes. |
| apps/acs/test/support/fakes.dart | Adds fakes for backend, feed, visit stores/synchronizer, and alert helpers. |
| apps/acs/test/route_service_test.dart | Adds unit tests for route/arrival logic. |
| apps/acs/test/reconnect_schedule_test.dart | Adds unit tests for reconnect backoff schedule. |
| apps/acs/test/mqtt_secure_client_test.dart | Fixes topic namespace expectations and expands refusal handling tests. |
| apps/acs/test/map_screen_test.dart | Adds widget tests for map/geofence flows. |
| apps/acs/test/alert_feed_test.dart | Adds tests ensuring missing MQTT password fails fast before sockets. |
| apps/acs/pubspec.yaml | Adds typed client dep, secure storage, maps version bump, assets cert dir, integration_test. |
| apps/acs/lib/core/services/visit_queue_factory.dart | Centralizes production visit-queue wiring (store + synchronizer). |
| apps/acs/lib/core/services/route_service.dart | Adds routing/arrival logic. |
| apps/acs/lib/core/services/reconnect_schedule.dart | Adds backoff schedule used by MQTT reconnect logic. |
| apps/acs/lib/core/services/mqtt_secure_client.dart | Hardens TLS setup, topic namespace helpers, refusal classification, and reconnect handling. |
| apps/acs/lib/core/services/backend_visit_synchronizer.dart | Implements translation from offline visits to visits.sync payloads. |
| apps/acs/lib/core/services/alert_queue.dart | Adds prioritized queue with territorial filter, idempotent upsert, and ack handling. |
| apps/acs/lib/core/services/alert_feed.dart | Adds MQTT feed wrapper with classified errors and CA asset loading. |
| apps/acs/lib/core/security/database_key_store.dart | Adds key custody via secure storage and in-memory test store. |
| apps/acs/lib/core/network/backend_scope.dart | Adds DI scope for injecting ACS backend in widgets/tests. |
| apps/acs/lib/core/network/backend_config.dart | Adds compile-time host/MQTT config and “missing password” detection. |
| apps/acs/lib/core/network/backend_client.dart | Adds typed ACS backend facade (ack + visit sync) with translated errors. |
| apps/acs/lib/core/network/auth_session.dart | Adds parsed JWT session metadata for ACS. |
| apps/acs/lib/core/database/sqlcipher_visit_store.dart | Adds encrypted visit persistence with key-loss recovery and retention behavior. |
| apps/acs/lib/core/database/encrypted_database.dart | Strengthens SQLCipher-only guarantee with explicit test-only unencrypted flag and migrations. |
| apps/acs/integration_test/red_alert_cycle_test.dart | Adds device integration tests for MQTT/TLS cycle + visit retention + idempotency. |
| apps/acs/integration_test/map_flow_test.dart | Adds integration tests for map/geofence flows and escalation routing. |
| apps/acs/integration_test/encrypted_storage_test.dart | Adds device-only proof that DB file is actually encrypted (no plaintext markers). |
| apps/acs/android/app/src/main/kotlin/com/example/sinalacs_acs/MainActivity.kt | Changes Android package declaration for ACS app. |
| apps/acs/android/app/src/main/AndroidManifest.xml | Injects Google Maps API key via manifest placeholder. |
| apps/acs/android/app/src/debug/res/xml/network_security_config.xml | Allows cleartext HTTP only for debug + localhost/10.0.2.2. |
| apps/acs/android/app/src/debug/AndroidManifest.xml | Wires debug-only network security config. |
| apps/acs/android/app/build.gradle.kts | Adds build-time guard requiring SINALACS_MQTT_PASSWORD and injects maps key placeholder. |
| apps/acs/.flutter-plugins-dependencies | Updates generated plugin dependency lockfile (should not be committed). |
| README.md | Updates local setup instructions to use bootstrap + ACS run wrapper; documents JWT secret rules. |
| CONTRIBUTING.md | Updates run instructions to use ACS wrapper script and explains why. |
| .gitignore | Ensures .env.example is tracked and ignores generated MQTT CA asset directory. |
| .github/workflows/ci.yml | Removes hardcoded shared password and centralizes ephemeral CI postgres password. |
| .env.example | Adds versioned .env template documenting all required variables and consumers. |
Suppressed comments (6)
backend/sinalacs_server/test/unit/app_config_test.dart:1
- Isso não compila em Dart:
?jwtSecretnão é sintaxe válida para valor de map. Para tornar o campo opcional, construa o map condicionalmente (ex.: só inclua'JWT_SECRET'quandojwtSecret != null) ou passe explicitamentejwtSecret ?? ''se a intenção for testar string vazia.
infra/docker/mosquitto/init.sh:1 - Arquivos
.key(incluindoca.key/server.key) não deveriam ficar world-readable (644). Recomendo restringir permissões: chaves privadas com600(ou640com grupo dedicado) e opasswordfiletambém (idealmente600), mantendo apenas.crtem644se necessário.
apps/acs/lib/core/services/route_service.dart:1 - A indentação/formatting desses métodos está inconsistente com o padrão Dart e tende a quebrar
dart format/lint do projeto. Sugestão: rodardart formatno arquivo (ou corrigir manualmente para alinhamento padrão de 2 espaços) para evitar ruído e diffs futuros.
apps/acs/lib/core/services/route_service.dart:1 - A indentação/formatting desses métodos está inconsistente com o padrão Dart e tende a quebrar
dart format/lint do projeto. Sugestão: rodardart formatno arquivo (ou corrigir manualmente para alinhamento padrão de 2 espaços) para evitar ruído e diffs futuros.
backend/sinalacs_server/test/unit/visit_sync_service_test.dart:1 - O nome do teste afirma que a visita é atualizada, mas as asserções verificam explicitamente que NÃO houve atualização (status permanece 'realizada' quando
entry.version == existing.version). Para refletir o comportamento validado, renomeie o teste para algo como “não atualiza quando entry.version == version do servidor (reenvio idempotente)”.
backend/sinalacs_server/test/unit/visit_sync_service_test.dart:1 - O nome do teste afirma que a visita é atualizada, mas as asserções verificam explicitamente que NÃO houve atualização (status permanece 'realizada' quando
entry.version == existing.version). Para refletir o comportamento validado, renomeie o teste para algo como “não atualiza quando entry.version == version do servidor (reenvio idempotente)”.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| @@ -1 +1 @@ | |||
| {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/codespace/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","native_build":true,"dependencies":[]},{"name":"geolocator_apple","path":"/home/codespace/.pub-cache/hosted/pub.dev/geolocator_apple-2.3.14/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"google_maps_flutter_ios","path":"/home/codespace/.pub-cache/hosted/pub.dev/google_maps_flutter_ios-2.15.2/","native_build":true,"dependencies":[]},{"name":"sqflite_darwin","path":"/home/codespace/.pub-cache/hosted/pub.dev/sqflite_darwin-2.4.1+1/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite_sqlcipher","path":"/home/codespace/.pub-cache/hosted/pub.dev/sqflite_sqlcipher-3.2.0/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/codespace/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","native_build":true,"dependencies":[]},{"name":"flutter_plugin_android_lifecycle","path":"/home/codespace/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.26/","native_build":true,"dependencies":[]},{"name":"geolocator_android","path":"/home/codespace/.pub-cache/hosted/pub.dev/geolocator_android-4.6.2/","native_build":true,"dependencies":[]},{"name":"google_maps_flutter_android","path":"/home/codespace/.pub-cache/hosted/pub.dev/google_maps_flutter_android-2.14.13/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"sqflite_android","path":"/home/codespace/.pub-cache/hosted/pub.dev/sqflite_android-2.4.0/","native_build":true,"dependencies":[]},{"name":"sqflite_sqlcipher","path":"/home/codespace/.pub-cache/hosted/pub.dev/sqflite_sqlcipher-3.2.0/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus","path":"/home/codespace/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","native_build":true,"dependencies":[]},{"name":"geolocator_apple","path":"/home/codespace/.pub-cache/hosted/pub.dev/geolocator_apple-2.3.14/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite_darwin","path":"/home/codespace/.pub-cache/hosted/pub.dev/sqflite_darwin-2.4.1+1/","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite_sqlcipher","path":"/home/codespace/.pub-cache/hosted/pub.dev/sqflite_sqlcipher-3.2.0/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus","path":"/home/codespace/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus","path":"/home/codespace/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","native_build":true,"dependencies":[]},{"name":"geolocator_windows","path":"/home/codespace/.pub-cache/hosted/pub.dev/geolocator_windows-0.2.5/","native_build":true,"dependencies":[]}],"web":[{"name":"connectivity_plus","path":"/home/codespace/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","dependencies":[]},{"name":"geolocator_web","path":"/home/codespace/.pub-cache/hosted/pub.dev/geolocator_web-4.1.4/","dependencies":[]},{"name":"google_maps_flutter_web","path":"/home/codespace/.pub-cache/hosted/pub.dev/google_maps_flutter_web-0.5.12/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"geolocator","dependencies":["geolocator_android","geolocator_apple","geolocator_web","geolocator_windows"]},{"name":"geolocator_android","dependencies":[]},{"name":"geolocator_apple","dependencies":[]},{"name":"geolocator_web","dependencies":[]},{"name":"geolocator_windows","dependencies":[]},{"name":"google_maps_flutter","dependencies":["google_maps_flutter_android","google_maps_flutter_ios","google_maps_flutter_web"]},{"name":"google_maps_flutter_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"google_maps_flutter_ios","dependencies":[]},{"name":"google_maps_flutter_web","dependencies":[]},{"name":"sqflite","dependencies":["sqflite_android","sqflite_darwin"]},{"name":"sqflite_android","dependencies":[]},{"name":"sqflite_darwin","dependencies":[]},{"name":"sqflite_sqlcipher","dependencies":[]}],"date_created":"2026-09-01 23:40:01.422052","version":"3.24.5","swift_package_manager_enabled":false} No newline at end of file | |||
| {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/rock/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/home/rock/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"geolocator_apple","path":"/home/rock/.pub-cache/hosted/pub.dev/geolocator_apple-2.3.14/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"google_maps_flutter_ios","path":"/home/rock/.pub-cache/hosted/pub.dev/google_maps_flutter_ios-2.18.6/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"integration_test","path":"/home/rock/flutter/packages/integration_test/","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"path_provider_foundation","path":"/home/rock/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqflite_darwin","path":"/home/rock/.pub-cache/hosted/pub.dev/sqflite_darwin-2.4.1+1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqflite_sqlcipher","path":"/home/rock/.pub-cache/hosted/pub.dev/sqflite_sqlcipher-3.2.0/","native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"connectivity_plus","path":"/home/rock/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_plugin_android_lifecycle","path":"/home/rock/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.35/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage","path":"/home/rock/.pub-cache/hosted/pub.dev/flutter_secure_storage-9.2.4/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"geolocator_android","path":"/home/rock/.pub-cache/hosted/pub.dev/geolocator_android-4.6.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"google_maps_flutter_android","path":"/home/rock/.pub-cache/hosted/pub.dev/google_maps_flutter_android-2.19.13/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"],"dev_dependency":false},{"name":"integration_test","path":"/home/rock/flutter/packages/integration_test/","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"jni","path":"/home/rock/.pub-cache/hosted/pub.dev/jni-1.0.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"jni_flutter","path":"/home/rock/.pub-cache/hosted/pub.dev/jni_flutter-1.0.3/","native_build":true,"dependencies":["jni"],"dev_dependency":false},{"name":"path_provider_android","path":"/home/rock/.pub-cache/hosted/pub.dev/path_provider_android-2.3.1/","native_build":false,"dependencies":["jni","jni_flutter"],"dev_dependency":false},{"name":"sqflite_android","path":"/home/rock/.pub-cache/hosted/pub.dev/sqflite_android-2.4.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqflite_sqlcipher","path":"/home/rock/.pub-cache/hosted/pub.dev/sqflite_sqlcipher-3.2.0/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"connectivity_plus","path":"/home/rock/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_macos","path":"/home/rock/.pub-cache/hosted/pub.dev/flutter_secure_storage_macos-3.1.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"geolocator_apple","path":"/home/rock/.pub-cache/hosted/pub.dev/geolocator_apple-2.3.14/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/home/rock/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqflite_darwin","path":"/home/rock/.pub-cache/hosted/pub.dev/sqflite_darwin-2.4.1+1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"sqflite_sqlcipher","path":"/home/rock/.pub-cache/hosted/pub.dev/sqflite_sqlcipher-3.2.0/","native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"connectivity_plus","path":"/home/rock/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_linux","path":"/home/rock/.pub-cache/hosted/pub.dev/flutter_secure_storage_linux-1.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"jni","path":"/home/rock/.pub-cache/hosted/pub.dev/jni-1.0.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/home/rock/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.2/","native_build":false,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"connectivity_plus","path":"/home/rock/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_windows","path":"/home/rock/.pub-cache/hosted/pub.dev/flutter_secure_storage_windows-3.1.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"geolocator_windows","path":"/home/rock/.pub-cache/hosted/pub.dev/geolocator_windows-0.2.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"jni","path":"/home/rock/.pub-cache/hosted/pub.dev/jni-1.0.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/home/rock/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false}],"web":[{"name":"connectivity_plus","path":"/home/rock/.pub-cache/hosted/pub.dev/connectivity_plus-7.3.1/","dependencies":[],"dev_dependency":false},{"name":"flutter_secure_storage_web","path":"/home/rock/.pub-cache/hosted/pub.dev/flutter_secure_storage_web-1.2.1/","dependencies":[],"dev_dependency":false},{"name":"geolocator_web","path":"/home/rock/.pub-cache/hosted/pub.dev/geolocator_web-4.1.4/","dependencies":[],"dev_dependency":false},{"name":"google_maps_flutter_web","path":"/home/rock/.pub-cache/hosted/pub.dev/google_maps_flutter_web-0.6.3+1/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_secure_storage","dependencies":["flutter_secure_storage_linux","flutter_secure_storage_macos","flutter_secure_storage_web","flutter_secure_storage_windows"]},{"name":"flutter_secure_storage_linux","dependencies":[]},{"name":"flutter_secure_storage_macos","dependencies":[]},{"name":"flutter_secure_storage_web","dependencies":[]},{"name":"flutter_secure_storage_windows","dependencies":["path_provider"]},{"name":"geolocator","dependencies":["geolocator_android","geolocator_apple","geolocator_web","geolocator_windows"]},{"name":"geolocator_android","dependencies":[]},{"name":"geolocator_apple","dependencies":[]},{"name":"geolocator_web","dependencies":[]},{"name":"geolocator_windows","dependencies":[]},{"name":"google_maps_flutter","dependencies":["google_maps_flutter_android","google_maps_flutter_ios","google_maps_flutter_web"]},{"name":"google_maps_flutter_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"google_maps_flutter_ios","dependencies":[]},{"name":"google_maps_flutter_web","dependencies":[]},{"name":"integration_test","dependencies":[]},{"name":"jni","dependencies":[]},{"name":"jni_flutter","dependencies":["jni"]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":["jni","jni_flutter"]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"sqflite","dependencies":["sqflite_android","sqflite_darwin"]},{"name":"sqflite_android","dependencies":[]},{"name":"sqflite_darwin","dependencies":[]},{"name":"sqflite_sqlcipher","dependencies":[]}],"date_created":"2026-09-12 17:43:15.622135","version":"3.44.8","swift_package_manager_enabled":{"ios":false,"macos":false}} No newline at end of file | |||
Adiciona o relatório completo de avaliação de UI/UX e acessibilidade (WCAG 2.1 AA) para os aplicativos Patient e ACS em
spec/ux_accessibility_assessment.md, incluindo evidências do WebAIM Contrast Checker emspec/assets/.Closes #2