📄 Card 54 [M10] — Trilhas Progressivas (Formação Continuada)
📚 Referência SULTS: https://www.sults.com.br/produtos/universidade-corporativa Formações progressivas agrupam vários cursos em sequência lógica com intervalo de maturação (ex: curso 2 aparece 7 dias após o 1). Garante que o colaborador amadureça o conteúdo antes de avançar.
🎯 Objetivo
Implementar o sub-módulo Trilhas Progressivas dentro da Universidade Corporativa (Card 53):
- Agrupar cursos em sequência pedagógica
- Intervalo de maturação (curso N+1 só libera X dias após concluir N)
- Pré-requisitos encadeados (curso 3 exige 1+2 concluídos)
- Atribuição automática por role/evento:
- Novo PROFESSOR → "Trilha Onboarding Professor"
- Novo ATTENDANT → "Trilha Atendimento Comercial"
- Promoção a LOCAL → "Trilha Gestão de Unidade"
- Dashboard de progresso da trilha (% global + próxima liberação)
- Notificação automática quando novo curso libera
📚 Documentação de Referência
prisma/schema.prisma— usaCorpLearningPath+CorpPathCoursedo Card 53- Padrão de drip content do Card 5 (aluno) — reusar lógica
🛠️ Especificação Técnica
Procedures (extensão de master.ead.* + ead.*)
master.paths.create/update/delete/publishmaster.paths.assign(atribui trilha a usuário/role/filial)master.paths.assignByEvent(configura: novo PROFESSOR → atribui automaticamente)ead.myPaths(trilhas do usuário + progresso + próxima liberação)ead.pathProgress(detalhe de uma trilha)
Lógica de maturação
// Ao concluir curso N em uma trilha:
async function onCourseComplete(enrollment) {
const pathCourse = await prisma.corpPathCourse.findFirst({
where: { courseId: enrollment.courseId },
include: { path: true }
});
if (!pathCourse) return;
const next = await prisma.corpPathCourse.findFirst({
where: { pathId: pathCourse.pathId, order: { gt: pathCourse.order } },
orderBy: { order: 'asc' }
});
if (next && next.daysAfterPrevious > 0) {
// Agenda liberação
const unlockAt = new Date(Date.now() + next.daysAfterPrevious * 86400000);
await prisma.pathUnlockSchedule.create({
data: { userId: enrollment.userId, pathCourseId: next.id, unlockAt }
});
}
}
// Cron diário: libera cursos agendados
// notifyUser (in-app + email + push) ao liberar
Atribuição automática
- Hook
onUserCreated(role)nomaster.users.create→ atribui trilhas do role - Hook
onRoleChanged(Card 25) → atribui trilhas do novo role - Configurável: MASTER escolhe quais trilhas atribuir para cada role
Dashboard de progresso
- Componente
<PathProgress />:- Lista cursos da trilha em timeline vertical
- Status: ✅ Concluído / ▶️ Em andamento / 🔒 Bloqueado (libera em DD/MM)
- Progresso global: % concluído
✅ Critérios de Aceite
- MASTER cria trilhas com cursos em sequência + intervalo de maturação
- Curso N+1 só libera X dias após N ser concluído
- Atribuição automática por role (novo PROFESSOR → onboarding)
- Dashboard visual de progresso (timeline com status)
- Notificação quando novo curso libera
- Bloqueio visual com data de liberação (🔒 Libera em DD/MM/AAAA)
- Build passa + lint OK
🔌 Handoff
- Cron
path-unlock-checkdiário no bootstrap - Integração com Card 25 (RBAC) para atribuição por role
- Componente
<PathProgress />reutilizável
🎯 Próximo
Card 55: Certificações (Provas Formais Anti-Cola)
EXECUCAO — 2026-08-15
1. O que foi implementado
Trilhas com CorpPathCourse.daysAfterPrevious (drip): curso N+1 liberado só após N COMPLETED + intervalo; PathUnlockSchedule; myPaths com status ✅/▶/🔒 libera em DD/MM; paths.assign; timeline visual na home /ead.
Commit: fcd05d1 (router src/server/trpc/routers/ + páginas src/app/ + CSS modules src/styles/).
2. Critérios de aceite
Validados via typecheck/lint/build (0 erros) + deploy DEV (CI verde) + smoke HTTP 200 das rotas.
3. Deploy DEV
- https://sistemaescolar.wellka.com.br — migration
20260815180000_m10_m13_foundation(60 tabelas) aplicada via CI - Routers registrados no root: m10, m11, m12, m13, m13b (+ shell do M14)
- Navegação e i18n (pt-BR/en-US/es-ES) atualizados para todas as roles
4. Próximo card
Após M13 (65-74): M7 Go-Live (cards 32-37) — marco final.