veza/veza-backend-api/internal/api/routes_education.go
senke 9cd0a43f7e feat(v0.12.3): F276-F305 education backend service, handler, and routes
- Course CRUD with slug generation, publish/archive lifecycle
- Lesson management with ordering and transcoding status
- Enrollment system with duplicate prevention
- Progress tracking with auto-completion at 90%
- Certificate issuance requiring full course completion
- Course reviews with rating aggregation
- Unit tests for service and handler layers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 09:45:26 +01:00

69 lines
2.5 KiB
Go

package api
import (
"github.com/gin-gonic/gin"
"veza-backend-api/internal/core/education"
"veza-backend-api/internal/handlers"
)
// setupEducationRoutes configures routes for Formation & Éducation (v0.12.3 F276-F305)
func (r *APIRouter) setupEducationRoutes(router *gin.RouterGroup) {
svc := education.NewService(r.db.GormDB, r.logger)
handler := handlers.NewEducationHandler(svc, r.logger)
// Public course catalog
coursePublic := router.Group("/courses")
coursePublic.GET("", handler.ListPublishedCourses)
coursePublic.GET("/:id", handler.GetCourse)
coursePublic.GET("/:id/lessons", handler.GetCourseLessons)
coursePublic.GET("/:id/reviews", handler.GetCourseReviews)
coursePublic.GET("/slug/:slug", handler.GetCourseBySlug)
// Public certificate verification
router.GET("/certificates/:code", handler.VerifyCertificate)
if r.config.AuthMiddleware == nil {
return
}
// Course management (requires auth)
courseAuth := router.Group("/courses")
courseAuth.Use(r.config.AuthMiddleware.RequireAuth())
r.applyCSRFProtection(courseAuth)
courseAuth.POST("", handler.CreateCourse)
courseAuth.PUT("/:id", handler.UpdateCourse)
courseAuth.DELETE("/:id", handler.DeleteCourse)
courseAuth.POST("/:id/publish", handler.PublishCourse)
courseAuth.POST("/:id/archive", handler.ArchiveCourse)
courseAuth.POST("/:id/lessons", handler.CreateLesson)
courseAuth.PUT("/:id/lessons/:lesson_id", handler.UpdateLesson)
courseAuth.DELETE("/:id/lessons/:lesson_id", handler.DeleteLesson)
courseAuth.POST("/:id/lessons/reorder", handler.ReorderLessons)
courseAuth.POST("/:id/enroll", handler.Enroll)
courseAuth.GET("/:id/progress", handler.GetCourseProgress)
courseAuth.POST("/:id/certificate", handler.IssueCertificate)
courseAuth.POST("/:id/reviews", handler.CreateReview)
// Enrollments (requires auth)
enrollAuth := router.Group("/enrollments")
enrollAuth.Use(r.config.AuthMiddleware.RequireAuth())
enrollAuth.GET("", handler.GetMyEnrollments)
// Progress (requires auth)
lessonAuth := router.Group("/lessons")
lessonAuth.Use(r.config.AuthMiddleware.RequireAuth())
r.applyCSRFProtection(lessonAuth)
lessonAuth.POST("/:lesson_id/progress", handler.UpdateProgress)
// Certificates (requires auth for user's own)
certAuth := router.Group("/certificates")
certAuth.Use(r.config.AuthMiddleware.RequireAuth())
certAuth.GET("", handler.GetMyCertificates)
// Creator courses list
creatorAuth := router.Group("/creators/me")
creatorAuth.Use(r.config.AuthMiddleware.RequireAuth())
creatorAuth.GET("/courses", handler.ListCreatorCourses)
}