Backend - Marketplace de Cursos¶
Objetivo¶
Documentar o estado atual do domínio de cursos após o ciclo de refatoração full (big bang), cobrindo contratos, modelos, permissões e migrações.
Resumo do que mudou¶
- Contratos de curso migrados para centavos (
price_amount_cents). - Vídeo desacoplado de fornecedor específico (
video_provider,video_*). - Duração de curso removida do modelo persistido e calculada por soma de aulas (
total_duration_sec). - Inclusão de materiais de aula (
course_lesson_materials). - Inclusão de avaliações (
course_reviews) e moderação. - Inclusão de revenue split por ordem (
course_order_revenue_shares). - Inclusão de bundles (
course_bundles,course_bundle_items). - Inclusão de recomendações cross-sell (
course_recommendations). - Endpoint agregado de catálogo (
GET /marketplace/catalog). - Permissionamento granular por módulo para cliente e profissional.
Modelos do domínio de cursos¶
Modelos principais em internal/models/marketplace/:
CourseCourseModuleCourseLessonCourseLessonMaterialCourseLessonProgressCourseEnrollmentCourseOrderCourseOrderRevenueShareCourseOrderStatusLogCourseReviewCourseReviewLogCourseRecommendationCourseBundleCourseBundleItemCourseCommissionSetting
Decisões estruturais importantes¶
Coursenão persiste maisdurationnemvideo_url.Course.PriceAmountCentssubstitui uso monetário em ponto flutuante.CourseLessonusa metadados genéricos de vídeo:video_providervideo_upload_idvideo_asset_idvideo_playback_idlast_video_provider_event_atCourseOrdermantém snapshots em centavos para auditoria e reconciliação.CourseOrderRevenueSharepermite N participantes por ordem.
Endpoints de marketplace¶
Rotas registradas em internal/modules/marketplace/courses/routes.go.
Cliente¶
GET /marketplace/catalogGET /marketplace/coursesGET /marketplace/courses/:idGET /marketplace/courses/:id/contentGET /marketplace/courses/:id/accessPOST /marketplace/courses/:id/purchase-intentPOST /marketplace/courses/:id/completeGET /marketplace/courses/:id/reviewsPOST /marketplace/courses/:id/reviewsGET /marketplace/enrollmentsGET /marketplace/enrollments/:enrollment_id/contentPOST /marketplace/enrollments/:enrollment_id/lessons/:lesson_id/progressPOST /marketplace/enrollments/:enrollment_id/lessons/:lesson_id/mark-watchedGET /marketplace/enrollments/:enrollment_id/lessons/:lesson_id/playbackGET /marketplace/bundlesGET /marketplace/bundles/:idPOST /marketplace/bundles/:id/purchase-intent
Profissional¶
- Cursos, módulos e aulas (CRUD editorial)
- Fluxo de vídeo (upload URL, import por URL, status, thumbnail, delete)
- Materiais de aula (CRUD)
- Recomendações (CRUD por curso)
- Bundles (CRUD + itens)
- Revenue/sales summary por curso
- Submissão para revisão e despublicação
- Exclusão lógica de curso com fila assíncrona para remoção de vídeos (
POST /marketplace/professional/courses/:id/delete) - Status de deleção no payload de curso (
deletion_status,deletion_progress_note, contadores de vídeos)
Admin¶
- Catálogo administrativo da vitrine (
GET /marketplace/admin/catalog) - Review queue/detail/playback
- Pré-visualização de aulas no fluxo de revisão usando token admin de playback
- Aprovar, rejeitar e forçar despublicação de curso
- Pedidos e reembolso
- Settlement e reconciliação
- Commission settings
- Reviews (listagem + moderação)
- Review logs
- Bundles (CRUD + itens)
- Recomendações (CRUD)
Webhooks públicos¶
POST /marketplace/webhooks/mercadopagoPOST /marketplace/webhooks/mux
Pré-visualização admin de vídeos¶
Para revisão editorial/operacional, o admin pode reproduzir vídeos das aulas sem matrícula de cliente via:
GET /marketplace/admin/courses/:course_id/lessons/:lesson_id/playback
Regras:
- Aula deve estar em status
ready. - Playback é assinado quando
marketplace.mux.signed_playback.enabled=true. - Endpoint é restrito a perfil admin.
- Fluxo é auditável via logs operacionais.
Contrato agregado de catálogo¶
GET /marketplace/catalog retorna:
{
"courses": [],
"bundles": [],
"recommendations": []
}
Campos de destaque:
courses[].price_amount_centscourses[].total_duration_seccourses[].rating_avgcourses[].reviews_countbundles[].price_amount_centsbundles[].courses_countbundles[].savings_cents
Permissionamento granular¶
Módulos canônicos em internal/modules/module_access/catalog.go:
- Cliente:
educacional.cursos.catalogoeducacional.cursos.playereducacional.cursos.bundleseducacional.cursos.reviews- Profissional:
educacional.cursos.profissional.gestaoeducacional.cursos.profissional.recomendacoeseducacional.cursos.profissional.bundleseducacional.cursos.profissional.materiaiseducacional.cursos.profissional.revenue
Observação:
- A gestão de módulos no admin passou a renderizar árvore recursiva, permitindo visualizar níveis como educacional.cursos.*.
Migrações relacionadas¶
Arquivos aplicados no ciclo:
042_marketplace_course_domain_refactor.sql043_marketplace_revenue_share_bundle_recommendation.sql044_marketplace_catalog_and_review_moderation.sql045_add_marketplace_course_permission_modules.sql046_marketplace_course_logical_delete.sql
Rollbacks correspondentes em migrations/rollback/.
OpenAPI¶
openapi.v2.yaml foi atualizado para refletir:
- novos schemas de marketplace;
- contratos em centavos;
- contratos de vídeo genéricos;
- cobertura das rotas
marketplace/*(cliente, profissional e admin).
Checklist de integração backend¶
- Usar apenas contratos em centavos.
- Não consumir campos
mux_*nos payloads de domínio. - Não depender de
course.durationpersistido. - Consumir catálogo preferencialmente por
GET /marketplace/catalog. - Validar módulo de acesso antes de liberar rotas no app cliente.