Files
warmbly/internal/api/handler/admin_organization.go
T
Matt 4b7a0be93d feat(admin): read-only organization endpoints
Wire three GET endpoints behind the existing admin middleware so the
admin app can browse workspaces alongside users:

  GET /admin/organizations              list with q/cursor/limit/sort
  GET /admin/organizations/:id          detail + plan/sub + limits + counts
  GET /admin/organizations/:id/members  full member list with joined users

The list query inlines member/email-account/campaign/active-campaign
counts via subqueries so the table can render usage without an extra
fetch per row. Detail layers GetOrganizationLimits + GetOrganizationCounts
on top of the list shape, ensuring admin sees the same numbers the in-app
limit checks enforce.

Gated on AdminPermViewUsers for now since orgs are tightly coupled to
user admin context today; a dedicated ViewOrganizations/ManageOrganizations
pair will land alongside the write paths (per-org overrides, ban scope)
in the next slice.
2026-05-28 08:39:13 +02:00

59 lines
1.6 KiB
Go

package handler
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/warmbly/warmbly/internal/errx"
"github.com/warmbly/warmbly/internal/models"
)
// AdminListOrganizations returns the paginated admin org listing.
func (h *Handler) AdminListOrganizations(c *gin.Context) {
var search models.AdminOrgSearch
if err := c.ShouldBindQuery(&search); err != nil {
errx.JSON(c, errx.New(errx.BadRequest, "invalid query parameters"))
return
}
result, xerr := h.OrganizationService.SearchOrganizationsForAdmin(c.Request.Context(), &search)
if xerr != nil {
errx.JSON(c, xerr)
return
}
c.JSON(http.StatusOK, result)
}
// AdminGetOrganization returns the detail payload for a single org.
func (h *Handler) AdminGetOrganization(c *gin.Context) {
orgID, err := uuid.Parse(c.Param("id"))
if err != nil {
errx.JSON(c, errx.New(errx.BadRequest, "invalid organization ID"))
return
}
detail, xerr := h.OrganizationService.GetOrganizationAdminDetail(c.Request.Context(), orgID)
if xerr != nil {
errx.JSON(c, xerr)
return
}
c.JSON(http.StatusOK, detail)
}
// AdminGetOrganizationMembers returns the members of an org with users.
func (h *Handler) AdminGetOrganizationMembers(c *gin.Context) {
orgID, err := uuid.Parse(c.Param("id"))
if err != nil {
errx.JSON(c, errx.New(errx.BadRequest, "invalid organization ID"))
return
}
members, xerr := h.OrganizationService.GetOrganizationMembersForAdmin(c.Request.Context(), orgID)
if xerr != nil {
errx.JSON(c, xerr)
return
}
c.JSON(http.StatusOK, &models.AdminOrgMembersResult{Data: members})
}