package api import ( "context" "net/http" "strconv" "time" "github.com/TopherMayor/unified-media-manager/internal/service" "github.com/labstack/echo/v4" ) func listRequests(reqSvc *service.RequestService, userSvc *service.UserService) echo.HandlerFunc { return func(c echo.Context) error { ctx, cancel := context.WithTimeout(c.Request().Context(), 10*time.Second) defer cancel() user := c.Get("user").(*service.User) page, pageSize := service.ParsePagination(c.QueryParam("page"), c.QueryParam("page_size")) filters := service.RequestFilters{ Status: c.QueryParam("status"), Page: page, PageSize: pageSize, } // Non-admin users can only see their own requests if user.Role != "admin" { userID := user.ID filters.RequestedBy = &userID } items, total, err := reqSvc.List(ctx, filters) if err != nil { return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) } return c.JSON(http.StatusOK, paginatedResponse{ Data: items, Total: total, Page: page, PageSize: pageSize, TotalPages: service.CalcTotalPages(total, pageSize), }) } } func createRequest(reqSvc *service.RequestService, userSvc *service.UserService) echo.HandlerFunc { return func(c echo.Context) error { ctx, cancel := context.WithTimeout(c.Request().Context(), 5*time.Second) defer cancel() user := c.Get("user").(*service.User) var req service.CreateRequest if err := c.Bind(&req); err != nil { return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()}) } if req.Title == "" { return c.JSON(http.StatusBadRequest, map[string]string{"error": "title is required"}) } id, err := reqSvc.Create(ctx, req, user.Role, user.ID) if err != nil { return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) } return c.JSON(http.StatusCreated, map[string]int64{"id": id}) } } func requestStats(reqSvc *service.RequestService, userSvc *service.UserService) echo.HandlerFunc { return func(c echo.Context) error { ctx, cancel := context.WithTimeout(c.Request().Context(), 5*time.Second) defer cancel() stats, err := reqSvc.Stats(ctx) if err != nil { return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) } return c.JSON(http.StatusOK, stats) } } func approveRequest(reqSvc *service.RequestService, userSvc *service.UserService) echo.HandlerFunc { return func(c echo.Context) error { ctx, cancel := context.WithTimeout(c.Request().Context(), 10*time.Second) defer cancel() user := c.Get("user").(*service.User) if user.Role != "admin" { return c.JSON(http.StatusForbidden, map[string]string{"error": "admin access required"}) } id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid id"}) } var body struct { Notes string `json:"notes"` } _ = c.Bind(&body) if err := reqSvc.Approve(ctx, id, user.ID, body.Notes); err != nil { return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()}) } return c.JSON(http.StatusOK, map[string]string{"status": "approved"}) } } func rejectRequest(reqSvc *service.RequestService, userSvc *service.UserService) echo.HandlerFunc { return func(c echo.Context) error { ctx, cancel := context.WithTimeout(c.Request().Context(), 5*time.Second) defer cancel() user := c.Get("user").(*service.User) if user.Role != "admin" { return c.JSON(http.StatusForbidden, map[string]string{"error": "admin access required"}) } id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid id"}) } var body struct { Notes string `json:"notes"` } _ = c.Bind(&body) if err := reqSvc.Reject(ctx, id, user.ID, body.Notes); err != nil { return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()}) } return c.JSON(http.StatusOK, map[string]string{"status": "rejected"}) } } func withdrawRequest(reqSvc *service.RequestService, userSvc *service.UserService) echo.HandlerFunc { return func(c echo.Context) error { ctx, cancel := context.WithTimeout(c.Request().Context(), 5*time.Second) defer cancel() user := c.Get("user").(*service.User) id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid id"}) } if err := reqSvc.Withdraw(ctx, id, user.ID); err != nil { return c.JSON(http.StatusBadRequest, map[string]string{"error": err.Error()}) } return c.JSON(http.StatusOK, map[string]string{"status": "withdrawn"}) } }