- Add video upload endpoint POST /courses/:id/lessons/:lesson_id/video - Add VideoTranscodeService for multi-bitrate HLS (720p/480p/360p) - Add VideoTranscodeWorker for async lesson video processing - Add SetLessonVideoPath and UpdateLessonTranscoding to education service - Add uploadLessonVideo to frontend educationService with progress - Add comprehensive handler tests (video upload, auth, validation) - Add service-level tests (models, slugs, clamping, errors, UUIDs) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
70 lines
2.6 KiB
Go
70 lines
2.6 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/lessons/:lesson_id/video", handler.UploadLessonVideo)
|
|
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)
|
|
}
|