Skip to content

feat(admin): implementar backoffice administrativo (issue #4) - #5

Merged
hbgit merged 17 commits into
developfrom
feat/admin-backoffice
Sep 15, 2026
Merged

hbgit merged 17 commits into
developfrom
feat/admin-backoffice

Conversation

@vinimartinsufrr

@vinimartinsufrr vinimartinsufrr commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

O que muda

Leva apps/admin/ de esqueleto (só pubspec.yaml) a um backoffice Flutter navegável, no mesmo padrão visual/código de apps/acs/ e apps/patient/:

  • Login (local, ambiente de desenvolvimento — ver divergência 2 abaixo)
  • Painel de indicadores: contadores por RiskLevel, alertas vermelhos abertos/reconhecidos, TMRAV
  • Microáreas: listagem somente leitura de microárea + ACS vinculado
  • Alertas: consulta filtrável por microárea/status, sem reclassificação de risco
  • Logs de auditoria: somente leitura, com o próprio acesso do admin também registrado (AdminDataSource.recordAccess)

Camada de dados isolada atrás de AdminDataSource (interface) + MockAdminDataSource (implementação mock, dados fictícios espelhando os campos reais dos .spy.yaml do backend), no espírito do AlertPublisher/AlertStore do servidor. Tema em admin_theme.dart, seguindo a estrutura de acs_theme.dart/patient_theme.dart (accent índigo #4F46E5). Navegação responsiva: NavigationRail em telas ≥640px, NavigationBar abaixo disso.

Suporte a Flutter Web adicionado (flutter create --platforms=web .) — alvo de plataforma decidido como Web (backoffice é desktop-first), conforme a issue sugeria confirmar antes do scaffolding.

Por quê

Fecha a issue #4: o apps/admin/ era o único dos três clientes (P-APP, ACS-APP, ADMIN) ainda não implementado, apesar de já reservado na arquitetura (spec/PRD_system.md §2.1) e na matriz RBAC (§4.2.2).

Como testar

cd apps/admin
flutter pub get
flutter analyze      # 0 erros/warnings
flutter test         # 12 arquivos de teste, 1+ por tela
flutter run -d web-server --web-port=8765   # depois abrir http://localhost:8765 manualmente
                                              # (flutter run -d chrome/edge falhou nesta máquina — problema
                                              #  de lançamento do CDP, não relacionado a este código)

Divergências em relação ao texto da issue (documentadas para não deixar o revisor descobrir sozinho)

  1. Versão do Flutter: a issue citava 3.24.0 para o job de CI; o ci.yml real já fixava 3.44.8 nos jobs patient-app/acs-app no momento em que criei a branch (confirmado lendo o arquivo). Usei 3.44.8.

  2. Login não chama auth.developmentLogin: a issue pede explicitamente esse endpoint. Investiguei implementar de verdade, seguindo o padrão que apps/patient/apps/acs já usam (sinalacs_client + BackendClient, que passaram a existir depois que este branch foi criado). Descobri que backend/sinalacs_server/lib/src/endpoints/auth_endpoint.dart só aceita role: 'patient' ou role: 'acs' — não há usuário fixo de desenvolvimento para admin; a chamada real falha com AlertValidationException. Ligar isso de verdade exige uma mudança no backend (endpoint compartilhado, fora do escopo desta issue de app). Mantive login local, documentado no código (LoginScreen) e em docs/telas-admin.md. Abro uma issue separada para estender auth.developmentLogin com o papel admin, se fizer sentido para o grupo.

Fora do escopo (por decisão explícita da issue)

  • Escrita/edição de vínculo ACS↔microárea (fica para uma próxima issue)
  • Autenticação institucional real (SSO/gov.br), mTLS no broker, deploy de produção
  • Qualquer reclassificação manual de risco

Screenshots

Capturadas rodando flutter run -d web-server e abrindo localhost manualmente no navegador (dados fictícios). Documentação completa por tela em docs/telas-admin.md.

Login Indicadores Microáreas
Login Indicadores Microáreas
Alertas Auditoria
Alertas Auditoria

Closes #4

🤖 Generated with Claude Code

https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX

vinimartinsufrr and others added 13 commits September 13, 2026 10:14
…s, alertas, auditoria)

Cinco telas no shell responsivo do backoffice: login local (padrão dev,
mesmo fluxo dos outros apps), painel de indicadores por RiskLevel,
listagem somente leitura de microáreas/ACS, consulta filtrável de
alertas (sem reclassificação de risco) e log de auditoria com
self-audit do próprio admin.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
…tient-app

A issue citava Flutter 3.24.0 para este job, mas o ci.yml real fixa
3.44.8 nos jobs patient-app/acs-app -- usei a versão que já roda no
pipeline, não a citada na issue.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
Screenshots reais ficam pendentes nesta entrega -- ver descrição do PR.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
… teste

_InfoRow (painel de indicadores) e os DropdownButtonFormField de filtro
de alertas estouravam a largura em telas <640px -- pego pelos próprios
testes de responsividade (flutter test acusou RenderFlex overflow).
Corrigido com Expanded/isExpanded. Também faltava o import de
flutter/material.dart em audit_log_screen_test.dart (flutter analyze
acusou).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
…orms=web)

