TDD — Relatório de EBD (Preencher)
Status
Section titled “Status”Em elaboração
Contexto
Section titled “Contexto”Este TDD define os cenários de teste e critérios de aceite para a funcionalidade “Preencher relatório de EBD”, com controle por fases e autorização por papel + vínculo + escopo.
Arquitetura funcional da jornada
Section titled “Arquitetura funcional da jornada”O fluxo é dividido em duas ações operacionais distintas:
-
Criar sessão de EBD (
create_ebd_session)- responsabilidade da governança da ocorrência (igreja/ministério);
- cria a sessão e define classes/responsáveis presentes.
-
Preencher classe da sessão (
fill_ebd_class_report)- responsabilidade de execução por classe;
- classes da sessão são visíveis para perfis operacionais;
- preenchimento efetivo depende de vínculo aprovado por classe.
Regra:
- sem sessão criada não há preenchimento de classe.
Cenários
Section titled “Cenários”Visibilidade da ação
Section titled “Visibilidade da ação”| ID | Cenário | Dado | Quando | Então |
|---|---|---|---|---|
| V1 | Ação visível para professor | Usuário com EBD_TEACHER aprovado e matriz READ/FULL | Acessa aba Ações | ”Preencher relatório de EBD” aparece na lista |
| V2 | Ação visível para secretário | Usuário com EBD_SECRETARY aprovado e matriz READ/FULL | Acessa aba Ações | ”Preencher relatório de EBD” aparece na lista |
| V3 | Ação visível para assistente vinculado | Usuário com papel de assistente e matriz READ/FULL | Acessa aba Ações | ”Preencher relatório de EBD” aparece conforme política híbrida |
| V4 | Ação oculta por matriz NONE | Usuário com minRole elegível, porém matriz NONE para EBD/FILL_REPORT | Acessa aba Ações | ”Preencher relatório de EBD” não aparece |
| V5 | Ação oculta sem perfil | Usuário não logado | Acessa aba Ações | ”Preencher relatório de EBD” não aparece |
Navegação
Section titled “Navegação”| ID | Cenário | Dado | Quando | Então |
|---|---|---|---|---|
| N1 | Navegação para página | Usuário com perfil autorizado | Toca em “Preencher relatório de EBD” | Abre EbdReportPage |
| N2 | Retorno | Na EbdReportPage | Toca em Voltar | Retorna à Home |
Página do relatório (MVP)
Section titled “Página do relatório (MVP)”| ID | Cenário | Dado | Quando | Então |
|---|---|---|---|---|
| P1 | Exibição inicial | Usuário na EbdReportPage | Página carrega | Título, descrição, seletor de igreja e data visíveis |
| P2 | Botão voltar | Na EbdReportPage | AppBar com leading | Ícone de voltar funcional |
| P3 | Igreja pré-selecionada | Perfil com organizationNode/unitId | Página carrega | Dropdown mostra igreja do perfil |
| P4 | Data domingo | Usuário toca no seletor de data | DatePicker abre | Apenas domingos selecionáveis |
| P5 | Continuar | Igreja e data selecionados | Toca em Continuar | Carrega ou cria EbdSession; exibe sessão |
Criação de EbdSession e inclusão de classes
Section titled “Criação de EbdSession e inclusão de classes”| ID | Cenário | Dado | Quando | Então |
|---|---|---|---|---|
| C1 | Registrar nova EBD | Usuário com perfil (EBD_SECRETARY ou superior) | Não existe sessão para unidade+data e toca em “Registrar nova EBD” | Cria EbdSession; fluxo de inclusão de classes inicia |
| C2 | Catálogo de classes oficial | Unidade com classes habilitadas em class_ref | Usuário abre criação de sessão | Sistema lista todas as classes habilitadas da igreja |
| C3 | Pré-seleção pela última EBD | Unidade com EBD anterior | Usuário cria nova EbdSession | Classes usadas na última EBD aparecem pré-selecionadas |
| C4 | Ajuste manual da seleção em lote | Lista de classes carregada | Usuário marca/desmarca classes | Sessão mantém somente classes selecionadas |
| C5 | Sessão sem EBD anterior | Unidade sem sessão anterior | Usuário cria nova EbdSession | Nenhuma classe vem pré-selecionada; todas habilitadas continuam disponíveis |
| C6 | Responsáveis da sessão | Usuários elegíveis na igreja | Usuário seleciona responsáveis | EbdSession.principals[] recebe múltiplos UIDs elegíveis |
| C7 | Classes como subcoleção | EbdSession criada com classes | Persistência no Firestore | Lessons em ebds/{sessionId}/lessons/{lessonId} |
| C8 | Sem formulário detalhado da classe na criação | Sessão em criação (create_ebd_session) | Usuário seleciona classes | Sistema não exibe formulário operacional por classe nesse momento |
| C9 | Lesson mínima na criação | Classe selecionada na criação de sessão | Sessão é salva | Lesson nasce com dados mínimos da classe e status=CREATED |
Ação separada de preenchimento por classe
Section titled “Ação separada de preenchimento por classe”| ID | Cenário | Dado | Quando | Então |
|---|---|---|---|---|
| CL1 | Sessão obrigatória | Não existe sessão para a data/unidade | Usuário tenta preencher classe | Operação negada com orientação para criar sessão |
| CL2 | Professor preenche sua classe | Sessão existente e professor vinculado | Entra no fluxo de classe | Pode editar dados da classe |
| CL3 | Assistente preenche sua classe | Sessão existente e assistente vinculado | Entra no fluxo de classe | Pode editar dados da classe |
| CL4 | Classe fora de escopo para edição | Sessão existente, sem vínculo com a classe selecionada | Tenta salvar preenchimento | Operação negada até vínculo aprovado |
| CL5 | Combo de classes com visão completa da sessão | Sessão existente com várias classes | Usuário abre ação de classe | Combo lista todas as classes da sessão, independentemente de vínculo |
| CL6 | Metadados e responsáveis por classe | Classe selecionada no fluxo de classe | Sistema carrega classe | Exibe nome, descrição e responsáveis vinculados (professor/assistentes) |
| CL6b | UI — professores e assistentes separados | Lesson com teacherIds/assistantIds | Usuário no fluxo Preencher classe da sessão | Combo apenas com professores da lesson + opção ”— Nenhum —”; Assistentes em chips apenas com IDs de assistantIds/monitorId (sem lista unificada) |
| CL6c | Seleção de classe antes do formulário | Sessão carregada com várias lessons | Combo Classe vinculada inicia em “Selecione a classe” | Dados operacionais (professor/assistentes, formulário da lesson) só aparecem após escolher uma classe |
| CL6d | Calendário da data EBD | Usuário toca na data | Abre CalendarDatePicker (domingos) | Ao tocar num domingo válido, fecha o diálogo e confirma a data (sem botão OK) |
| CL6e | Vínculo bloqueia edição de papéis na lesson | Usuário já está em teacherIds/assistantIds | Tela de preenchimento | Combos professor/assistente visíveis porém bloqueados (AbsorbPointer) com mensagem explicativa |
| CL6f | Status não operacional | notHeldToday ou notExists | Usuário altera status no card da lesson | Quantidades (alunos, visitantes, etc.) e editora/revista bloqueados e zerados/limpos |
| CL7 | Sugestão de andamento no preenchimento | Lesson recém-criada com status=CREATED | Professor/assistente abre a classe para preencher | Status operacional é sugerido como IN_PROGRESS |
| CL8 | Solicitação de adesão à classe | Usuário operacional sem vínculo na classe selecionada; tem EBD_TEACHER e/ou EBD_ASSISTENT APPROVED no perfil | Marca checkbox(es) conforme papel desejado (pré-seleção pelo activeRole quando aplicável) e envia pedido | Uma solicitação = um requestedRole (TEACHER ou ASSISTANT); sem papel aprovado correspondente, UI orienta e botão desabilitado |
| CL9 | Aprovação de adesão por professor vinculado | Pedido pendente de adesão como assistente | Professor já vinculado na classe aprova | Solicitante passa a constar em assistantIds / vínculo de assistente |
| CL10 | Aprovação de adesão por governança local (mesma igreja) | Pedido pendente (professor ou assistente) | Usuário com EBD_SUPERINTENDENT ou LOCAL_SECRETARY aprovado no perfil e mesma unitId da sessão/classe | Solicitante passa a constar nos vínculos da classe |
| CL10b | Aprovação de adesão por admin do ministério | Pedido pendente (professor ou assistente) | Usuário com MINISTRY_ADMIN ou PLATFORM_ADMIN aprovado no perfil e mesmo ministryId da lesson | Solicitante passa a constar nos vínculos da classe |
| CL11 | Rejeição de adesão | Pedido pendente de adesão | Aprovador rejeita | Pedido fica rejeitado e não libera preenchimento |
| CL12 | Assistente salva sem professor na lesson | Sessão gravável; assistente vinculado (assistantIds/monitorId); teacherIds/teacherId vazios ou incompletos | Salva preenchimento da classe | Permitido — escopo exige apenas vínculo do ator com a lesson; não exige o outro papel preenchido |
| CL13 | Professor salva sem assistentes na lesson | Sessão gravável; professor vinculado (teacherIds/teacherId); assistentes vazios | Salva preenchimento da classe | Permitido — idem CL12 |
Regra explícita — quem aprova vinculação à classe (CLASS_MEMBERSHIP_REQUEST)
Section titled “Regra explícita — quem aprova vinculação à classe (CLASS_MEMBERSHIP_REQUEST)”Escopo: ministryId da lesson = ministryId do aprovador. A igreja é a unitId da sessão EBD (ou da lesson, quando preenchida).
| Papel solicitado na adesão | Pode aprovar |
|---|---|
| ASSISTANT (assistente de classe) | (1) Qualquer professor já vinculado à lesson (teacherIds / teacherId); (2) EBD_SUPERINTENDENT ou LOCAL_SECRETARY com assignment APPROVED e mesma unitId da ocorrência; (3) MINISTRY_ADMIN ou PLATFORM_ADMIN com assignment APPROVED (âmbito do ministério). |
| TEACHER (professor) | (1) Não depende de outro professor vinculado; (2) EBD_SUPERINTENDENT ou LOCAL_SECRETARY mesma igreja (unitId); (3) MINISTRY_ADMIN / PLATFORM_ADMIN como acima. |
A autorização de aprovação usa role_assignments com status APPROVED, não apenas o active_role exibido na sessão — assim um usuário com superintendência aprovada continua podendo aprovar mesmo que o papel ativo operacional seja outro (ex.: assistente).
Fases do relatório
Section titled “Fases do relatório”Fonte de verdade (runtime atual): CREATED -> IN_PROGRESS -> CONCLUDED -> CLOSED.
Mapeamento legado de nomenclatura:
PREENCHIMENTO~CREATED/IN_PROGRESSREVISAO~IN_PROGRESSCONCLUIDO~CONCLUDEDENVIADO/APROVADO~CLOSED
| ID | Cenário | Dado | Quando | Então |
|---|---|---|---|---|
| F1 | Iniciar preenchimento | Sessão em CREATED com dados mínimos | Usuário autorizado inicia edição | Sessão vai para IN_PROGRESS |
| F2 | Concluir | Sessão em IN_PROGRESS com classes preenchidas | Usuário autorizado conclui | Sessão vai para CONCLUDED |
| F3 | Fechar envio | Sessão em CONCLUDED e usuário com escopo de envio | Usuário fecha relatório | Sessão vai para CLOSED |
| F4 | Bloqueio pós-fechamento | Sessão em CLOSED | Papel operacional tenta editar | Backend bloqueia edição |
| F5 | Reabertura controlada | Sessão em CLOSED | Governança autoriza reabertura | Sessão volta para IN_PROGRESS |
| F6 | Adesão bloqueada em fase final | Sessão em CLOSED | Usuário solicita adesão de classe | Backend rejeita solicitação |
| F7 | Revisão de adesão bloqueada em fase final | Sessão em CLOSED | Aprovador tenta aprovar/rejeitar adesão | Backend rejeita operação |
Diagnóstico de acesso (403 / matriz)
Section titled “Diagnóstico de acesso (403 / matriz)”Dados no perfil (Firestore users/{email}): conferir status, ministry_id, active_role, primary_role, role_assignments (cada item com roleId/role_id e status).
Regra do gateway para a matriz (process-user-action.ts, resolveActorRoleForAccess): ordem active_role → primary_role → primeiro item APPROVED na lista role_assignments → fallback papel no token. A matriz usa esse papel contra resourceId/actionId da ação (ex.: USER_EBD_LESSONS_LIST_BY_SESSION → LESSON / FILL_CLASS_REPORT / READ).
Logs no Cloud Functions (prefixo fixo; correlacionar com meta.request_id do POST):
[AccessDebug][<request_id>] resolveActorRole ...— se o ministério da conta bate com o esperado,statusda conta, lista de papéis aprovados, origem do papel (activeRole|primaryRole|firstApprovedAssignment| fallback token).[AccessDebug] assertMinistryAccess DENY ...— sem papel resolvido, ou matriz negou comevalCode/evalSource/matchedRole(viaresolveAccessLevel).
No app (HTTP ≥ 400): repositórios HTTP de sessão e lesson anexam [FORBIDDEN_ACCESS_LEVEL] (ou outro error.code do JSON) à mensagem, para ver na UI sem inspecionar o Network.
Escopo em USER_EBD_SESSION_UPDATE (gateway): autorização de escrita na sessão para perfil operacional deve considerar se o account.id está vinculado como professor ou assistente em qualquer lesson da subcoleção ebds/{sessionId}/lessons — não apenas uma amostra arbitrária de um documento. Implementação em process-user-action.ts (handleEbdSessionUpdate): percorre todas as lessons da sessão antes de decidir FORBIDDEN_CLASS_SCOPE.
Ordem de persistência no app (preenchimento por classe): no fluxo fill_ebd_class_report, gravar primeiro a lesson alvo (USER_EBD_LESSON_*) e em seguida a sessão (USER_EBD_SESSION_UPDATE), para que totais/agregados da sessão não bloqueiem o salvamento dos dados operacionais da classe quando o escopo já é válido na lesson.
Responsabilidade de inclusão
Section titled “Responsabilidade de inclusão”| ID | Cenário | Dado | Quando | Então |
|---|---|---|---|---|
| R1 | Inclusão pelo criador | Nova EbdSession | Usuário cria sessão | As classes incluídas são definidas pelo criador por seleção em lote |
| R2 | Fonte de classes | Classes da igreja habilitadas | Criação de sessão | Classes são lidas de platform/ministrys/{ministryId}/data/class_ref |
Escopo por vínculo e papel
Section titled “Escopo por vínculo e papel”| ID | Cenário | Dado | Quando | Então |
|---|---|---|---|---|
| S1 | Assistente preenche classe vinculada | Usuário assistente da classe | Tenta preencher/revisar/concluir | Permitido |
| S2 | Assistente fora da classe | Usuário assistente não vinculado à classe | Tenta preencher/revisar/concluir | Negado |
| S3 | Professor preenche classe vinculada | Usuário professor da classe | Tenta preencher/revisar/concluir | Permitido |
| S4 | Superintendente envia igreja de responsabilidade | Usuário superintendente da igreja | Tenta enviar relatório da igreja | Permitido |
| S5 | Superintendente fora da igreja | Usuário superintendente sem vínculo com a igreja alvo | Tenta enviar | Negado |
| S6 | Governança devolve/aprova | Secretaria geral/coordenação | Tenta devolver/aprovar | Permitido |
| S7 | Secretaria local envia relatório | Usuário secretaria local da igreja de atuação | Tenta enviar relatório da igreja | Permitido |
Totais e consistência
Section titled “Totais e consistência”| ID | Cenário | Dado | Quando | Então |
|---|---|---|---|---|
| T1 | Totais gerais derivados | Sessão com múltiplas classes | Salva sessão | Totais da igreja = soma das classes |
| T2 | Sem campo manual conflitante | Usuário altera dados de classes após cálculo anterior | Recalcula totais | Totais gerais atualizados automaticamente |
| T3 | Professor com vínculo obrigatório na classe selecionada | Usuário professor sem vínculo na classe selecionada | Tenta salvar preenchimento da classe | Negado com erro de consistência |
| T4 | Assistente com vínculo obrigatório na classe selecionada | Usuário assistente sem vínculo na classe selecionada | Tenta salvar preenchimento da classe | Negado com erro de consistência |
Quadro único — ações x fases x papéis
Section titled “Quadro único — ações x fases x papéis”Legenda:
SIM= permitidoNAO= não permitidoCOND= permitido com condição de escopo/fase
| Ação | Fase alvo | Assistente (classe vinculada) | Professor (classe vinculada) | Superintendente (igreja responsável) | Secretaria local (igreja de atuação) | Secretaria geral / Coordenação ministério | Condição principal |
|---|---|---|---|---|---|---|---|
| Preencher dados da classe | CREATED / IN_PROGRESS | SIM | SIM | SIM | SIM | SIM | Classe dentro do escopo do usuário |
| Revisar dados da classe | IN_PROGRESS | SIM | SIM | SIM | SIM | SIM | Classe dentro do escopo do usuário |
| Concluir questionário da classe | CONCLUDED | SIM | SIM | SIM | SIM | SIM | Vínculo obrigatório do papel com ao menos 1 classe |
| Fechar relatório da igreja | CLOSED | NAO | NAO | SIM | SIM | SIM | Sessão em CONCLUDED e escopo válido |
| Reabrir fase antes do fechamento final | IN_PROGRESS / CONCLUDED | COND | COND | COND | COND | COND | Permitido conforme escopo e regra de governança |
| Editar após fechamento | CLOSED | NAO | NAO | NAO | NAO | COND | Somente por reabertura explícita de governança |
| Solicitar adesão | CREATED / IN_PROGRESS / CONCLUDED | SIM | SIM | SIM | SIM | SIM | Bloqueado em CLOSED |
| Aprovar/rejeitar adesão | CREATED / IN_PROGRESS / CONCLUDED | COND | COND | COND | COND | COND | Ver tabela “Quem aprova vinculação à classe”: prof. vinculado (só assistente), sup/sec local mesma unit, min./plat. admin |
Notas obrigatórias:
- Após
CLOSED, papéis operacionais não podem mais alterar o relatório. - Reabertura de edição ocorre por governança (retorno para
IN_PROGRESS). - Totais gerais da igreja são sempre derivados da soma das classes.
Fluxograma completo do ciclo de vida EBD
Section titled “Fluxograma completo do ciclo de vida EBD”flowchart TD A[Inicio] --> B{Sessao EBD existe para unidade/data?} B -- Nao --> C[Criar sessao de EBD] C --> C1[Definir classes da sessao] C1 --> C2[Definir responsaveis EBD presentes] C2 --> D[Fase: CREATED] B -- Sim --> D
D --> E[Professor/Assistente preenchem classes vinculadas] E --> F{Dados minimos por classe ok?} F -- Nao --> E F -- Sim --> G[Fase: IN_PROGRESS]
G --> H{Revisao aprovada no escopo?} H -- Nao --> D H -- Sim --> I[Fase: CONCLUDED]
I --> J{Ator pode fechar?} J -- Superintendente ou Secretaria Local --> K[Fase: CLOSED] J -- Secretaria Geral/Coordenacao --> K J -- Nao --> I
K --> L{Governanca ministerial decide} L -- Reabrir --> M[Fase: IN_PROGRESS] M --> D L -- Manter fechado --> N[Fase: CLOSED]
K --> O[Operacional bloqueado para editar] N --> P[Fim]Critérios de aceite (resumo)
Section titled “Critérios de aceite (resumo)”- Ação “Preencher relatório de EBD” filtrada por regra híbrida (
minRole+ matriz READ/FULL). - Navegação para EbdReportPage funcional.
- Seleção de igreja (dropdown) com igreja do perfil pré-selecionada.
- Seleção de data (apenas domingos).
- GetOrCreateEbdSession: busca por unitId+date ou cria nova sessão.
- Coleção
platform/ministrys/{id}/data/ebdsno Firestore. - Catálogo de classes em
platform/ministrys/{id}/data/class_ref(1 documento por classe, comclassName,classDescription,enabled). - Classes como subcoleção:
ebds/{sessionId}/lessons/{lessonId}. - Inclusão pelo criador: Quem cria a sessão define quais classes incluir por seleção em lote.
- Sugestão na criação: Ao criar, classes da última EBD (mesma unidade) vêm pré-selecionadas, mantendo todas as demais visíveis.
- Criação sem formulário operacional: na criação de sessão não há edição detalhada da classe (totais, observações, status operacional).
- Lesson mínima na criação: classes entram com payload mínimo e
status=CREATED. - Vínculo por classe na sessão: na gestão da sessão, cada classe pode ter múltiplos professores e múltiplos assistentes; atribuição é opcional.
- Visão no preenchimento: no fluxo de classe, o usuário vê todas as classes da sessão; vínculo controla permissão de edição/salvamento por classe.
- Adesão à classe: usuário operacional pode solicitar adesão por classe (
TEACHER/ASSISTANT). Na UI, só aparecem opções de papel aprovadas no perfil (EBD_TEACHER/EBD_ASSISTENTemrole_assignments); pré-seleção alinhada aoactiveRolequando for um desses. Aprovação conforme tabela “Quem aprova vinculação à classe” (professor vinculado para assistente; superintendente ou secretário local da mesma igreja; administrador do ministério ou da plataforma; uso derole_assignmentsAPPROVED). - Pendências comuns: solicitações de cargo e de adesão à classe compartilham a mesma lista de pendências (item tipado).
- Responsáveis da sessão: multi seleção de pessoas elegíveis (
EBD_SUPERINTENDENT,LOCAL_PASTOR,ASSISTANT_LOCAL_PASTOR,LOCAL_SECRETARY,EBD_SECRETARY). - Formulário da sessão exibe
Tipo(classes de hoje),Clima,Temperatura,Observação; não exibeStatusnem totais gerais. - Preenchimento operacional: no fluxo
fill_ebd_class_report, o status da classe é sugerido comoIN_PROGRESS. - Layout: totais de participantes no
LessonFormCardem coluna (um campo abaixo do outro). - Totais gerais da igreja derivados da soma das classes.
- Regras de fase e bloqueio pós-envio aplicadas.
- Regras de escopo por vínculo/papel aplicadas.
- Ações separadas de sessão e classe aplicadas no fluxo.
- Cenários C1–C9, CL1–CL13 e CL6b–CL6f (UI/fluxo preenchimento), F1–F7, S1–S7, T1–T4 e R1–R2 cobertos por testes ou validação manual até automação.
Pendente (fase futura)
Section titled “Pendente (fase futura)”- Automação completa dos cenários de fase com auditoria.
- UI dedicada para devolução/aprovação por governança.