Skip to content

[Feature]: Admin organization routes have no delete, and the list cannot be paginated or searched #131

Description

@Bccorb

Problem statement

The admin organization routes are less capable than the other admin collections, and the gap blocks work in the dashboard.

Every organization route currently exposed, from openapi.json at 4bbed05:

GET    /admin/organizations                                    params: []
POST   /admin/organizations                                    params: []
GET    /admin/organizations/{organizationId}                   params: [organizationId]
PATCH  /admin/organizations/{organizationId}                   params: [organizationId]
GET    /admin/organizations/{organizationId}/members           params: [organizationId]
POST   /admin/organizations/{organizationId}/members           params: [organizationId]
PATCH  /admin/organizations/{organizationId}/members/{userId}  params: [organizationId, userId]
DELETE /admin/organizations/{organizationId}/members/{userId}  params: [organizationId, userId]

Two gaps:

1. An organization cannot be deleted. The only DELETE in the group removes a member. There is no DELETE /admin/organizations/{organizationId}, so an organization created by mistake, or belonging to an offboarded tenant, can only be edited, never removed.

2. GET /admin/organizations accepts no query parameters. It returns { organizations, total } with no limit, offset, or search, so a caller receives whatever the endpoint returns and cannot request a window or ask the server to filter.

This is inconsistent with the neighbouring admin collections, which is what makes it feel unintended rather than deliberate:

Endpoint Pagination Filtering
GET /admin/auth-events limit, offset userId, type, from, to
GET /admin/sessions limit, offset none
GET /admin/organizations none none

Proposed solution

  • Add DELETE /admin/organizations/{organizationId}, with explicit semantics for existing memberships: either refuse while members remain (409) or cascade and document it. Whichever is chosen, it should be stated in the OpenAPI description, since the caller has to warn the operator accordingly.
  • Add limit and offset to GET /admin/organizations, matching the shape /admin/sessions already uses (limit with a sane default and maximum, offset defaulting to 0). total is already returned, so the response shape does not need to change.
  • Optionally add a search parameter over name and slug.

Alternatives considered

The dashboard currently filters the returned array in memory. That is fine for a small deployment and is commented as such, but it cannot reach an organization the endpoint did not return, so it is a stopgap rather than a solution.

Leaving deletion out entirely was also considered. It is defensible if organizations are meant to be permanent, but nothing in the API or docs says so, and the member routes do support removal, so the current state reads as an omission rather than a policy.

Impact area

Developer experience

Additional context

Blocks fells-code/seamless-auth-admin-dashboard#219, which has the dashboard side of this: a delete action gated behind confirmation and step-up, and server-driven pagination through the existing table component. Nothing there can ship until these routes exist, since a Remove button that 404s or a pager that cannot fetch page two is worse than the current honest limitation.

Related: fells-code/seamless-auth-admin-dashboard#220 raises the same search question for /admin/sessions, which has limit/offset but no search either. Worth deciding once for both collections rather than answering it differently per endpoint.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions