Refatoração do domínio Simulado — Resumo executivo #61
Replies: 1 comment
-
Pendências e Docs FuturosPropósito: documento vivo com tudo que está em aberto na série de docs do domínio Simulado — itens que precisam virar doc novo, lacunas dentro de docs existentes, decisões em aberto, tech debt identificado. Como usar:
Última atualização: 2026-05-26 Visão geral da sérieOrdem de execução atual:
Itens previstos sem doc ainda:
1. Docs ainda a escrever1.1 Permissões do cursinho — modelo e catálogoPor que: vários docs (6 introduz Escopo proposto:
Bloqueado por: nada — pode entrar a qualquer momento. Bloqueia (parcialmente):
Posição na série: seria #8 se entrar após os atuais, ou inserir antes de #6 e renumerar (mais coerente conceitualmente, mais trabalhoso pra renumeração — decidir na hora). Status: planejado, sem prazo. 1.2 Histórico/relatório do cursinhoPor que: a tela de Provas do Cursinho (doc 6) e a leitura de Cartão de Resposta (doc 7) só fazem sentido pleno se o cursinho consegue ver o desempenho agregado dos alunos. Sem esse doc, o ciclo "criar prova → aplicar → ver resultado" fica incompleto. Provavelmente o objetivo final de toda essa série de docs. Escopo proposto:
Bloqueado por: doc 6 (provas-cursinho — escopo de cursinho), parcialmente doc 7 (cartão alimenta o mesmo Historico mas não bloqueia leitura). Bloqueia: nenhum doc, mas é o objetivo final do ciclo. Status: já no planejamento da equipe, conforme conversa de 12/2025. Doc não vai ser escrito por mim nesta série; espaço reservado aqui pra referência. 1.3 UI de atribuição de matrículaPor que: doc 7 (Cartão de Resposta) adiciona Escopo proposto:
Bloqueado por: doc 7 (precisa do campo Bloqueia: usabilidade completa do doc 7. Tecnicamente é parte do ciclo. Posição: poderia ser doc separado (#9 ou similar) OU seção/anexo dentro de doc 7. Decisão pendente. Status: lacuna conhecida, depende do doc 7. 2. Lacunas em docs existentesItens deixados em aberto dentro dos docs escritos. Quando o doc dependente for escrito ou a decisão for tomada, atualizar o doc original. 2.1 Tech debt —
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Refatoração do domínio Simulado — Resumo executivo
Para: apresentação ao time
De: Fernando Almeida
Data: 2026-05-26
Documento curto pra discussão em reunião. Cada item aqui tem doc detalhado próprio na mesma pasta. Use esse como mapa.
Por quê
Objetivo final: permitir que o cursinho parceiro consiga criar sua própria prova/simulado, aplicar (online ou em papel via cartão), receber as respostas dos estudantes, e ver o desempenho deles.
Tudo o que está nessa série de docs é caminho pra esse objetivo. Quebrei em 7 entregas porque cada uma é um PR/release independente e algumas têm dependências entre si.
Os 10 docs em uma tabela
[categoria-simulado.md](https://github.com/orgs/vcnafacul/discussions/65)TipoSimulado→Categoria. Embuteexameecustomna categoria. Refatora o dispatcher de factories.unificacao-simulados-provas.mdDashSimuladoadmin. Vista de simulados passa pra dentro doShowProva. Remove permissãocriarSimulado.crud-categoria-simulado.mdprova-customizada-factory.mdCustomProvaFactorypra criar provas custom (1 simulado por prova). AdicionacriadorIdecursinhoIdem Prova/Simulado.simulado-janela-disponibilidade.mddisponivelDe/disponivelAteno simulado. Janela temporal de disponibilidade.provas-cursinho.mdcursinhoId). PermissõesvisualizarProvasCursinhoecadastrarProvasCursinho.cartao-resposta.mdms-omrPython. Matrícula emStudentCourse.simulados-compartilhados.mdmainSimulate.questoes-em-multiplas-provas.mdnumerosai deQuestaoe vai pro relacionamento (Prova.questoeseSimulado.questoesviram arrays de{questao, numero}). Habilita reuso de questão entre provas.duplicacao-questoes.mdQuestao.origem(de onde veio) eQuestao.copias[](filhas que nasceram dela).Decisões transversais (atravessam vários docs)
Vale alinhar com o time logo de cara:
TipoSimuladoviraCategoriaem todas as camadas. Renomeio massivo: schema, módulo, repository, DTOs, services, UI.Categoriacarregaexame(ref) ecustom(bool). AProvaaponta praCategoria(mantém ref). Não tem maisProva.exameouProva.customseparados.Categoria.selecionavel: booleandistingue categorias que aparecem no select de criação de prova (Enem Dia 1, Enem Dia 2, Personalizadas) das que são só classificador interno (Linguagens, Matemática, etc., usadas pelas factories ENEM).criadorIdem toda prova (não só custom). Vem do JWT do usuário logado.cursinhoIdpersistido sempre —nullno fluxo admin, preenchido no fluxo cursinho.prova.categoria.custompra decidir CustomProvaFactory vs ENEM, eprova.categoria.exame.nome + prova.anopra escolher a versão da factory ENEM.criarSimuladoé removida — com cuidado de migração.RolesLabelemclient-vcnafacul/src/enums/roles/roles.tslinhas 43-47). Quem hoje marca "Visualizar Simulados" no painel está marcandocriarSimulado: trueno banco. Antes de dropar a coluna, migrar: pra cada role comcriar_simulado = true, garantirvisualizar_provas = true. Senão admins perdem acesso aos simulados. Detalhes em doc 2 §8.1.visualizarSimuladonão existe e não deve ser criada — verificado por grep com variações.visualizarProvas(admin) evisualizarProvasCursinho(cursinho) já cobrem, porque a visualização dos simulados acontece dentro doShowProva. Registrado em doc 2 §8.2 pra evitar que alguém crie essa permissão por reflexo no futuro.<acao><Recurso>Cursinho(visualizarProvasCursinho,cadastrarProvasCursinho, futurasgerenciarRespostasCursinho).Fluxo simplificado de implementação
A ordem certa minimiza retrabalho. Cada doc tem seu próprio plano de implementação detalhado; aqui é o sumário.
Etapa 1 — Fundação (doc 1)
Renomeio + remodelo.
TipoSimulado/→Categoria/no ms-simulado (PR só de naming, build verde antes de mexer em comportamento).exame,custom,selecionavel,descricaoemCategoria.Prova.tipo→Prova.categoria. RemoverProva.exame.Simulado.tipo→Simulado.categoria.ProvaFactory.getFactory(prova).getTipos→getCategorias,ITipoSimulado→ICategoria, ajuste em ~6 arquivos que leemsimulado.tipo.x.Etapa 2 — Limpeza de UX e cleanup de permissões (doc 2)
Antes do CRUD, porque adiciona um slot pra ele.
DashSimulado(arquivo e rota).ShowProva(stateview: 'details' | 'simulados').getProvaById) ao abrir modal.criarSimuladoem 14 lugares (entity, DTO, service, seeds, frontend, modal de role, rotas).DELETE /mssimulado/simulado/:idpracadastrarProvas.Etapa 3 — CRUD de Categoria (doc 3) — pode rodar em paralelo com 4 e 5
Plugga no slot da etapa 2.
ManageCategoriasna DashProva (acessado pelo botão "Gerenciar Categorias").PATCHnão existe,DELETEenriquecido comcountByCategoriae bloqueio em uso.Etapa 4 — Factory Custom (doc 4)
Adiciona criadorId/cursinhoId — pré-requisito pro cursinho (doc 6) e cartão (doc 7).
CustomProvaFactoryque cria 1 simulado por prova custom.criadorIdem Prova (todas as provas, sempre setado) e Simulado (propagado).cursinhoIdem Prova/Simulado (sempre persistido, null no admin).NewProvamodal aprende a setar nome livre + PDF opcional quando categoria custom.ProvaService.executeSync) pra não rodar string matching ENEM em provas custom.Etapa 5 — Janela de disponibilidade (doc 5) — independente, pode entrar a qualquer momento depois de 1+2
Feature isolada.
disponivelDe/disponivelAteemSimulado(nullable).!bloqueado && (de==null || agora>=de) && (até==null || agora<=até).PATCH /v1/simulado/:id/disponibilidade.getAvailablee gate emgetToAnswer.ShowProva(datetime-local).Etapa 6 — Tela de Provas do cursinho (doc 6)
Depende de 1, 2 e 4.
pages/partnerPrepProvas/(espelha DashProva)./mssimulado/cursinho/prova/*).cursinhoIdnoGET /v1/provado ms-simulado.visualizarProvasCursinho,cadastrarProvasCursinho).cursinhoIdresolvido via Collaborator +criadorId.Etapa 7 — Cartão de resposta (doc 7)
O passo mais complexo. Depende de 1, 2, 4, 6.
StudentCourse.matricula(8 dígitosYYYY0001, unique por cursinho).HistoricoganhaimageCartaoR2Keyeorigem.ms-omr(Python + FastAPI + OMRChecker).POST /mssimulado/cartao-resposta) com frontend orquestrando serial.Etapa 8 — Compartilhamento de simulados (doc 8)
Depende de 1, 4, 6. Pode rodar em paralelo com 7.
SimuladoFavoritono ms-simulado:(cursinhoId, simulado, favoritadoPor)única.pages/partnerPrepProvas.pages/mainSimulate— vê próprios do cursinho + favoritados.cadastrarProvasCursinho,visualizarProvasCursinho).Etapa 9 — Questão em múltiplas provas (doc 9) — Release A.5
Refactor profundo. Depende de 1 e 2. Decidido executar entre Fundação e Catálogo Gerenciável.
Questaoperdeprovaenumero. Vira só "questão como ente" (conteúdo + classificação + status + estatísticas globais).Prova.questoeseSimulado.questoesviram arrays de subdocumentos{ questao: ref, numero: number }.frente1como tiebreaker.getMissingNumbers,verifyNumberProva,EnemService.validate) migra pro novo modelo preservando comportamento.Etapa 10 — Duplicação de questão com linhagem (doc 10)
Depende de doc 9 finalizado. Roda após a Release A.5 completar.
Questao:origem: ref<Questao> | null(de onde veio) ecopias: ref<Questao>[](filhas).POST /v1/questao/:id/duplicarcria novaQuestaoeditável independentemente, com lastro.Pending, com estatísticas zeradas, compartilhando refs de imagens com a original.O que NÃO está sendo feito nesta série
Pra alinhar expectativa:
StudentCourse.matriculaé criado no doc 7, mas a UI de atribuição é doc separado.Decisões que precisam de OK do time
Pontos onde vale conferir alinhamento antes de codar:
TipoSimulado → Categoria— afeta dezenas de arquivos. Vale fazer em PR único de naming.alterarPermissao). Cursinho não tem acesso ao CRUD (admin gerencia o catálogo global)."{Prefixo} {qtd}q {duracao}min"(ex.:"Personalizado 30q 60min"). Admin pode passar prefixo opcional.Prova.custom: booleanfoi descartado em favor deprova.categoria.custom(Leitura B). Uma fonte de verdade, sem snapshot.cursinhoIdsempre persistido, mesmo no fluxo admin (semprenull). Facilita o dia em que outros fluxos forem criados.criarSimulado— confirmar com produto/operações se a estratégia "quem tinha criarSimulado=true ganha visualizarProvas=true automaticamente, e depois a coluna é dropada" está OK. Comunicar admins via release notes: "A permissão 'Visualizar Simulados' virou 'Visualizar Provas'".Sequência de releases sugerida
Cada bullet é um conjunto de PRs que faz sentido ir junto:
Releases A, B, C fazem sentido próximas (não há valor pra usuário até a C). A.5 é tech-debt-buster + enabler; se postergar, retrabalho nos PRs subsequentes. D pode ir entre qualquer ponto após A. E pode ir após C. F precisa de C+E. G precisa de C+E e pode rodar em paralelo com F. H precisa de A.5 finalizada e pode ir em qualquer ponto depois.
Material de apoio
docs/pendencias.md— meta-doc vivo com tudo que está em aberto.Qualquer dúvida me chama — escrevi todos os 7 docs, então tenho contexto completo.
Beta Was this translation helpful? Give feedback.
All reactions