Community
Status: 🟡 Em fluxo (read-only facade sobre tabelas legacy) Code: backend/app/modules/community UI: frontend/src/app/(admin)/[slug]/admin/community + frontend/src/app/(public)/clube Última revisão deste doc: 2026-05-13 por Felipe + Claude Dependências fortes: raw SQL contra tabelas legacy (
community_*)
1. Identidade
O que faz (uma frase)
Expõe read-only API sobre tabelas legacy de comunidade (cursos, módulos, jornadas, EVAI ciclos mensais, posts) consumida pela UI /clube (área aluno) — sem ORM próprio, raw SQL via text() queries.
Por que existe (negócio)
Comunidade do Mais Consciente já existia em forma legacy (Sangha) com cursos modulares, jornadas (ferramentas) e calendário EVAI (Estudo Vivencial). Migração completa pra ORM levaria semanas; em vez disso, módulo expõe leituras das tabelas existentes pro frontend novo, mantendo retrocompatibilidade.
Status atual
- Read-only proxy. 35 endpoints GET. POST/PATCH/DELETE não implementados (virão conforme demanda).
Próxima mudança: migração gradual para modelos ORM próprios + CRUD admin.
2. Cases de uso reais
Case 1: Aluno abre /clube/cursos
Frontend chama GET /api/community/courses → backend faz raw SQL SELECT * FROM community_course WHERE tenant_id=... → retorna lista.
Case 2: Aluno acessa curso → módulos → vídeos
3 chamadas: /courses/{slug} retorna nested (modules + vídeos).
Case 3: Calendário EVAI
/evai/current retorna mês atual + 4 semanas + items (audio/video/PDF/exercício).
3. Oportunidades de negócio
- Migração para ORM CRUD — habilita admin completo no painel.
- Posts + reações + moderação — features sociais (não implementadas yet).
- Live events — integrar com meetings module pra aulas ao vivo na própria comunidade.
4. Arquitetura interna
Arquivos
routes.py— 35 endpoints GET com raw SQL.__init__.py— bare router.
Tabelas legacy consultadas
community_course— cursos (id, slug, titulo, descricao, total_aulas, simbolo, cor, disponivel, sort_order)community_course_module— módulos do cursocommunity_course_module_video— vídeos (bunny_guid)community_tool— jornadas + ferramentascommunity_jornada_day— dias da jornada (audio_url, exercicio_md, duracao_min)community_jornada_assessment— avaliaçõescommunity_jornada_pdf— PDFs anexadoscommunity_evai_month— ciclos mensais (codigo, numero, tema, descricao)community_evai_week— semanas (slug, fase, subtema)community_evai_item— items (titulo, tipo, duracao_min, url, bunny_video_id, event_at)- (planejado:
community_post,community_reaction,community_comment)
5. API / Endpoints (35)
Cursos (3)
| Método | Rota | O que faz |
|---|---|---|
| GET | /courses | Lista cursos ativos |
| GET | /courses/{slug} | Detalhe com modules + vídeos nested |
Jornadas (2)
| GET | /jornadas | Lista |
| GET | /jornadas/{slug} | Detalhe + days + assessment + PDF |
EVAI (4)
| GET | /evai/current | Mês corrente + semanas + items |
| GET | /evai/months | Lista todos meses |
| GET | /evai/months/{codigo} | Detalhe mês + semanas |
| GET | /evai/weeks/{slug} | Detalhe semana + items |
(Outros endpoints existem para sub-features menores; lista completa em routes.py.)
6. Configuração
Sem env vars. Cache local de tenant_slug → tenant_id em memory dict (_SLUG_CACHE) — sem invalidação até restart.
7. Operações + Troubleshooting
Sintoma: Endpoint retorna 404 em curso existente
Causa: tenant_id não está sendo resolvido (Starlette BaseHTTPMiddleware bug — request.state vazio).
Fix: Header X-Tenant-Slug deve estar presente; código fallback resolve via slug.
Sintoma: Mudança em legacy table não aparece
Causa: _SLUG_CACHE em memória.
Fix: restart container.
8. Limitações e débitos técnicos
| # | Item |
|---|---|
| 1 | Raw SQL sem typecheck — typos só em runtime |
| 2 | Sem paginação built-in — ALL items |
| 3 | _SLUG_CACHE sem invalidação — vive até restart |
| 4 | Tenant resolve via header — workaround Starlette bug |
| 5 | Read-only — CRUD admin não implementado |
| 6 | Sem features sociais (posts, reações, comments) |
9. Histórico
Built como facade sobre Sangha legacy. Migração completa pra ORM tracked como débito.