Yimaru-BackEnd/internal/web_server/routes.go

357 lines
25 KiB
Go

package httpserver
import (
"Yimaru-Backend/internal/domain"
"Yimaru-Backend/internal/web_server/handlers"
"context"
"fmt"
"strconv"
"github.com/gofiber/fiber/v2"
fiberSwagger "github.com/swaggo/fiber-swagger"
)
func (a *App) initAppRoutes() {
h := handlers.New(
a.assessmentSvc,
a.courseSvc,
a.questionsSvc,
a.subscriptionsSvc,
a.arifpaySvc,
a.logger,
a.settingSvc,
a.NotidicationStore,
a.validator,
a.recommendationSvc,
a.userSvc,
a.transactionSvc,
a.authSvc,
a.vimeoSvc,
a.teamSvc,
a.activityLogSvc,
a.issueReportingSvc,
a.cloudConvertSvc,
a.ratingSvc,
a.rbacSvc,
a.JwtConfig,
a.cfg,
a.mongoLoggerSvc,
a.analyticsDB,
)
a.fiber.Get("/", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"message": "Welcome to Yimaru Backend API",
"version": a.cfg.APP_VERSION,
})
})
a.fiber.Get("/routes", func(c *fiber.Ctx) error {
return c.JSON(a.fiber.Stack()) // prints all registered routes
})
// Groups
groupV1 := a.fiber.Group("/api/v1")
// Serve static files (profile pictures, etc.)
a.fiber.Static("/static", "./static")
// Swagger
a.fiber.Get("/swagger/*", fiberSwagger.FiberWrapHandler())
groupV1.Get("/", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"message": "Welcome to Yimaru Backend API v1",
"version": "1.0.1",
})
})
// Assessment questions (public)
groupV1.Post("/assessment/questions", h.CreateAssessmentQuestion)
groupV1.Get("/assessment/questions", h.ListAssessmentQuestions)
groupV1.Get("/assessment/questions/:id", h.GetAssessmentQuestionByID)
// Reorder (drag-and-drop support)
// Keep static reorder routes before dynamic `/:id` routes to avoid route collisions
// (e.g., `/courses/reorder` being parsed as `/courses/:id`).
groupV1.Put("/course-management/categories/reorder", a.authMiddleware, a.RequirePermission("course_categories.reorder"), h.ReorderCourseCategories)
groupV1.Put("/course-management/courses/reorder", a.authMiddleware, a.RequirePermission("courses.reorder"), h.ReorderCourses)
groupV1.Put("/course-management/sub-courses/reorder", a.authMiddleware, a.RequirePermission("subcourses.reorder"), h.ReorderSubCourses)
groupV1.Put("/course-management/videos/reorder", a.authMiddleware, a.RequirePermission("videos.reorder"), h.ReorderSubCourseVideos)
groupV1.Put("/course-management/practices/reorder", a.authMiddleware, a.RequirePermission("practices.reorder"), h.ReorderPractices)
// Course Categories
groupV1.Post("/course-management/categories", a.authMiddleware, a.RequirePermission("course_categories.create"), h.CreateCourseCategory)
groupV1.Get("/course-management/categories", a.authMiddleware, a.RequirePermission("course_categories.list"), h.GetAllCourseCategories)
groupV1.Get("/course-management/categories/:id", a.authMiddleware, a.RequirePermission("course_categories.get"), h.GetCourseCategoryByID)
groupV1.Put("/course-management/categories/:id", a.authMiddleware, a.RequirePermission("course_categories.update"), h.UpdateCourseCategory)
groupV1.Delete("/course-management/categories/:id", a.authMiddleware, a.RequirePermission("course_categories.delete"), h.DeleteCourseCategory)
// Courses
groupV1.Post("/course-management/courses", a.authMiddleware, a.RequirePermission("courses.create"), h.CreateCourse)
groupV1.Get("/course-management/courses/:id", a.authMiddleware, a.RequirePermission("courses.get"), h.GetCourseByID)
groupV1.Get("/course-management/categories/:categoryId/courses", a.authMiddleware, a.RequirePermission("courses.list_by_category"), h.GetCoursesByCategory)
groupV1.Put("/course-management/courses/:id", a.authMiddleware, a.RequirePermission("courses.update"), h.UpdateCourse)
groupV1.Post("/course-management/courses/:id/thumbnail", a.authMiddleware, a.RequirePermission("courses.upload_thumbnail"), h.UploadCourseThumbnail)
groupV1.Delete("/course-management/courses/:id", a.authMiddleware, a.RequirePermission("courses.delete"), h.DeleteCourse)
// Sub-courses
groupV1.Post("/course-management/sub-courses", a.authMiddleware, a.RequirePermission("subcourses.create"), h.CreateSubCourse)
groupV1.Get("/course-management/sub-courses/:id", a.authMiddleware, a.RequirePermission("subcourses.get"), h.GetSubCourseByID)
groupV1.Get("/course-management/courses/:courseId/sub-courses", a.authMiddleware, a.RequirePermission("subcourses.list_by_course"), h.GetSubCoursesByCourse)
groupV1.Get("/course-management/courses/:courseId/sub-courses/list", a.authMiddleware, a.RequirePermission("subcourses.list_by_course_list"), h.ListSubCoursesByCourse)
groupV1.Get("/course-management/sub-courses/active", a.authMiddleware, a.RequirePermission("subcourses.list_active"), h.ListActiveSubCourses)
groupV1.Patch("/course-management/sub-courses/:id", a.authMiddleware, a.RequirePermission("subcourses.update"), h.UpdateSubCourse)
groupV1.Post("/course-management/sub-courses/:id/thumbnail", a.authMiddleware, a.RequirePermission("subcourses.upload_thumbnail"), h.UploadSubCourseThumbnail)
groupV1.Put("/course-management/sub-courses/:id/deactivate", a.authMiddleware, a.RequirePermission("subcourses.deactivate"), h.DeactivateSubCourse)
groupV1.Delete("/course-management/sub-courses/:id", a.authMiddleware, a.RequirePermission("subcourses.delete"), h.DeleteSubCourse)
// Sub-course Videos
groupV1.Post("/course-management/videos", a.authMiddleware, a.RequirePermission("videos.create"), h.CreateSubCourseVideo)
groupV1.Post("/course-management/videos/vimeo", a.authMiddleware, a.RequirePermission("videos.create_vimeo"), h.CreateSubCourseVideoWithVimeo)
groupV1.Post("/course-management/videos/upload", a.authMiddleware, a.RequirePermission("videos.upload"), h.UploadSubCourseVideo)
groupV1.Post("/course-management/videos/vimeo/import", a.authMiddleware, a.RequirePermission("videos.import_vimeo"), h.CreateSubCourseVideoFromVimeoID)
groupV1.Get("/course-management/videos/:id", a.authMiddleware, a.RequirePermission("videos.get"), h.GetSubCourseVideoByID)
groupV1.Get("/course-management/sub-courses/:subCourseId/videos", a.authMiddleware, a.RequirePermission("videos.list_by_subcourse"), h.GetVideosBySubCourse)
groupV1.Get("/course-management/sub-courses/:subCourseId/videos/published", a.authMiddleware, a.RequirePermission("videos.list_published"), h.GetPublishedVideosBySubCourse)
groupV1.Put("/course-management/videos/:id/publish", a.authMiddleware, a.RequirePermission("videos.publish"), h.PublishSubCourseVideo)
groupV1.Put("/course-management/videos/:id", a.authMiddleware, a.RequirePermission("videos.update"), h.UpdateSubCourseVideo)
groupV1.Delete("/course-management/videos/:id", a.authMiddleware, a.RequirePermission("videos.delete"), h.DeleteSubCourseVideo)
// Learning Tree
groupV1.Get("/course-management/learning-tree", a.authMiddleware, a.RequirePermission("learning_tree.get"), h.GetFullLearningTree)
groupV1.Get("/course-management/courses/:courseId/learning-path", a.authMiddleware, a.RequirePermission("learning_tree.get"), h.GetCourseLearningPath)
// Questions
groupV1.Post("/questions", a.authMiddleware, a.RequirePermission("questions.create"), h.CreateQuestion)
groupV1.Get("/questions", a.authMiddleware, a.RequirePermission("questions.list"), h.ListQuestions)
groupV1.Get("/questions/search", a.authMiddleware, a.RequirePermission("questions.search"), h.SearchQuestions)
groupV1.Get("/questions/:id", a.authMiddleware, a.RequirePermission("questions.get"), h.GetQuestionByID)
groupV1.Put("/questions/:id", a.authMiddleware, a.RequirePermission("questions.update"), h.UpdateQuestion)
groupV1.Delete("/questions/:id", a.authMiddleware, a.RequirePermission("questions.delete"), h.DeleteQuestion)
// Question Sets
groupV1.Post("/question-sets", a.authMiddleware, a.RequirePermission("question_sets.create"), h.CreateQuestionSet)
groupV1.Get("/question-sets", a.authMiddleware, a.RequirePermission("question_sets.list"), h.GetQuestionSetsByType)
groupV1.Get("/question-sets/by-owner", a.authMiddleware, a.RequirePermission("question_sets.list_by_owner"), h.GetQuestionSetsByOwner)
groupV1.Get("/question-sets/sub-courses/:subCourseId/entry-assessment", a.authMiddleware, a.RequirePermission("question_sets.list_by_owner"), h.GetSubCourseEntryAssessmentSet)
groupV1.Get("/question-sets/:id", a.authMiddleware, a.RequirePermission("question_sets.get"), h.GetQuestionSetByID)
groupV1.Put("/question-sets/:id", a.authMiddleware, a.RequirePermission("question_sets.update"), h.UpdateQuestionSet)
groupV1.Delete("/question-sets/:id", a.authMiddleware, a.RequirePermission("question_sets.delete"), h.DeleteQuestionSet)
// Question Set Items
groupV1.Post("/question-sets/:setId/questions", a.authMiddleware, a.RequirePermission("question_set_items.add"), h.AddQuestionToSet)
groupV1.Get("/question-sets/:setId/questions", a.authMiddleware, a.RequirePermission("question_set_items.list"), h.GetQuestionsInSet)
groupV1.Delete("/question-sets/:setId/questions/:questionId", a.authMiddleware, a.RequirePermission("question_set_items.remove"), h.RemoveQuestionFromSet)
groupV1.Put("/question-sets/:setId/questions/:questionId/order", a.authMiddleware, a.RequirePermission("question_set_items.update_order"), h.UpdateQuestionOrderInSet)
// Question Set Personas
groupV1.Get("/question-sets/:setId/personas", a.authMiddleware, a.RequirePermission("question_set_personas.list"), h.GetUserPersonasByQuestionSet)
groupV1.Post("/question-sets/:setId/personas", a.authMiddleware, a.RequirePermission("question_set_personas.add"), h.AddUserPersonaToQuestionSet)
groupV1.Delete("/question-sets/:setId/personas/:userId", a.authMiddleware, a.RequirePermission("question_set_personas.remove"), h.RemoveUserPersonaFromQuestionSet)
// Subscription Plans
groupV1.Post("/subscription-plans", a.authMiddleware, a.RequirePermission("subscription_plans.create"), h.CreateSubscriptionPlan)
groupV1.Get("/subscription-plans", h.ListSubscriptionPlans)
groupV1.Get("/subscription-plans/:id", h.GetSubscriptionPlan)
groupV1.Put("/subscription-plans/:id", a.authMiddleware, a.RequirePermission("subscription_plans.update"), h.UpdateSubscriptionPlan)
groupV1.Delete("/subscription-plans/:id", a.authMiddleware, a.RequirePermission("subscription_plans.delete"), h.DeleteSubscriptionPlan)
// User Subscriptions
groupV1.Post("/subscriptions", a.authMiddleware, a.RequirePermission("subscriptions.create"), h.Subscribe)
groupV1.Post("/subscriptions/checkout", a.authMiddleware, a.RequirePermission("subscriptions.checkout"), h.SubscribeWithPayment)
groupV1.Get("/subscriptions/me", a.authMiddleware, a.RequirePermission("subscriptions.get_mine"), h.GetMySubscription)
groupV1.Get("/subscriptions/history", a.authMiddleware, a.RequirePermission("subscriptions.history"), h.GetMySubscriptionHistory)
groupV1.Get("/subscriptions/status", a.authMiddleware, a.RequirePermission("subscriptions.status"), h.CheckSubscriptionStatus)
groupV1.Post("/subscriptions/:id/cancel", a.authMiddleware, a.RequirePermission("subscriptions.cancel"), h.CancelSubscription)
groupV1.Put("/subscriptions/:id/auto-renew", a.authMiddleware, a.RequirePermission("subscriptions.set_auto_renew"), h.SetAutoRenew)
// Payments (ArifPay)
groupV1.Post("/payments/subscribe", a.authMiddleware, a.RequirePermission("payments.initiate"), h.InitiateSubscriptionPayment)
groupV1.Get("/payments/verify/:session_id", a.authMiddleware, a.RequirePermission("payments.verify"), h.VerifyPayment)
groupV1.Get("/payments", a.authMiddleware, a.RequirePermission("payments.list_mine"), h.GetMyPayments)
groupV1.Get("/payments/:id", a.authMiddleware, a.RequirePermission("payments.get"), h.GetPaymentByID)
groupV1.Post("/payments/:id/cancel", a.authMiddleware, a.RequirePermission("payments.cancel"), h.CancelPayment)
groupV1.Get("/payments/methods", h.GetArifpayPaymentMethods)
groupV1.Post("/payments/webhook", h.HandleArifpayWebhook)
// Direct Payments
groupV1.Post("/payments/direct", a.authMiddleware, a.RequirePermission("payments.direct_initiate"), h.InitiateDirectPayment)
groupV1.Post("/payments/direct/verify-otp", a.authMiddleware, a.RequirePermission("payments.direct_verify_otp"), h.VerifyDirectPaymentOTP)
groupV1.Get("/payments/direct/methods", h.GetDirectPaymentMethods)
// Auth Routes (public)
groupV1.Post("/auth/google/android", h.GoogleAndroidLogin)
groupV1.Get("/auth/google/login", h.GoogleLogin)
groupV1.Get("/auth/google/callback", h.GoogleCallback)
groupV1.Post("/auth/customer-login", h.LoginUser)
groupV1.Post("/auth/admin-login", h.LoginAdmin)
groupV1.Post("/auth/super-login", h.LoginSuper)
groupV1.Post("/auth/refresh", h.RefreshToken)
groupV1.Post("/user/:id/profile-picture", a.authMiddleware, a.RequirePermission("users.upload_profile_picture"), h.UploadProfilePicture)
groupV1.Post("/auth/logout", a.authMiddleware, a.RequirePermission("auth.logout"), h.LogOutuser)
groupV1.Get("/auth/test", a.authMiddleware, func(c *fiber.Ctx) error {
userID, ok := c.Locals("user_id").(int64)
if !ok {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid user ID")
}
role, ok := c.Locals("role").(domain.Role)
if !ok {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid role")
}
refreshToken, ok := c.Locals("refresh_token").(string)
if !ok {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid refresh token")
}
companyID, err := strconv.ParseInt(c.Get("company_id"), 10, 64)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid company_id")
}
a.logger.Info("User ID: " + strconv.FormatInt(userID, 10))
fmt.Printf("User ID: %d\n", userID)
a.logger.Info("Role: " + string(role))
a.logger.Info("Refresh Token: " + refreshToken)
a.logger.Info("Company ID: " + strconv.FormatInt(companyID, 10))
return c.SendString("Test endpoint")
})
// User Routes
groupV1.Get("/user/:user_id/is-profile-completed", a.authMiddleware, a.RequirePermission("users.profile_completed"), h.CheckProfileCompleted)
groupV1.Get("/users", a.authMiddleware, a.RequirePermission("users.list"), h.GetAllUsers)
groupV1.Get("/users/summary", a.authMiddleware, a.RequirePermission("users.summary"), h.GetUserSummary)
groupV1.Put("/user", a.authMiddleware, a.RequirePermission("users.update_self"), h.UpdateUser)
groupV1.Patch("/user/status", a.authMiddleware, a.RequirePermission("users.update_status"), h.UpdateUserStatus)
groupV1.Put("/user/knowledge-level", h.UpdateUserKnowledgeLevel)
groupV1.Get("/user/:user_name/is-pending", h.CheckUserPending)
groupV1.Post("/user/resetPassword", h.ResetPassword)
groupV1.Post("/user/sendResetCode", h.SendResetCode)
groupV1.Post("/user/verify-otp", h.VerifyOtp)
groupV1.Post("/user/resend-otp", h.ResendOtp)
groupV1.Post("/user/register", h.RegisterUser)
groupV1.Post("/user/sendRegisterCode", h.SendRegisterCode)
groupV1.Post("/user/checkPhoneEmailExist", h.CheckPhoneEmailExist)
groupV1.Get("/user/admin-profile", a.authMiddleware, a.RequirePermission("users.admin_profile"), h.AdminProfile)
groupV1.Get("/user/user-profile", a.authMiddleware, a.RequirePermission("users.user_profile"), h.GetUserProfile)
groupV1.Get("/user/single/:id", a.authMiddleware, a.RequirePermission("users.get"), h.GetUserByID)
groupV1.Delete("/user/delete/:id", a.authMiddleware, a.RequirePermission("users.delete"), h.DeleteUser)
groupV1.Post("/user/search", a.authMiddleware, a.RequirePermission("users.search"), h.SearchUserByNameOrPhone)
// Admin management
groupV1.Get("/admin", a.authMiddleware, a.RequirePermission("admins.list"), h.GetAllAdmins)
groupV1.Get("/admin/:id", a.authMiddleware, a.RequirePermission("admins.get"), h.GetAdminByID)
groupV1.Post("/admin", a.authMiddleware, a.RequirePermission("admins.create"), h.CreateAdmin)
groupV1.Put("/admin/:id", a.authMiddleware, a.RequirePermission("admins.update"), h.UpdateAdmin)
// Logs
groupV1.Get("/logs", a.authMiddleware, a.RequirePermission("logs.list"), handlers.GetLogsHandler(context.Background()))
groupV1.Get("/activity-logs", a.authMiddleware, a.RequirePermission("activity_logs.list"), h.GetActivityLogs)
groupV1.Get("/activity-logs/:id", a.authMiddleware, a.RequirePermission("activity_logs.get"), h.GetActivityLogByID)
// Notifications
groupV1.Post("/sendSMS", h.SendSingleAfroSMS)
groupV1.Get("/ws/connect", a.WebsocketAuthMiddleware, h.ConnectSocket)
groupV1.Get("/notifications", a.authMiddleware, a.RequirePermission("notifications.list_mine"), h.GetUserNotification)
groupV1.Get("/notifications/all", a.authMiddleware, a.RequirePermission("notifications.list_all"), h.GetAllNotifications)
groupV1.Patch("/notifications/:id/read", a.authMiddleware, a.RequirePermission("notifications.mark_read"), h.MarkNotificationAsRead)
groupV1.Post("/notifications/mark-all-read", a.authMiddleware, a.RequirePermission("notifications.mark_all_read"), h.MarkAllNotificationsAsRead)
groupV1.Patch("/notifications/:id/unread", a.authMiddleware, a.RequirePermission("notifications.mark_unread"), h.MarkNotificationAsUnread)
groupV1.Post("/notifications/mark-all-unread", a.authMiddleware, a.RequirePermission("notifications.mark_all_unread"), h.MarkAllNotificationsAsUnread)
groupV1.Delete("/notifications", a.authMiddleware, a.RequirePermission("notifications.delete_mine"), h.DeleteUserNotifications)
groupV1.Get("/notifications/unread", a.authMiddleware, a.RequirePermission("notifications.count_unread"), h.CountUnreadNotifications)
groupV1.Post("/notifications/create", a.authMiddleware, a.RequirePermission("notifications.create"), h.CreateAndSendNotification)
// Issues
groupV1.Post("/issues", a.authMiddleware, a.RequirePermission("issues.create"), h.CreateIssue)
groupV1.Get("/issues/me", a.authMiddleware, a.RequirePermission("issues.list_mine"), h.GetMyIssues)
groupV1.Get("/issues/user/:user_id", a.authMiddleware, a.RequirePermission("issues.list_by_user"), h.GetUserIssues)
groupV1.Get("/issues", a.authMiddleware, a.RequirePermission("issues.list_all"), h.GetAllIssues)
groupV1.Get("/issues/:id", a.authMiddleware, a.RequirePermission("issues.get"), h.GetIssueByID)
groupV1.Patch("/issues/:id/status", a.authMiddleware, a.RequirePermission("issues.update_status"), h.UpdateIssueStatus)
groupV1.Delete("/issues/:id", a.authMiddleware, a.RequirePermission("issues.delete"), h.DeleteIssue)
// Devices
groupV1.Post("/devices/register", a.authMiddleware, a.RequirePermission("devices.register"), h.RegisterDeviceToken)
groupV1.Post("/devices/unregister", a.authMiddleware, a.RequirePermission("devices.unregister"), h.UnregisterDeviceToken)
// Push Notifications
groupV1.Post("/notifications/test-push", a.authMiddleware, a.RequirePermission("notifications.test_push"), h.SendTestPushNotification)
groupV1.Post("/notifications/bulk-push", a.authMiddleware, a.RequirePermission("notifications.bulk_push"), h.SendBulkPushNotification)
groupV1.Post("/notifications/bulk-sms", a.authMiddleware, a.RequirePermission("notifications.bulk_sms"), h.SendBulkSMS)
groupV1.Post("/notifications/send-email", a.authMiddleware, a.RequirePermission("notifications.send_email"), h.SendSingleEmail)
groupV1.Post("/notifications/bulk-email", a.authMiddleware, a.RequirePermission("notifications.bulk_email"), h.SendBulkEmail)
// Scheduled Notifications
groupV1.Get("/notifications/scheduled", a.authMiddleware, a.RequirePermission("notifications_scheduled.list"), h.ListScheduledNotifications)
groupV1.Get("/notifications/scheduled/:id", a.authMiddleware, a.RequirePermission("notifications_scheduled.get"), h.GetScheduledNotification)
groupV1.Post("/notifications/scheduled/:id/cancel", a.authMiddleware, a.RequirePermission("notifications_scheduled.cancel"), h.CancelScheduledNotification)
// Settings
groupV1.Get("/settings", a.authMiddleware, a.RequirePermission("settings.list"), h.GetGlobalSettingList)
groupV1.Get("/settings/:key", a.authMiddleware, a.RequirePermission("settings.get"), h.GetGlobalSettingByKey)
groupV1.Put("/settings", a.authMiddleware, a.RequirePermission("settings.update"), h.UpdateGlobalSettingList)
// Analytics
groupV1.Get("/analytics/dashboard", a.authMiddleware, a.RequirePermission("analytics.dashboard"), h.GetAnalyticsDashboard)
// Vimeo
vimeoGroup := groupV1.Group("/vimeo")
vimeoGroup.Get("/videos/:video_id", a.authMiddleware, a.RequirePermission("vimeo.videos.get"), h.GetVimeoVideo)
vimeoGroup.Get("/videos/:video_id/embed", a.authMiddleware, a.RequirePermission("vimeo.videos.embed"), h.GetEmbedCode)
vimeoGroup.Get("/videos/:video_id/status", a.authMiddleware, a.RequirePermission("vimeo.videos.status"), h.GetTranscodeStatus)
vimeoGroup.Delete("/videos/:video_id", a.authMiddleware, a.RequirePermission("vimeo.videos.delete"), h.DeleteVimeoVideo)
vimeoGroup.Post("/uploads/pull", a.authMiddleware, a.RequirePermission("vimeo.uploads.pull"), h.CreatePullUpload)
vimeoGroup.Post("/uploads/tus", a.authMiddleware, a.RequirePermission("vimeo.uploads.tus"), h.CreateTusUpload)
vimeoGroup.Get("/oembed", h.GetOEmbed)
vimeoGroup.Get("/sample", h.GetSampleVideo)
// Team Management
teamGroup := groupV1.Group("/team")
teamGroup.Post("/login", h.TeamMemberLogin)
teamGroup.Get("/me", a.authMiddleware, a.RequirePermission("team.profile.get_mine"), h.GetMyTeamProfile)
teamGroup.Get("/stats", a.authMiddleware, a.RequirePermission("team.stats"), h.GetTeamMemberStats)
teamGroup.Get("/members", a.authMiddleware, a.RequirePermission("team.members.list"), h.GetAllTeamMembers)
teamGroup.Post("/members", a.authMiddleware, a.RequirePermission("team.members.create"), h.CreateTeamMember)
teamGroup.Get("/members/:id", a.authMiddleware, a.RequirePermission("team.members.get"), h.GetTeamMember)
teamGroup.Put("/members/:id", a.authMiddleware, a.RequirePermission("team.members.update"), h.UpdateTeamMember)
teamGroup.Patch("/members/:id/status", a.authMiddleware, a.RequirePermission("team.members.update_status"), h.UpdateTeamMemberStatus)
teamGroup.Delete("/members/:id", a.authMiddleware, a.RequirePermission("team.members.delete"), h.DeleteTeamMember)
teamGroup.Post("/members/:id/change-password", a.authMiddleware, a.RequirePermission("team.members.change_password"), h.ChangeTeamMemberPassword)
// Sub-course Prerequisites
groupV1.Post("/course-management/sub-courses/:id/prerequisites", a.authMiddleware, a.RequirePermission("subcourse_prerequisites.add"), h.AddSubCoursePrerequisite)
groupV1.Get("/course-management/sub-courses/:id/prerequisites", a.authMiddleware, a.RequirePermission("subcourse_prerequisites.list"), h.GetSubCoursePrerequisites)
groupV1.Delete("/course-management/sub-courses/:id/prerequisites/:prerequisiteId", a.authMiddleware, a.RequirePermission("subcourse_prerequisites.remove"), h.RemoveSubCoursePrerequisite)
// User Progression
groupV1.Post("/progress/sub-courses/:id/start", a.authMiddleware, a.RequirePermission("progress.start"), h.StartSubCourse)
groupV1.Put("/progress/sub-courses/:id", a.authMiddleware, a.RequirePermission("progress.update"), h.UpdateSubCourseProgress)
groupV1.Post("/progress/sub-courses/:id/complete", a.authMiddleware, a.RequirePermission("progress.complete"), h.CompleteSubCourse)
groupV1.Post("/progress/videos/:id/complete", a.authMiddleware, a.RequirePermission("progress.update"), h.CompleteSubCourseVideo)
groupV1.Post("/progress/practices/:id/complete", a.authMiddleware, a.RequirePermission("progress.update"), h.CompletePractice)
groupV1.Get("/progress/sub-courses/:id/access", a.authMiddleware, a.RequirePermission("progress.check_access"), h.CheckSubCourseAccess)
groupV1.Get("/progress/courses/:courseId", a.authMiddleware, a.RequirePermission("progress.get_course"), h.GetUserCourseProgress)
// Ratings
groupV1.Post("/ratings", a.authMiddleware, a.RequirePermission("ratings.submit"), h.SubmitRating)
groupV1.Get("/ratings", a.authMiddleware, a.RequirePermission("ratings.list_by_target"), h.GetRatingsByTarget)
groupV1.Get("/ratings/summary", a.authMiddleware, a.RequirePermission("ratings.summary"), h.GetRatingSummary)
groupV1.Get("/ratings/me", a.authMiddleware, a.RequirePermission("ratings.get_mine"), h.GetMyRating)
groupV1.Get("/ratings/me/all", a.authMiddleware, a.RequirePermission("ratings.list_mine"), h.GetMyRatings)
groupV1.Delete("/ratings/:id", a.authMiddleware, a.RequirePermission("ratings.delete"), h.DeleteRating)
// RBAC Management
rbacGroup := groupV1.Group("/rbac", a.authMiddleware)
rbacGroup.Get("/roles", a.RequirePermission("rbac.roles.list"), h.ListRoles)
rbacGroup.Get("/roles/:id", a.RequirePermission("rbac.roles.get"), h.GetRoleByID)
rbacGroup.Post("/roles", a.RequirePermission("rbac.roles.create"), h.CreateRole)
rbacGroup.Put("/roles/:id", a.RequirePermission("rbac.roles.update"), h.UpdateRole)
rbacGroup.Delete("/roles/:id", a.RequirePermission("rbac.roles.delete"), h.DeleteRole)
rbacGroup.Put("/roles/:id/permissions", a.RequirePermission("rbac.roles.set_permissions"), h.SetRolePermissions)
rbacGroup.Get("/roles/:id/permissions", a.RequirePermission("rbac.roles.get_permissions"), h.GetRolePermissions)
rbacGroup.Get("/permissions", a.RequirePermission("rbac.permissions.list"), h.ListPermissions)
rbacGroup.Get("/permissions/groups", a.RequirePermission("rbac.permissions.groups"), h.ListPermissionGroups)
rbacGroup.Post("/permissions/sync", a.RequirePermission("rbac.permissions.sync"), h.SyncPermissions)
}