Produtos digitais — arquitetura, API e análise técnica
Referência do recurso em 02/11/2026, a partir do código do pepper-api, pepper-front, sabine e pepper-mcp. Os caminhos são relativos à raiz de cada repositório. O plano de origem está em pepper-front/PLANO-PRODUTOS-DIGITAIS.md e o andamento em pepper-front/PROGRESSO-PRODUTOS-DIGITAIS.md.
Entidades
| Entidade | Campos / comportamento relevante |
|---|---|
Product.digital | format (course, mentorship, library), totalHours, accessDays (null = vitalício), sequential, previewEnabled, certificate (enabled, minProgress, minScore, template, signatories) e stats calculado pelo servidor. |
ProductModule | Título, ordem (index), liberação programada (afterDays ou date), exclusão lógica. |
ProductItem | kind (video, youtube, audio, pdf, image, link, text, survey, session), required, preview, requireFullView, media (caminho privado products/...), survey, session (startsAt, endsAt, joinUrl, location). |
Enrollment | Cliente, perfil do cliente, produto, origem (order, manual, subscription, voucher), status (active, completed, expired, revoked), expiresAt, progresso por item e consolidado (percent, score), presença. |
Certificate | Código de verificação, snapshot dos dados na emissão, PDF em caminho privado. |
Voucher (kind: access) | Código AC-XXXXX-XXXXX por unidade vendida no balcão sem conta; redeemedBy e enrollment após o resgate. |
Regras no servidor
| Regra | Onde |
|---|---|
| Conclusão de item a partir do snapshot do player (95% / última página / ao abrir) | src/domains/Enrollment/progress.js |
| Cadeados: ordem, liberação programada, acesso encerrado | src/domains/Enrollment/gate.js |
| Nota dos questionários | src/domains/Enrollment/grade.js |
| Liberação/reativação de acesso | src/domains/Enrollment/grant.js |
| Pedido pago → matrículas e códigos; pedido inválido → revogação | src/domains/Order/on-paid.js |
| Códigos de acesso | src/domains/Voucher/access.js, access.controller.js |
| Acesso por assinatura | src/domains/Subscription/digital-access.js |
| Encontros e presença | src/domains/ProductModule/sessions.js |
| Elegibilidade e emissão do certificado | src/domains/Certificate/eligibility.js, issue.js |
| Limites de upload e URLs assinadas | src/libs/storage/upload-rules.js, signed-urls.js |
Rotas
| Grupo | Rotas | Permissão |
|---|---|---|
| Conteúdo | GET /product-content/product/:productId; módulos e itens (criar, editar, remover, reordenar); POST /product-content/items/:itemId/upload-url | productContent |
| Encontros | GET /product-content/business/:businessId/sessions?start&end (até 93 dias); GET/PUT /product-content/items/:itemId/attendance | productContent |
| Participantes | GET/POST /enrollment/product/:productId; GET .../report; PUT /enrollment/:enrollmentId; PUT .../items/:itemId/complete | enrollment |
| Certificados | GET /certificate/:id, GET .../pdf, POST /certificate/enrollment/:enrollmentId, POST /certificate/product/:productId/preview | certificate |
| Aluno | /customer/me/enrollments (lista, trilha, item, progresso, respostas, certificado); POST /customer/me/vouchers/:code/redeem-access (10/min) | conta do cliente |
| Público | GET /public/product/:productId/syllabus; GET /public/certificate/:code | — |
A documentação OpenAPI de cada domínio está em src/domains/<Domínio>/swagger.js.
Armazenamento
- Conteúdo pago fica em
products/**, fechado nasstorage.rules: o envio e a leitura só acontecem por URL assinada emitida pela API, depois de checar permissão ou matrícula. - Anexos e imagens comuns (
attachments/**,images/**) só podem ser apagados pela API (DELETE /storage/files, com login). A regra nova dostorage.rulesainda não foi publicada: publique depois da API e dos fronts. - O bucket precisa de CORS de envio (PUT) e leitura para o upload pelo navegador e o PDF no app.
Frontends
| Fluxo | Evidência |
|---|---|
| Cadastro/edição e certificado | pepper-front/src/app/product/new, edit, product-digital.ts |
| Aba Conteúdo, itens e questionários | pepper-front/src/app/product/view/product-content, product-item-modal, product-quiz-modal |
| Participantes e presença | pepper-front/src/app/product/view/product-participants |
| Meus Conteúdos (web) | pepper-front/src/app/learn |
| Verificação pública | pepper-front/src/app/public/certificate |
| App: dados, matrícula e player | sabine/src/app/providers/product.service.ts, enrollment.service.ts, components/content-player, components/pdf-viewer |
| App: páginas | sabine/src/app/pages/learn-list, learn-course, learn-item |
| App: links e notificações | sabine/src/app/providers/deep-link.ts, push-routing.ts |
Agentes (MCP)
O pepper-mcp expõe o recurso para agentes, agindo em nome de um usuário real (as permissões acima continuam valendo):
| Tool | Uso |
|---|---|
pepper_get_product_content, pepper_get_product_syllabus | Conteúdo e ementa pública. |
pepper_list_product_enrollments, pepper_get_product_enrollment_report | Participantes e funil. |
pepper_list_content_sessions, pepper_get_session_attendance | Agenda de encontros e presença. |
pepper_get_certificate, pepper_verify_certificate | Certificado emitido e verificação pública. |
pepper_grant_enrollment, pepper_set_session_attendance, pepper_issue_certificate | Escritas, só com PEPPER_MCP_ALLOW_WRITE=1. |
pepper_digital_product_overview | Panorama: conteúdo quebrado, funil, participantes parados, próximos encontros. |
Pendências técnicas
- Migração aditiva das três permissões novas para perfis existentes.
- Envio de notificações (acesso, certificado, encontro) pela API.
- Campo de liberação programada de módulos e botão de emissão de certificado na interface.
- Sincronizar o acesso por assinatura no pagamento automático da mensalidade.
- Fase de escala (HLS, CDN, relatórios de consumo, offline, cotas), dependente do provedor de vídeo.