Learning Path Patterns
Padrao de Trilhas de Aprendizado para Plataforma B2B de treinamento técnico corporativo
Versao: 1.0.0 Ultima Atualizacao: 2025-11-22 Target: Hub MVP (US-044) Projeto: Plataforma B2B de treinamento técnico corporativo - Plataforma B2B de Treinamento Tecnico
Indice
- Overview
- Conceito Fundamental: Curso vs Caminho
- Schema de Dados
- Padroes de UI/UX
- Implementacao de Referencia
- Como Adicionar Novos Caminhos
- Antipadroes a Evitar
- Exemplos do Projeto
- Referencias
Overview
Esta skill documenta o padrao correto para modelar e implementar Caminhos de Aprendizado (Learning Paths) no sistema Plataforma B2B de treinamento técnico corporativo.
O que voce vai aprender:
- Diferenca entre Area de Estudo (curso) e Caminho Proposto (trilha)
- Como estruturar dados para caminhos escalavel
- Padroes de UI para mostrar disponibilidade de cursos
- Navegacao correta: Hub -> Caminho -> Curso -> Aula
- Como adicionar novos caminhos sem duplicar dados
Por que esta skill e importante:
- Clareza conceitual: Evita confusao entre curso e trilha
- Escalabilidade: Mesmo curso pode estar em multiplos caminhos
- Manutencao: Atualizar curso atualiza todas as trilhas
- UX consistente: Usuario entende hierarquia intuitivamente
- MVP focus: Mostra apenas conteudo padronizado
Contexto da US-044: O Hub anterior mostrava 13 areas + flashcards soltos em "Caminhos". A US-044 simplificou para MVP: 1 Area (Bash) + 1 Caminho correto (sequencia de cursos).
Conceito Fundamental: Curso vs Caminho
ERRADO (antes da US-044)
Caminho de Aprendizado = Container de Flashcards
- Flashcard 1: "O que e variavel?"
- Flashcard 2: "Sintaxe de loop"
- ...
Problema: Mistura conceitos, nao referencia cursos reais
CORRETO (depois da US-044)
Area de Estudo (Curso):
- Entidade autocontida
- Tem: video, modulos, notas, flashcards
- Exemplo: Bash, C, Rust
Caminho Proposto (Trilha):
- Sequencia ordenada de CURSOS
- Referencia Areas de Estudo existentes (ou planejadas)
- Exemplo: "Desenvolvedor Backend" = Bash -> Linux -> Docker -> DevOps
Analogia do Design Pattern
Composite vs Entity Reference:
Entity (Area de Estudo):
{
id: "bash",
name: "Bash Shell Scripting",
modules: 16,
hours: 32,
flashcards: [...], // Dados REAIS aqui
sections: [...] // Conteudo REAL aqui
}
Composite (Caminho Proposto):
{
id: "backend-developer",
name: "Desenvolvedor Backend",
cursos: [
{ areaId: "bash", ordem: 1, disponivel: true }, // REFERENCIA
{ areaId: "linux", ordem: 2, disponivel: false }, // REFERENCIA
{ areaId: "docker", ordem: 3, disponivel: false } // REFERENCIA
]
}
Beneficio: Se bash for atualizado (mais modulos, novos flashcards), TODOS os caminhos que referenciam bash refletem automaticamente.
Schema de Dados
Schema de Caminho Proposto (caminhoExemploData.js)
export const caminhoExemplo = {
// Identificacao
id: 'backend-developer',
name: 'Desenvolvedor Backend',
icon: 'trilha',
description: 'Caminho proposto para dominar desenvolvimento backend...',
badge: 'exemplo', // 'exemplo' | 'popular' | 'novo' | null
// Sequencia ordenada de cursos (REFERENCIAS, nao dados duplicados)
cursos: [
{
ordem: 1, // Posicao na sequencia
areaId: 'bash', // Referencia a studyAreas.js
nome: 'Bash Shell Scripting', // Display name (pode ser diferente)
icone: 'terminal',
descricao: 'Fundamentos de linha de comando...',
modules: 16, // Estatisticas (sync com Area)
hours: 32,
disponivel: true, // Clicavel ou nao
destaque: 'Padrao de referencia' // Badge especial (opcional)
},
{
ordem: 2,
areaId: 'linux',
nome: 'Linux Fundamentals',
icone: 'linux',
descricao: 'Sistema operacional, administracao...',
modules: 12,
hours: 24,
disponivel: false, // "Em breve" badge
destaque: null
}
// ... mais cursos
],
// Estatisticas calculadas (getters)
get totalCursos() { return this.cursos.length; },
get cursosDisponiveis() { return this.cursos.filter(c => c.disponivel).length; },
get totalModules() { return this.cursos.reduce((sum, c) => sum + c.modules, 0); },
get totalHours() { return this.cursos.reduce((sum, c) => sum + c.hours, 0); },
get modulesDisponiveis() {
return this.cursos.filter(c => c.disponivel).reduce((sum, c) => sum + c.modules, 0);
},
get hoursDisponiveis() {
return this.cursos.filter(c => c.disponivel).reduce((sum, c) => sum + c.hours, 0);
}
};
// Exportar dicionario de caminhos
export const caminhosPropostos = {
'backend-developer': caminhoExemplo
};
Schema de Area de Estudo (studyAreas.js)
export const studyAreas = [
{
name: "Bash",
icon: "terminal",
description: "Shell scripting, automacao e linha de comando",
modules: 16,
hours: 32,
badge: "Integrado", // Status do sistema integrado
hasIntegratedApp: true, // Tem LearningSystem dedicado
key: "bash", // ID para navegacao
flashcards: [...] // Flashcards REAIS
}
];
Regra de Ouro:
studyAreas.jscontem dados REAIS (flashcards, metricas)caminhoExemploData.jscontem REFERENCIAS + metadados de ordenacao
Padroes de UI/UX
Padrao 1: Card de Caminho no Hub
// HubView.jsx - Secao de Caminhos Propostos
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{Object.values(caminhosPropostos).map(caminho => (
<div
key={caminho.id}
=> openLearningPath(caminho.id)}
className="bg-gradient-to-br from-purple-50 to-blue-50 rounded-xl p-6
shadow-lg hover:shadow-xl cursor-pointer transition-all"
>
<div className="flex items-center gap-3 mb-3">
<span className="text-2xl">{caminho.icon}</span>
<h3 className="text-lg font-bold text-slate-800">{caminho.name}</h3>
{caminho.badge && (
<span className="px-2 py-0.5 bg-purple-100 text-purple-600
text-xs rounded-full">{caminho.badge}</span>
)}
</div>
<p className="text-slate-600 text-sm mb-4">{caminho.description}</p>
{/* Estatisticas */}
<div className="flex gap-4 text-sm text-slate-500">
<span>{caminho.totalCursos} cursos</span>
<span>{caminho.totalModules} modulos</span>
<span>{caminho.totalHours}h</span>
</div>
</div>
))}
</div>
Padrao 2: Lista de Cursos no LearningPathView
// LearningPathView.jsx - Mostrar sequencia de cursos
<div className="space-y-4">
{path.cursos.map((curso, index) => (
<div
key={curso.areaId}
=> curso.disponivel && navigateToCourse(curso.areaId)}
className={`
flex items-center gap-4 p-4 rounded-lg border-2 transition-all
${curso.disponivel
? 'border-green-200 bg-green-50 hover:border-green-400 cursor-pointer'
: 'border-slate-200 bg-slate-50 cursor-not-allowed opacity-60'}
`}
>
{/* Numero da ordem */}
<div className={`
w-8 h-8 rounded-full flex items-center justify-center font-bold
${curso.disponivel ? 'bg-green-500 text-white' : 'bg-slate-300 text-slate-600'}
`}>
{curso.ordem}
</div>
{/* Info do curso */}
<div className="flex-1">
<div className="flex items-center gap-2">
<span>{curso.icone}</span>
<span className="font-medium">{curso.nome}</span>
{/* Badge de disponibilidade */}
{curso.disponivel ? (
<span className="px-2 py-0.5 bg-green-100 text-green-700
text-xs rounded-full">Disponivel</span>
) : (
<span className="px-2 py-0.5 bg-slate-100 text-slate-500
text-xs rounded-full">Em breve</span>
)}
{/* Destaque especial */}
{curso.destaque && (
<span className="px-2 py-0.5 bg-purple-100 text-purple-600
text-xs rounded-full">{curso.destaque}</span>
)}
</div>
<p className="text-sm text-slate-600 mt-1">{curso.descricao}</p>
</div>
{/* Metricas */}
<div className="text-right text-sm text-slate-500">
<div>{curso.modules} modulos</div>
<div>{curso.hours}h</div>
</div>
{/* Seta se disponivel */}
{curso.disponivel && (
<ChevronRight className="w-5 h-5 text-green-500" />
)}
</div>
))}
</div>
Padrao 3: Navegacao do Breadcrumb
Hub > Caminho: Desenvolvedor Backend
Hub > Caminho: Desenvolvedor Backend > Bash (curso)
Hub > Caminho: Desenvolvedor Backend > Bash > Aula 1.1
Implementacao:
// Breadcrumb para LearningPathView
<nav className="flex items-center gap-2 text-sm text-slate-600 mb-6">
<button => setCurrentView('hub')} className="hover:text-purple-600">
Hub
</button>
<ChevronRight className="w-4 h-4" />
<span className="text-slate-800 font-medium">
Caminho: {path.name}
</span>
</nav>
Implementacao de Referencia
Arquivo: src/data/caminhoExemploData.js
/**
* Caminho de Aprendizado Exemplo
*
* Este arquivo define o modelo correto para "Caminhos Propostos".
*
* CONCEITO:
* - Caminho Proposto = sequencia ordenada de CURSOS (Areas de Estudo)
* - NAO e um container de flashcards soltos
* - Cada curso referencia uma Area de Estudo existente (ou planejada)
* - Cursos tem ordem, disponibilidade e sao clicaveis quando disponiveis
*
* PADRAO:
* - Baseado no modelo Bash (bashLearningData.js) que e a referencia
* - Cada curso tem: ordem, areaId, nome, descricao, modules, hours, disponivel
*
* @see docs/backlog/ROADMAP.md - US-044
*/
export const caminhoExemplo = {
id: 'backend-developer',
name: 'Desenvolvedor Backend',
icon: 'trilha',
description: 'Caminho proposto para dominar desenvolvimento backend...',
badge: 'exemplo',
cursos: [
{
ordem: 1,
areaId: 'bash',
nome: 'Bash Shell Scripting',
icone: 'terminal',
descricao: 'Fundamentos de linha de comando, automacao e scripting robusto',
modules: 16,
hours: 32,
disponivel: true,
destaque: 'Padrao de referencia'
},
// ... mais cursos
],
// Getters para estatisticas
get totalCursos() { return this.cursos.length; },
get cursosDisponiveis() { return this.cursos.filter(c => c.disponivel).length; },
get totalModules() { return this.cursos.reduce((sum, c) => sum + c.modules, 0); },
get totalHours() { return this.cursos.reduce((sum, c) => sum + c.hours, 0); }
};
export const caminhosPropostos = {
'backend-developer': caminhoExemplo
};
export default caminhoExemplo;
Arquivo: src/components/LearningPathView.jsx (Essencia)
import { caminhosPropostos } from '../data/caminhoExemploData';
export function LearningPathView({ pathId, onBack, onCourseClick }) {
const path = caminhosPropostos[pathId];
if (!path) {
return <div>Caminho nao encontrado</div>;
}
const handleCourseClick = (curso) => {
if (curso.disponivel) {
onCourseClick(curso.areaId); // Navega para /curso/:areaId
}
};
return (
<div className="max-w-6xl mx-auto p-6">
{/* Breadcrumb */}
<nav>Hub > Caminho: {path.name}</nav>
{/* Header */}
<h1>{path.icon} {path.name}</h1>
<p>{path.description}</p>
{/* Stats */}
<div>
{path.cursosDisponiveis}/{path.totalCursos} cursos disponiveis |
{path.modulesDisponiveis}/{path.totalModules} modulos |
{path.hoursDisponiveis}h/{path.totalHours}h
</div>
{/* Lista de cursos */}
{path.cursos.map(curso => (
<CursoCard
key={curso.areaId}
curso={curso}
=> handleCourseClick(curso)}
/>
))}
</div>
);
}
Como Adicionar Novos Caminhos
Passo 1: Definir o Caminho no caminhoExemploData.js
export const caminhoFrontend = {
id: 'frontend-developer',
name: 'Desenvolvedor Frontend',
icon: 'frontend',
description: 'Domine as tecnologias do frontend moderno',
badge: 'novo',
cursos: [
{ ordem: 1, areaId: 'html-css', nome: 'HTML & CSS', disponivel: false, ... },
{ ordem: 2, areaId: 'javascript', nome: 'JavaScript', disponivel: false, ... },
{ ordem: 3, areaId: 'react', nome: 'React', disponivel: false, ... },
{ ordem: 4, areaId: 'vscode', nome: 'VSCode & Ferramentas', disponivel: true, ... }
],
get totalCursos() { return this.cursos.length; },
// ... outros getters
};
// Adicionar ao dicionario
export const caminhosPropostos = {
'backend-developer': caminhoExemplo,
'frontend-developer': caminhoFrontend // NOVO
};
Passo 2: Criar Areas de Estudo referenciadas (se nao existirem)
Se html-css nao existe em studyAreas.js, adicionar:
// studyAreas.js
{
name: "HTML & CSS",
icon: "html",
description: "Fundamentos da web",
modules: 10,
hours: 20,
badge: null, // Nao tem sistema integrado ainda
hasIntegratedApp: false,
key: "html-css",
flashcards: []
}
Passo 3: (Opcional) Criar LearningSystem para cursos disponiveis
Se quiser habilitar navegacao para o curso, criar:
HtmlCssLearningSystem.jsxhtmlCssLearningData.js
E marcar disponivel: true no caminho.
Antipadroes a Evitar
1. Duplicar Dados de Curso no Caminho
ERRADO:
cursos: [
{
areaId: 'bash',
flashcards: [ // DUPLICADO!
{ front: "...", back: "..." }
],
sections: [...] // DUPLICADO!
}
]
CORRETO:
cursos: [
{
areaId: 'bash', // REFERENCIA - flashcards estao em studyAreas.js
modules: 16, // Apenas metadados de exibicao
hours: 32
}
]
2. Misturar Flashcards Soltos no Caminho
ERRADO:
caminhoBackend = {
name: "Backend",
flashcards: [ // Flashcards NAO pertencem a caminho!
{ front: "O que e REST?", back: "..." }
]
}
CORRETO:
// Flashcards pertencem a CURSOS (studyAreas.js)
caminhoBackend = {
name: "Backend",
cursos: [
{ areaId: 'api-rest', ... } // API REST tem seus proprios flashcards
]
}
3. Hardcoded Availability
ERRADO:
// Verificar se curso esta disponivel via logica complexa
{studyAreas.find(a => a.key === curso.areaId)?.hasIntegratedApp && (
<button>Acessar</button>
)}
CORRETO:
// Declarativo no schema
{ areaId: 'bash', disponivel: true } // Explicito
// No componente, simples:
{curso.disponivel && <button>Acessar</button>}
4. Ordem Implicita via Array Index
ERRADO:
cursos: ['bash', 'linux', 'docker'] // Ordem implicita, fragil
CORRETO:
cursos: [
{ ordem: 1, areaId: 'bash' },
{ ordem: 2, areaId: 'linux' },
{ ordem: 3, areaId: 'docker' }
]
Exemplos do Projeto
Arquivo Real: src/data/caminhoExemploData.js
Localizacao: src/data/caminhoExemploData.js:1-109
Este arquivo e o modelo de referencia implementado na US-044.
Arquivo Real: src/components/LearningPathView.jsx
Localizacao: src/components/LearningPathView.jsx
Renderiza a lista de cursos do caminho com estados de disponibilidade.
Arquivo Real: src/components/HubView.jsx
Localizacao: src/components/HubView.jsx
Mostra cards de Caminhos Propostos e Areas de Estudo.
Navegacao Implementada
Rota | Componente | Props
---------------|-------------------|------------------------
/ | HubView | studyAreas, caminhosPropostos
/trilha/:id | LearningPathView | pathId, onCourseClick
/curso/:id | *LearningSystem | courseId
/curso/:id/aula/:aulaId | *NotesView | moduleId
Referencias
Skills Relacionadas
- platform-architecture - Arquitetura geral do sistema
- ux-nomenclature - Glossario de termos (Caminho vs Trilha)
- component-refactor - Refatoracao de componentes
Documentacao Tecnica
- ROADMAP.md - US-044 (Hub MVP Simplificado)
- docs/tecnico/architecture/ - Arquitetura detalhada
Codigo Real do Projeto
Implementacao de Referencia (US-044):
src/data/caminhoExemploData.js:1-109- Schema de caminhosrc/data/studyAreas.js- Areas de estudo (MVP: apenas Bash)src/components/HubView.jsx- Hub com caminhossrc/components/LearningPathView.jsx- Lista de cursos do caminhosrc/components/SistemaEducacionalCompleto.jsx- Integracao
Voce esta em: .claude/skills/learning-path-patterns/SKILL.md
Criado em: 2025-11-22
Mantido por: Joao Pelegrino + Claude Code
Uso: Referencia para implementar e escalar Caminhos de Aprendizado
Ultima auditoria: 2025-11-22
Desbloqueia: Novos caminhos, escala do Hub, consistencia UX