Trilha de cursos
TLDR: Criar o model
Trailpara agrupar cursos em sequência ordenada, com tabela intermediária, admin, backfill e endpoints GET.
Contexto
Hoje os cursos existem de forma independente. A feature de trilha agrupa cursos em uma sequência guiada — análoga à jornada de áudios — permitindo que um curso dependa do anterior dentro da trilha.
Objetivos
- Criar o model
Trailcom os camposcode,title,description,is_active,sort - Criar a tabela intermediária
TrailCourse(trail + course + sort) - Backfill: criar a trilha padrão e associar os cursos existentes por ordem de
sort - Admin: criar/editar trilhas com cursos inline; exibir a trilha no admin de
Course - Endpoints GET: listar trilhas, detalhe de trilha, cursos de uma trilha
- Testes para models, admin e views
Fora de escopo
— (não registrado na spec original)
Mudanças
Novos arquivos
apps/courses/models/trail.py— modelsTraileTrailCourseapps/courses/migrations/0023_trail_trailcourse.py— cria as tabelasapps/courses/migrations/0024_backfill_default_trail.py— seed: trilha padrão + cursos existentesapps/courses/views/trail_api.py—TrailListAPIView,TrailDetailAPIView,TrailCoursesAPIViewtests/courses/test_trail.py— testes de model, admin e views
Arquivos modificados
apps/courses/models/__init__.py— exportarTrail,TrailCourseapps/courses/admin.py—TrailAdmin(comTrailCourseInline) + exibir a trilha noCourseAdminapps/courses/serializers.py—TrailSerializer,TrailCourseSerializerapps/courses/urls.py— 3 novas rotas de trailapps/courses/views/__init__.py— exportar as novas views
Model Trail
python
code UniqueCodeField(size_code=6)
title CharField(255)
description RichTextField(blank, null)
is_active BooleanField(default=True)
sort PositiveIntegerField(default=0)
# Meta: ordering = ['sort'], verbose_name = "Trilha"
Tabela intermediária TrailCourse
python
trail ForeignKey(Trail, CASCADE, related_name="trail_courses")
course ForeignKey(Course, CASCADE, related_name="trail_courses")
sort PositiveIntegerField()
# unique_together: (trail, course), (trail, sort)
# ordering: ['sort']
Backfill (migration)
get_or_createdeTrailcomcode="TRAIL001",title="Trilha Padrão"- Se criada: associar todos os
Courseativos, ordenados porsort, viaTrailCourse
Endpoints
| Método | URL | View |
|—|—|—|
| GET | /v1/courses/trails | TrailListAPIView |
| GET | /v1/courses/trails/<trail_id> | TrailDetailAPIView |
| GET | /v1/courses/trails/<trail_id>/courses | TrailCoursesAPIView |
Serializers
TrailSerializer:id,code,title,description,is_active,sort,qty_coursesTrailCourseSerializer: usaCourseSerializerpara cada curso e adiciona osortda trilha
Como verificar
python manage.py migratesem erros- No admin: criar trilha, adicionar cursos via inline, reordenar via
sort GET /v1/courses/trails→ lista trilhas ativasGET /v1/courses/trails/1→ detalhe da trilhaGET /v1/courses/trails/1/courses→ cursos da trilha em ordempytest tests/courses/test_trail.py→ todos passam
Documentação
Documentar a regra de negócio de trilha e a dependência entre cursos.