🛡 REGRA DE GOVERNANÇA TÉCNICA (OBRIGATÓRIA)¶
📚 Enterprise Documentation Engine¶
- Wiki pública oficial:
https://docs.spokeplus.com(MkDocs Material, sem autenticação). - Toda alteração estrutural exige atualização dos arquivos em
/docs. - O snapshot de schema (
docs/schema/latest-schema.jsonedocs/schema/latest-schema.md) é regenerado automaticamente viascripts/generate-schema-snapshot.js. - PR é inválido se mudanças estruturais não atualizarem documentação.
Estas regras são permanentes e devem ser obedecidas por qualquer agente de implementação (Codex) ou colaborador humano.
📜 Changelog¶
- 2026-03-02: Engine Core ativado com endpoint público
POST /practice/evaluate, pipeline morfológico v1 (alinhamento por índice simples) e score 40/40/20. -
2026-03-02: Formalizadas as referências oficiais do Morphological Evaluation Engine (token-level), da geração de
word_formscom irregulares e do Word Detail Panel, incluindo vínculos cruzados com ENGINE_SPEC e governança documental obrigatória. -
2026-03-02: Snapshot estrutural oficial formalizado com
sql/9000_schema_tables.sql,sql/9001_schema_columns.sqle viewvw_schema_snapshotvia migration0011_schema_snapshot_view.sql; obrigatório executar e atualizar documentação após qualquer mudança estrutural. - 2026-03-02: Word Detail (Admin) recebeu a ação Gerar formas com endpoint
POST /admin/content-bank/vocabulary/:id/forms/generate(modessuggest|save) para preview/edit/save deword_formscom políticakeep_manual. - 2026-03-02: Content Bank agora é morfológico, universal e multilíngue (lemma raiz + formas derivadas, relações semânticas, sentence tokens morfossintáticos e endpoint de Word Detail).
- 2026-03-02: Remoção do modelo legado anterior. Content Bank agora exclusivamente linguístico.
📘 Referências oficiais — Morphological Evaluation Engine¶
Documentos normativos para implementação linguística token-level:
docs/MORPHOLOGICAL_EVALUATION_SPEC.mddocs/MORPHOLOGY_GENERATION_SPEC.mddocs/WORD_DETAIL_PANEL_SPEC.mddocs/irregulars/en_verbs.json
O ENGINE_SPEC.md deve manter links cruzados para estes artefatos sem duplicar conteúdo.
1. Proibições Absolutas¶
❌ Não alterar portas (3000 API / 3001 Web)
❌ Não alterar estrutura do PM2
❌ Não remover rotas existentes
❌ Não alterar controllers existentes sem justificativa documentada
❌ Não remover tabelas existentes
❌ Não misturar JavaScript/TypeScript dentro de arquivos SQL
❌ Nunca usar SERVICE_ROLE no frontend
2. Obrigação de Documentação¶
Toda alteração estrutural exige:
- Atualização do README.md
- Atualização do MANUAL_MESTRE.md
- Atualização do Changelog no topo (formato YYYY-MM-DD)
- Atualização da seção Banco de Dados (se tabela/coluna for alterada)
- Atualização da seção Rotas (se rota for criada/modificada)
Nenhuma tarefa é considerada concluída sem atualização da documentação.
3. Regra de Migrations SQL¶
- Toda migration deve ser idempotente (
IF NOT EXISTS, guards, DO $$ BEGIN EXCEPTION`) - Nunca sobrescrever estrutura anterior
- Nunca alterar tabela sem documentar impacto
- Sempre criar migration numerada (ex: 0008_xxx.sql)
- Sempre manter ordem oficial listada no README
4. Snapshot Obrigatório do Banco¶
Sempre que houver alteração estrutural:
O agente deve gerar um snapshot atualizado do schema executando:
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'public'
ORDER BY table_name, ordinal_position;
Esse snapshot deve ser usado para atualizar a seção: "🗄 Banco de Dados (schema real atual)"
🔎 Snapshot Estrutural Oficial¶
Após qualquer alteração estrutural:
- Executar
sql/9000_schema_tables.sql - Executar
sql/9001_schema_columns.sql - Atualizar seção 🗄 Banco de Dados
- Commitar atualização documental
5. Fonte Única de Verdade¶
- Content Bank oficial = modelo linguístico único (
vocabulary,word_*,sentences,sentence_*,tags,pos_colors,tts_assets) - Estrutura pedagógica oficial =
courses → units → skills → lessons worldsestagessão visuais (não controlam progressão)- Adaptive Engine não altera ordem do bloco estruturado da Unit
🔒 MODELO OFICIAL ATIVO¶
- O Content Bank oficial ativo em produção é o modelo linguístico:
vocabulary,word_*,sentences,sentence_*,tags. - Toda evolução do Content Engine deve usar exclusivamente o modelo linguístico oficial.
- O legado de Content Bank foi removido da aplicação e do schema.
6. Política de Atualização Contínua¶
Após qualquer commit que altere:
- Tabelas
- Views
- Rotas
- Middleware
- Variáveis de ambiente
- Estrutura do Engine
O agente deve:
- Atualizar README
- Atualizar MANUAL_MESTRE
- Atualizar Changelog
- Confirmar que build não quebrou
- Confirmar que PM2 não foi alterado
Sem isso a tarefa é considerada incompleta.
# 🧠 SPOKE PLUS — MANUAL MESTRE OFICIAL (VERSÃO 2.0 — CONSOLIDADO)
> Documento mestre da plataforma Spoke Plus (Admin + Course Engine + Infra).
> **Objetivo:** manter uma única fonte oficial de verdade para o time (humano + Codex), evitando retrabalho e decisões conflitantes.
---
## 0) Você deve colocar isso no GitHub?
**Sim, recomendo**, porque vira a “fonte única” do projeto e reduz confusão.
Mas siga estas regras antes:
- **Se o repositório for público:**
- Remover **IP**, **usuários**, **paths internos sensíveis**, qualquer **secret**, e detalhes que facilitem ataque.
- Substituir por placeholders: `YOUR_SERVER_IP`, `YOUR_USER`, `YOUR_PATH`.
- **Se o repositório for privado:**
- Pode manter mais detalhes, mas **NUNCA** commit de `.env`, chaves, tokens, `SUPABASE_SERVICE_ROLE_KEY`, `ADMIN_BOOTSTRAP_SECRET`.
- Sempre versionar o manual em: `docs/MANUAL_MESTRE.md` e linkar no `README.md`.
A parte de infraestrutura atual (Ubuntu/PM2/paths/“não usar root”) é essencial e já existe na doc de infra :contentReference[oaicite:0]{index=0} — só precisa ser “sanitizada” se for público.
---
## 1) Visão geral do produto (o que é / o que não é)
**Spoke Plus é uma plataforma educacional gamificada inspirada em Duolingo**, baseada em:
- Skill-driven architecture (skills são o núcleo pedagógico) :contentReference[oaicite:1]{index=1}
- Conteúdo atômico reutilizável (items/variants) :contentReference[oaicite:2]{index=2}
- Geração dinâmica de lições (lesson engine) :contentReference[oaicite:3]{index=3}
- Economia (cookies) + XP + streak + métricas
- Admin SaaS profissional (Course Engine / User Management / Reports / System)
**O Spoke Plus NÃO é um CMS de páginas.**
É um **Content Engine pedagógico escalável** :contentReference[oaicite:4]{index=4}.
---
## 2) Arquitetura técnica (atual)
### 2.1 Backend (API)
- Node.js + Express (ESModules) :contentReference[oaicite:5]{index=5}
- Supabase (Postgres + Auth + Storage)
- **SERVICE_ROLE** somente no backend (nunca no front) :contentReference[oaicite:6]{index=6}
- Porta: **3000**
- Processo gerenciado via **PM2** :contentReference[oaicite:7]{index=7}
### 2.2 Frontend (Admin)
- Next.js 14 (App Router) :contentReference[oaicite:8]{index=8}
- React 18
- Porta: **3001**
- **Nenhum acesso direto ao banco** (admin consome Express `/admin/...`) :contentReference[oaicite:9]{index=9}
---
## 3) Regras não negociáveis (segurança e consistência)
### 3.1 Princípios
- Frontend **nunca** usa `SUPABASE_SERVICE_ROLE_KEY`. :contentReference[oaicite:10]{index=10}
- Admin **nunca** acessa DB direto: sempre via Express API. :contentReference[oaicite:11]{index=11}
- Rotas administrativas exigem proteção (middleware `requireAdmin`). :contentReference[oaicite:12]{index=12}
- Bootstrap de admin é protegido por header `x-bootstrap-secret`. :contentReference[oaicite:13]{index=13}
### 3.2 Separação rígida de papéis
Papéis:
- `student`: usuário padrão
- `admin`: usuário presente em `admin_users`
- `system`: reservado (infra-only, futuro)
Regras:
- **Admin nunca aparece como student.**
- Endpoints de student devem rejeitar `admin IDs`. :contentReference[oaicite:14]{index=14}
---
## 4) Infraestrutura (VPS + Deploy)
### 4.1 Servidor
- VPS Ubuntu 24.04 LTS
- Projeto em: `/home/spoke/spokeplus` :contentReference[oaicite:15]{index=15}
- **Nunca executar build/deploy como root** (evita EACCES em `.next`). :contentReference[oaicite:16]{index=16} :contentReference[oaicite:17]{index=17}
### 4.2 PM2 (processos oficiais)
- Backend: `spokeplus` (entry `server.js`, porta 3000) :contentReference[oaicite:18]{index=18}
- Frontend: `spokeplus-web` (`npm start`, porta 3001) :contentReference[oaicite:19]{index=19}
### 4.3 Deploy automático (GitHub Actions + SSH)
Workflow padrão (resumo):
- `git pull origin main`
- API: `npm install --production` + `pm2 reload spokeplus --update-env`
- WEB: `cd web` + `npm install` + `npm run build` + `pm2 restart spokeplus-web --update-env` + `pm2 save` :contentReference[oaicite:20]{index=20}
**Procedimento seguro manual** (quando necessário): :contentReference[oaicite:21]{index=21}
---
## 5) Setup local / produção (passo a passo)
### 5.1 Instalação
```bash
npm install
cd web && npm install
5.2 Env¶
cp .env.example .env
cp web/.env.example web/.env.local
5.3 Banco: ordem oficial de SQL (Supabase)¶
Rodar no Supabase nesta ordem:
sql/0001_user_provision.sqlsql/0002_views_if_missing.sqlsql/0004_enrollment.sqlsql/0005_dashboard_metrics.sqlsql/0006_content_engine.sqlsql/0007_content_bank_consolidation.sqlsql/0008_drop_legacy_content_model.sqlsql/0009_content_bank_hardening.sqlsql/0010_morphological_engine.sqlsql/0011_schema_snapshot_view.sqlsql/9000_schema_tables.sql(snapshot operacional/documental)sql/9001_schema_columns.sql(snapshot operacional/documental)
Observação:
0005cria views de métricas (ex.: dashboard + atividade recente).0006cria a base do Content Engine (itens reutilizáveis + estrutura do curso).
6) Bootstrap de Admin (fluxo correto)¶
- Criar usuário via signup normal (para disparar trigger/provisionamento).
- Promover a admin via bootstrap protegido:
curl -X POST http://localhost:3000/admin/bootstrap/add-admin \
-H 'Content-Type: application/json' \
-H 'x-bootstrap-secret: YOUR_ADMIN_BOOTSTRAP_SECRET' \
-d '{"user_id":"<SUPABASE_USER_ID>"}'
7) Admin Dashboard (rotas e módulos)¶
7.1 Rotas principais (Next.js)¶
- Login:
/admin/login - Dashboard:
/ - Students:
/students - Student details:
/students/[userId] - Admin Users:
/admin-users - Courses:
/courses - Course Builder:
/course-builder - Content Bank:
/content-bank - Reports:
/reports - Settings:
/settings - System:
/system
7.2 Contrato de consumo de API¶
Frontend chama sempre:
apiFetch('/admin/...')
Nunca “Supabase direto” para dados administrativos.
8) Course Engine (núcleo pedagógico)¶
8.1 Conceitos (oficiais)¶
- Content Bank oficial linguístico:
vocabulary,sentences,word_*,sentence_*,tags. - Estrutura oficial de aprendizagem:
courses → units → skills → lessons. - Unit: bloco de progressão real (ordem pedagógica canônica do aluno).
- Map (worlds/stages): camada visual de navegação e apresentação (não define progressão real).
- Adaptive híbrido: adapta exercícios e reforço sem alterar o bloco estrutural da Unit.
- Skill: núcleo pedagógico.
- Item: conteúdo atômico reutilizável.
- Variant: exercício (formas diferentes).
- Lesson: execução dinâmica (não é “lição fixa manual”).
8.2 Tabs/funcionalidades alvo no Course Engine¶
Base do design/arquitetura do dashboard:
- Overview
- Skill Graph
- Skills Manager
- Items Engine
- Lesson Engine
- Quality Control
- Settings
- Publish (checklist de qualidade)
8.3 Quality Control (obrigatório)¶
Flags automáticas (exemplos):
- Skill com poucos itens
- Item com poucas variants
- Missing TTS
- Missing speaking
- Dependência não definida
- Coverage desigual
9) Regra oficial de conclusão de Skill (obrigatória)¶
Uma skill só pode ser marcada como completed quando:
sessions_completed >= skills.min_sessions_required
AND
mastery >= skills.min_mastery_required
10) Economia (cookies) — visão do sistema¶
session_cookie_start- Erro: -1 cookie
- Ao chegar em 0: comprar continue ou finalizar
-
Continue pack:
-
continue_pack_cost continue_pack_amount-
Recompensas:
-
lesson_reward practice_reward
11) Integração de IA (direção oficial)¶
Objetivo: criação assistida de conteúdo (reutilizável, multi-idiomas):
generateImage()generateAudio()autoTranslate()Fluxo planejado:- criar item → gerar tags → gerar imagem → gerar TTS → armazenar/cache
12) Troubleshooting (problemas reais do ambiente)¶
12.1 “Failed to find Server Action … older or newer deployment”¶
Isso normalmente aparece quando:
- O front está tentando chamar Server Actions, mas o build/deploy não está alinhado (build id diferente), OU
- Há cache antigo do
.next, OU - Você está usando uma rota/handler que mudou entre deploys.
Regra oficial do projeto: evitar Server Actions no admin e usar Express API (/admin/...) para reduzir esse tipo de erro.
Checklist de correção (produção):
- Garantir deploy completo:
npm run builde restart dospokeplus-web. -
Limpar build antigo se necessário:
-
remover
web/.next(como usuário correto, não root) - Rebuild e restart PM2 do web.
12.2 EACCES / permissão em .next¶
Causa típica: build feito como root.
Correção padrão: chown -R + remover .next + rebuild .
13) Política de documentação (obrigatória para Codex e humanos)¶
13.1 README sempre atualizado¶
Toda PR deve incluir:
- O que mudou (bullets)
- Rotas novas/alteradas
- SQL novo (se houver) e ordem
- Mudanças de env (variáveis novas)
- Passos de deploy/restart necessários
13.2 Changelog curto por commit/PR¶
Criar/atualizar: docs/CHANGELOG.md com:
- Data
- Commit/PR
- Resumo
- Riscos / migrações
13.3 “Nunca apagar o que já funciona”¶
Se for refatorar UI/rotas:
- preservar
students,admin-users,settings,system,reports,courses - qualquer rota removida precisa de substituição + redirect + nota no README/Changelog
13.4 Governança técnica contínua (obrigatória)¶
A partir de agora, para qualquer mudança estrutural:
- Toda alteração estrutural deve atualizar documentação (
README.md+MANUAL_MESTRE.md). - Sempre gerar snapshot do schema após mudanças de banco.
- Nunca alterar portas, PM2 ou rotas base.
- Não remover nada existente.
- Não quebrar build.
- Commits organizados.
- Sem alterar infraestrutura.
14) Estado atual (marco)¶
- Admin com Next App Router + proteção global
- UX profissional de erros (error.tsx / not-found.tsx)
- Students + Admin Users separados
- System monitor + logs
- Course Engine em evolução (Content Bank + Course Builder)
- Deploy estável via PM2 + GitHub Actions
Apêndice A — Links internos do projeto¶
docs/MANUAL_MESTRE.md(este arquivo)docs/INFRA.md(versão sanitizada da infra)docs/COURSE_ENGINE.md(arquitetura do course engine)docs/DB_SCHEMA.md(tabelas/views essenciais)
Observação: a visão de Course Engine (versão 1.0) está detalhada no documento oficial e serve como base de UI/escopo.
## Prompt para o Codex (copiar e colar)
```text
Tarefa: Consolidar documentação oficial e preparar para GitHub.
Contexto: Projeto SPOKE PLUS (Node+Express API + Next.js 14 admin). Temos múltiplas docs (Infra, Course Engine, Manual Mestre). Quero uma “VERSÃO 2.0 OFICIAL” única e consistente.
Objetivo:
1) Criar/atualizar os arquivos:
- docs/MANUAL_MESTRE.md (conteúdo do manual mestre consolidado)
- docs/INFRA.md (extrair do manual apenas infra e “sanitizar” para repo público: substituir IP, usuário e paths sensíveis por placeholders)
- docs/COURSE_ENGINE.md (extrair e organizar a arquitetura do Course Engine: tabs, quality control, publish checklist)
- docs/DB_SCHEMA.md (lista de tabelas/views essenciais e a ordem oficial de SQL: 0001, 0002, 0004, 0005, 0006)
2) Atualizar README.md para:
- linkar os docs acima
- incluir seção “Documentation Policy” (toda PR atualiza README + Changelog)
- incluir seção “SQL order” com 0006_content_engine.sql
- incluir seção “Troubleshooting” com o erro “Failed to find Server Action” e a política do projeto: evitar Server Actions no admin, usar Express /admin/...
3) Criar docs/CHANGELOG.md e adicionar a entrada mais recente com o resumo do último conjunto de mudanças (admin app router + auth provider cache + students/admin-users + course engine/content bank).
Regras:
- NÃO apagar rotas existentes (students, admin-users, settings, system, reports, courses).
- NÃO commitar nenhum secret, .env, keys.
- Manter tudo em Markdown bem formatado.
- Commitar com mensagem: "Docs: consolidate official v2 manual and documentation policy"
Se você quiser, eu também reescrevo o README.md inteiro no mesmo padrão acima (já pronto para colar), mas o manual mestre acima já resolve o núcleo e dá ordem para o Codex atualizar o resto.
Practice Evaluation Engine (v1)¶
- Rota pública:
POST /practice/evaluate. - Validação de body com erro
400para payload inválido. 404quandosentence_idnão existir.500para falha interna sem vazamento de stack trace.- Pipeline v1 usa alinhamento simples por índice (sem realinhamento avançado).
- Score oficial: lexical 40, morphology 40, syntax 20.
Grammar Cards no Content Bank¶
- O módulo de Grammar usa
grammar_concepts+grammar_cards+grammar_card_examples+grammar_card_assets. - Examples NÃO duplicam texto: vínculo obrigatório com
sentences.id. - Áudio EN dos examples deve vir de
tts_assets(entity_type=sentence) por link; ausência deve ser exibida sem geração automática nesta fase. - QA mínimo para
ready/published: conceito, título, explicação nativa mínima, ao menos 1 exemplo tokenizado e assetnative_explanation_audio.
Redis local (VPS) para fila TTS¶
- Instalação Ubuntu/Debian:
sudo apt update && sudo apt install -y redis-server. - Instalação RHEL/CentOS:
sudo yum install -y redis. - Hardening mínimo em
/etc/redis/redis.conf: bind 127.0.0.1protected-mode yesappendonly yesport 6379requirepass <senha>(opcional; sincronizar comREDIS_PASSWORD).- Reiniciar e habilitar:
sudo systemctl enable --now redis.
Env vars TTS/Queue¶
REDIS_HOST=127.0.0.1REDIS_PORT=6379REDIS_PASSWORD=(opcional)REDIS_TLS=falseTTS_PROVIDER=mock|openai|elevenlabsTTS_WORKER_CONCURRENCY=2TTS_DEFAULT_VOICE_EN=(opcional)TTS_DEFAULT_VOICE_PTBR=(opcional)
PM2 — Worker dedicado de TTS¶
pm2 start workers/ttsWorker.js --name spokeplus-tts-worker
pm2 save
pm2 status
Admin UI v2 Dark SaaS¶
- O Admin foi padronizado com tema Dark/Light via
next-themes, com dark como padrão e toggle na Topbar. - O shell global usa Sidebar fixa + Topbar fixa + área de conteúdo com scroll.
- Componentes base do padrão Admin:
Button,Badge,Card(Header/Body),Table,Input/Textarea/Select,DropdowneDialog(Radix),Toast(sonner). - Tokens de tema centrais:
bg,surface,border,text,primary,success,warning,danger. - Padrão oficial: Admin não usa MUI; o frontend Admin segue Tailwind + Radix.