From 57f0db269a4b4c8db28dcd1446db1510846c92af Mon Sep 17 00:00:00 2001 From: Yared Yemane Date: Tue, 14 Apr 2026 09:21:13 -0700 Subject: [PATCH] add legacy category courses GET endpoint for compatibility Expose GET /course-management/categories/:categoryId/courses so legacy tab/API callers no longer fail with Cannot GET during initial content load. Made-with: Cursor --- .../web_server/handlers/hierarchy_handler.go | 50 +++++++++++++++++++ internal/web_server/routes.go | 1 + 2 files changed, 51 insertions(+) diff --git a/internal/web_server/handlers/hierarchy_handler.go b/internal/web_server/handlers/hierarchy_handler.go index a9f5a41..d4a4e21 100644 --- a/internal/web_server/handlers/hierarchy_handler.go +++ b/internal/web_server/handlers/hierarchy_handler.go @@ -188,6 +188,56 @@ func (h *Handler) ListCourseCategories(c *fiber.Ctx) error { }) } +// ListCoursesByCategory godoc +// @Summary List courses by category +// @Description Legacy-compatible endpoint that returns courses for one category +// @Tags course-management +// @Produce json +// @Param categoryId path int true "Category ID" +// @Param offset query int false "Offset" +// @Param limit query int false "Limit" +// @Success 200 {object} domain.Response +// @Failure 400 {object} domain.ErrorResponse +// @Failure 500 {object} domain.ErrorResponse +// @Router /api/v1/course-management/categories/{categoryId}/courses [get] +func (h *Handler) ListCoursesByCategory(c *fiber.Ctx) error { + categoryID, err := strconv.ParseInt(c.Params("categoryId"), 10, 64) + if err != nil || categoryID <= 0 { + return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{Message: "Invalid category ID", Error: "categoryId must be a positive integer"}) + } + + offset := int32(c.QueryInt("offset", 0)) + if offset < 0 { + offset = 0 + } + limit := int32(c.QueryInt("limit", 10000)) + if limit <= 0 { + limit = 10000 + } + + rows, err := h.analyticsDB.GetCoursesByCategory(c.Context(), dbgen.GetCoursesByCategoryParams{ + CategoryID: categoryID, + Offset: pgtype.Int4{Int32: offset, Valid: true}, + Limit: pgtype.Int4{Int32: limit, Valid: true}, + }) + if err != nil { + return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{Message: "Failed to load courses", Error: err.Error()}) + } + + total := 0 + if len(rows) > 0 { + total = int(rows[0].TotalCount) + } + + return c.JSON(domain.Response{ + Message: "Courses retrieved successfully", + Data: map[string]interface{}{ + "courses": rows, + "total_count": total, + }, + }) +} + // CreateCourseCategory godoc // @Summary Create course category // @Description Legacy-compatible endpoint for creating a course category diff --git a/internal/web_server/routes.go b/internal/web_server/routes.go index 3accf3e..50f0784 100644 --- a/internal/web_server/routes.go +++ b/internal/web_server/routes.go @@ -80,6 +80,7 @@ func (a *App) initAppRoutes() { // Unified Course Management (single hierarchy model) groupV1.Get("/course-management/categories", a.authMiddleware, a.RequirePermission("learning_tree.get"), h.ListCourseCategories) + groupV1.Get("/course-management/categories/:categoryId/courses", a.authMiddleware, a.RequirePermission("learning_tree.get"), h.ListCoursesByCategory) groupV1.Post("/course-management/categories", a.authMiddleware, a.RequirePermission("course_categories.create"), h.CreateCourseCategory) groupV1.Delete("/course-management/categories/:categoryId", a.authMiddleware, a.RequirePermission("course_categories.delete"), h.DeleteCourseCategory) groupV1.Post("/course-management/courses", a.authMiddleware, a.RequirePermission("courses.create"), h.CreateCourse)