Faltava o scaffolding de plataforma -- flutter run/build web falhava
com 'This application is not configured to build on the web.'.
Adiciona web/, .metadata, .gitignore próprio do app e README.md no
padrão de apps/patient e apps/acs. O test/widget_test.dart gerado
pelo comando (teste padrão do contador, referenciando uma classe
MyApp inexistente) foi removido -- os testes reais já estão em
test/*_test.dart.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
O banner 'ambiente de desenvolvimento' usava AdminColors.yellow na
borda e no ícone, e o chip de status do ACS na tela de microáreas
usava AdminColors.green para Ativo -- exatamente o padrão que a issue
proíbe explicitamente (amarelo para aviso, verde para status, não
para RiskLevel). Banner agora usa AdminColors.accent (índigo,
neutro); o chip de status usa ícone (check/remove) em vez de cor
para diferenciar ativo/inativo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
Investiguei ligar de verdade (apps/patient e apps/acs já fazem isso, via
sinalacs_client + BackendClient) antes de decidir manter local. Motivo:
backend/sinalacs_server/lib/src/endpoints/auth_endpoint.dart só aceita
role patient ou acs -- não existe usuário fixo de dev para admin, a
chamada real falharia com AlertValidationException. Ligar isso exige
mudança no backend, fora do escopo desta issue (app apps/admin). Ver
descrição do PR para o achado completo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
A frase antiga dizia que paciente/ACS também não chamam o backend hoje
-- ficou desatualizada depois que os dois passaram a autenticar de
verdade contra auth.developmentLogin. Corrige e explica por que o
admin continua local (mesmo motivo do commit anterior: endpoint só
aceita role patient/acs).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
Capturadas rodando flutter run -d web-server e abrindo localhost
manualmente no navegador, dados fictícios. Remove a nota de pendência
em telas-admin.md, que já referenciava esses arquivos pelo nome.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical authentication and moderate data-loading and audit error-handling issues remain.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds a Flutter Web administrative backoffice with responsive navigation, mock data, dashboards, alerts, microareas, and audit logs.

Changes:

  • Adds admin screens, theme, and local development login.
  • Adds data-source contracts, mock implementation, tests, and documentation.
  • Adds Web scaffolding and an admin CI job.
File summaries
File Description
docs/telas-admin.md Admin screen documentation.
apps/admin/web/manifest.json PWA metadata.
apps/admin/web/index.html Flutter Web shell.
apps/admin/test/mock_admin_data_source_test.dart Mock data-source tests.
apps/admin/test/micro_areas_screen_test.dart Microareas screen tests.
apps/admin/test/login_flow_test.dart Login flow tests.
apps/admin/test/audit_log_screen_test.dart Audit log tests.
apps/admin/test/alerts_screen_test.dart Alerts screen tests.
apps/admin/test/admin_home_shell_test.dart Admin shell tests.
apps/admin/README.md Admin app documentation.
apps/admin/pubspec.lock Locked dependencies.
apps/admin/lib/main.dart Application entry point.
apps/admin/lib/core/data/mock_admin_data_source.dart Mock administrative data source.
apps/admin/lib/core/data/admin_data_source.dart Data-source interface and models.
apps/admin/lib/app/app.dart Login, navigation, and administrative screens.
apps/admin/lib/app/admin_theme.dart Admin theme.
apps/admin/analysis_options.yaml Analyzer configuration.
apps/admin/.metadata Flutter project metadata.
apps/admin/.gitignore Project exclusions.
.github/workflows/ci.yml Admin CI job.
Review details

Suppressed comments (9)

apps/admin/lib/app/app.dart:244

  • Se fetchDashboardIndicators() falhar, snapshot.hasData permanece falso mesmo quando o Future termina com erro, então a tela fica em um spinner indefinidamente e oculta falhas de rede/backend. Trate snapshot.hasError antes desse ramo e mostre um estado de erro, idealmente com retry.
          if (!snapshot.hasData) return const Center(child: CircularProgressIndicator());

apps/admin/lib/app/app.dart:325

  • O mesmo FutureBuilder deixa qualquer erro de fetchMicroAreas() preso no spinner: com erro, snapshot.hasData nunca fica verdadeiro. Isso faz uma falha do backend parecer uma tela carregando para sempre; trate snapshot.hasError explicitamente antes de renderizar o loading.
          final areas = snapshot.data ?? const [];
          if (!snapshot.hasData) return const Center(child: CircularProgressIndicator());

apps/admin/lib/app/app.dart:431

  • Quando fetchAlerts falha, snapshot.data fica nulo e este ramo exibe “Nenhum alerta...” como se a consulta tivesse retornado vazia. Uma indisponibilidade pode assim ocultar alertas vermelhos; trate snapshot.hasError antes do estado vazio e mostre uma falha (idealmente com retry).
              else if (alerts.isEmpty)
                const Padding(padding: EdgeInsets.only(top: 24), child: Text('Nenhum alerta para o filtro selecionado.'))

apps/admin/lib/app/app.dart:487

  • Se fetchAuditLogs() falhar, entries também vira vazio e a tela afirma “Nenhum acesso registrado ainda”, ocultando a falha de leitura dos logs. Diferencie snapshot.hasError do resultado vazio e mostre um erro/retry.
              final entries = snapshot.data ?? const [];

apps/admin/lib/app/app.dart:369

  • Aqui o Future de recordAccess() também é descartado. Uma falha na fonte real deixa a consulta de alertas disponível sem registrar o acesso e gera uma exceção assíncrona não tratada; aguarde o registro e trate falha antes de mostrar a lista.
    widget.dataSource.recordAccess(actionType: 'view', resourceType: 'alerts');

apps/admin/lib/app/app.dart:38

  • O repositório removeu a senha pré-preenchida do app ACS (apps/acs/lib/app/app.dart:98-100), e este 123456 volta a embutir uma credencial no bundle. Mesmo sendo mock, isso pode ser confundido com uma senha válida ou reutilizado por engano; mantenha o campo vazio e documente o modo de desenvolvimento separadamente.
  final _senha = TextEditingController(text: '123456');

apps/admin/lib/app/app.dart:393

  • DropdownButton trata value == null como ausência de seleção, portanto este item nulo não mantém o rótulo “Todas” visível: o campo começa ou volta do filtro com aparência vazia. Use um valor sentinela não nulo (mapeado para filtro nulo) ou um hint para deixar o estado sem filtro claro.
                        DropdownMenuItem(value: null, child: Text('Todas')),

apps/admin/lib/app/app.dart:418

  • O filtro de status tem o mesmo problema do filtro de microárea: com value nulo, “Todos” não é exibido como seleção atual e o campo fica visualmente vazio após limpar o filtro. Use um sentinela não nulo ou um hint explícito.
                        const DropdownMenuItem(value: null, child: Text('Todos')),

apps/admin/web/manifest.json:9

  • O manifesto ainda declara portrait-primary e os metadados padrão do Flutter. Como este backoffice é desktop-first e tem layout responsivo, uma instalação PWA pode ficar restrita a retrato e exibir splash/chrome azul genérico, divergindo do tema índigo/escuro do app. Ajuste esses metadados para o backoffice, usando orientação any e as cores/descrição do produto.
    "background_color": "#0175C2",
    "theme_color": "#0175C2",
    "description": "A new Flutter project.",
    "orientation": "portrait-primary",
  • Files reviewed: 19/30 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +47 to +50
void _login() {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => AdminHomeShell(dataSource: widget.dataSource)),
);
Comment thread apps/admin/lib/app/app.dart Outdated
@override
void initState() {
super.initState();
widget.dataSource.recordAccess(actionType: 'view', resourceType: 'micro_areas');
Comment thread apps/admin/lib/app/app.dart Outdated
Comment on lines +392 to +396
items: const [
DropdownMenuItem(value: null, child: Text('Todas')),
DropdownMenuItem(
value: 'Microárea 12 — Zona Rural',
child: Text('Microárea 12 — Zona Rural', overflow: TextOverflow.ellipsis),
Comment on lines +481 to +482
if (recordSnapshot.connectionState != ConnectionState.done) {
return const Center(child: CircularProgressIndicator());
@hbgit

hbgit commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Olá @vinimartinsufrr , obrigado pelas suas contribuições.

Visando atender certos critérios de qualidade, segue aqui nesta ISSUE uma revisão que necessita de alguns ajustes no seu PR: #5 (review)

Verifique as alterações necessárias e faça uma atualização nesta PR.

vinimartinsufrr and others added 4 commits September 15, 2026 08:58
Corrige os 9 pontos da review em pull/5#pullrequestreview-5199741445:

- Indicadores, microáreas, alertas e auditoria: FutureBuilder só checava
  hasData, então um erro real ficava com spinner infinito (indicadores) ou
  era mostrado como se a lista estivesse vazia (alertas, auditoria) --
  escondendo, por exemplo, uma falha ao carregar alertas vermelhos. Todas
  as quatro telas agora tratam snapshot.hasError com um estado de erro
  próprio e botão de retry (_AsyncError, cor neutra, não usa
  vermelho/amarelo/verde -- essas cores continuam reservadas a RiskLevel).
- Microáreas e alertas: recordAccess() era chamado sem await no initState
  (fire-and-forget), então uma falha no registro de auditoria não impedia
  a tela de mostrar dado sensível, e virava exceção assíncrona não
  tratada. Agora o acesso é registrado antes dos dados serem buscados/
  exibidos, no mesmo espírito do que AuditLogScreen já fazia certo.
- Dropdown de filtro (microárea e status): com value null, o
  DropdownButton mostra o hint, não o child do item -- sem hint definido,
  o campo ficava em branco ao selecionar Todas/Todos em vez de mostrar o
  rótulo. Adicionado hint explícito nos dois.
- Login: campos de matrícula/senha vinham pré-preenchidos
  (admin.dev/123456), diferente do padrão atual do ACS (que remove esse
  preenchimento). Removido; o botão continua avançando independente do
  que for digitado, já documentado no próprio LoginScreen.
- web/manifest.json e web/index.html: description, theme/background
  color e orientation ainda eram o padrão gerado pelo flutter create
  (azul do Flutter, A new Flutter project., portrait-primary), não o
  tema índigo/escuro e o layout desktop-first do backoffice.

Durante a correção, os próprios testes novos (próximo commit) pegaram
mais um bug: setState(() => _future = fetch()) retorna a Future da
atribuição (regra de que x = y vale y em Dart), o que o Flutter rejeita.
Corrigido para corpo de bloco nos dois retries que tinham esse padrão
(Indicadores e Microáreas).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
Cobre os quatro FutureBuilder corrigidos (indicadores, microáreas,
alertas, auditoria): erro não pode aparecer como vazio nem travar em
spinner, e o botão Tentar novamente precisa recuperar de verdade. Mais
um teste de regressão do hint dos dropdowns (Todas/Todos visíveis
fechados). Duplo de teste novo em test/support/failing_admin_data_source.dart,
que permite forçar falha em qualquer método uma única vez.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
Os outros 2 comentários inline (pull/5#discussion_r4006859849 e
r4006859916) já tinham sido corrigidos sem querer no commit anterior
(mesmo bug do recordAccess sem await e do hasError da auditoria, só que
relatado como comentário de linha em vez de no resumo da review).
Restavam estes dois:

- Login sem nenhum controle de acesso: o botão Entrar ignorava
  matrícula/senha e não tinha gate nenhum, então qualquer pessoa
  clicava e via alertas/auditoria, mesmo numa build fora de dev. O
  banner é só aviso, não bloqueia nada. Adiciona devLoginEnabled
  (default kDebugMode, false em build profile/release) que desabilita
  o botão de verdade fora de modo debug -- não resolve a falta de auth
  institucional (fora de escopo, já documentado), mas fecha o buraco de
  qualquer um entrar em qualquer build.

- Filtro de microárea em Alertas: os itens do dropdown eram três
  strings fixas no código (as do seed mock). Trocando o
  AdminDataSource por uma fonte real, ou surgindo uma microárea nova,
  os alertas dela continuariam retornando mas sem opção de filtro
  correspondente. As opções agora vêm de fetchMicroAreas().

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
…nâmico)

login_dev_gate_test.dart: com devLoginEnabled false o botão fica
desabilitado e não navega; com true funciona normal.
alerts_filter_dynamic_test.dart: um AdminDataSource com uma microárea
fora do antigo seed mock aparece como opção no filtro, provando que
as opções vêm de fetchMicroAreas() e não de uma lista fixa no código.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyMMKXSksyUUNXPieFpSfX
@vinimartinsufrr

vinimartinsufrr commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator Author

Bom dia Professor @hbgit, obrigado pela revisão. Tratei os 13 pontos da review do Copilot (pull/5#pullrequestreview-5199741445, sendo 9 no resumo + 4 comentários inline, sendo 2 destes últimos duplicados dos 9):

Tratamento de erro (indicadores, microáreas, alertas, auditoria): os FutureBuilder só checavam hasData, então um erro real ficava em spinner infinito ou era mostrado como se a lista estivesse vazia. O que podia esconder, por exemplo, uma falha ao carregar alertas vermelhos. Agora as 4 telas tratam snapshot.hasError com um estado de erro próprio e botão de retry.

Auditoria de acesso não esperada: recordAccess() era chamado sem await em Microáreas e Alertas, então uma falha no registro não impedia a tela de mostrar dado sensível. Agora o acesso é registrado antes dos dados serem exibidos.

Login sem nenhum controle de acesso: o botão Entrar ignorava matrícula/senha e não tinha gate nenhum, ou seja, qualquer pessoa clicava e via alertas/auditoria, em qualquer build. Adicionei um gate por kDebugMode (desabilitado de verdade fora de modo debug). Não resolve a falta de auth institucional real (documentado como fora de escopo desta issue), mas fecha esse buraco específico.

Filtro de microárea fixo no código: os itens do dropdown eram três strings fixas do seed mock. Agora vêm de fetchMicroAreas().

Dropdown "em branco" ao selecionar Todas/Todos* DropdownButton mostra o hint, não o child do item, quando o valor é null. Adicionei hint explícito nos dois filtros.

Senha pré-preenchida no login: removida, seguindo o padrão atual do ACS.

Metadados padrão do Flutter Web (manifest.json, index.html): ainda tinham a cor azul/descrição genérica do template. Atualizados para o tema do backoffice.

Durante a correção, os próprios testes novos pegaram mais um bug (setState(() => future = fetch()) retorna a Future da atribuição, o que o Flutter rejeita), foi corrigido também.

Adicionei 8 testes novos cobrindo especificamente esses achados (erro/retry por tela, gate de login, filtro dinâmico), além dos 11 que já existiam. flutter analyze limpo e flutter test com 19/19 passando.

Sem force-push em nenhum momento. Apenas commits novos em cima do que já estava no PR, como pede o guia de contribuição.

@hbgit
hbgit merged commit 17dc567 into develop Sep 15, 2026
5 of 6 checks passed
hbgit added a commit that referenced this pull request Sep 15, 2026
CLAUDE.md e AGENTS.md não eram atualizados desde 8c5215a. Desde então,
develop recebeu a branch feat/admin-backoffice (merge #5) e uma
reauditoria de acessibilidade (fix(a11y)), e nenhum dos dois ficou
refletido na documentação de orientação para IA — o guia ainda descrevia
apps/admin como "pubspec skeleton, no implementation yet" e o CI com
quatro jobs.

apps/admin (backoffice)
- Documentada a arquitetura real do app: AdminHomeShell com 4 telas
  somente leitura (Indicadores, Microáreas, Alertas, Auditoria), a
  interface AdminDataSource/MockAdminDataSource (mesmo padrão de DI de
  PatientBackend/AcsBackend, ainda sem consumir sinalacs_client), o
  registro de acesso via recordAccess() antes de renderizar dado
  sensível (PRD §4.2.2), o motivo do login não chamar
  auth.developmentLogin (backend só aceita role 'patient'/'acs'), o
  layout desktop-first (NavigationRail/NavigationBar) e o suporte a
  Flutter Web, exclusivo deste app entre os três.

CI
- CLAUDE.md e AGENTS.md ainda diziam "quatro jobs" / "jobs separados
  para backend e apps"; agora refletem os cinco jobs reais
  (serverpod-backend, backend-docker-build, patient-app, acs-app,
  admin-app).

Acessibilidade (WCAG 2.2 AA)
- Documentados os tokens redOnSurface/accentOnSurface (ACS) e
  dangerOnSurface/accentOnSurface (paciente) introduzidos pela
  reauditoria de contraste: cores clínicas de preenchimento só atingem
  4.5:1 (WCAG 1.4.3) como fill, não como texto sobre Card/surfaceRaised.
  Adicionada uma regra de trabalho explícita nos dois arquivos: medir
  contraste contra a superfície onde o texto realmente renderiza, não
  contra o fundo do Scaffold — o erro que produziu o falso positivo
  original em spec/ux_accessibility_assessment.md.

Leitura obrigatória
- Adicionados os três documentos novos em spec/ (lgpd_data_audit.md,
  ux_accessibility_assessment.md, ux_ui_test_plan.md) às listas de
  leitura obrigatória de ambos os arquivos.

Signed-off-by: Herbert Rocha <herberthb12@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants