Skip to content

Delete Admin

Method

REST method is adopted.

HTTP Method

DELETE: Soft-delete an admin account

Naming Convention

To unify naming of query parameters and nodes and improve readability, snake_case is used for URIs and nodes in JSON during requests.

Request and Response

Headers

Meta information is set in HTTP headers rather than in the response body.

Request Headers

  • Authorization: Bearer <access_token>
  • Content-Type: application/json

Response Headers

  • Content-Type: application/json

Delete Admin

URI

Path parameter type is integer.

/api/v1/admins/{admin_id}

Response (200 OK)

Response is JSON. The admin record is soft-deleted (deletedAt is populated).

{
  "id": 2,
  "cognitoSub": "3333-cccc-4444-dddd",
  "roleId": 1,
  "name": "Deleted Admin",
  "createdAt": 1640995200000,
  "updatedAt": 1640995200000,
  "createdBy": "1111-aaaa-2222-bbbb",
  "updatedBy": "1111-aaaa-2222-bbbb",
  "deletedAt": 1640995200000,
  "deletedBy": "1111-aaaa-2222-bbbb",
  "role": {
    "id": 1,
    "name": "admin"
  }
}

Note: An admin cannot delete their own account. The system checks the actor's admin ID from the session against the target ID.

Authentication

Authentication is performed using JSON Web Tokens (JWT) issued by Amazon Cognito. A valid Bearer token is required in the Authorization header.

Exception Handling

Exception handling status codes are as follows.

Description Status Code Status Name
Missing or invalid token 401 Unauthorized
Admin not found 404 Not Found
Cannot delete own account 409 Conflict
Internal server error 500 Internal Server Error

Process Flow

Sequence Diagram

sequenceDiagram
    participant Client
    participant Middleware as Protected Route Middleware
    participant API as Hono Router
    participant Service as Admin Service
    participant Cognito as Admin Cognito Pool
    participant DB as PostgreSQL Database

    Client->>Middleware: DELETE /api/v1/admins/{admin_id}
    Middleware->>Middleware: Verify JWT & session

    alt Token Valid
        Middleware-->>API: Auth info (sub, session with adminId)
        API->>API: Extract actorAdminId from session

        alt Self-delete Check
            API->>Service: remove(id, actorSub, actorAdminId)
            Service->>Service: Check id !== actorAdminId

            alt Not Self-delete
                Service->>DB: findOneByIdOnly(id)
                DB-->>Service: Admin record

                alt Admin Found
                    Service->>Cognito: resolveUsernameBySub(cognitoSub)

                    alt Cognito User Exists
                        Cognito-->>Service: username
                        Service->>Cognito: adminDeleteUser(username)
                        Cognito-->>Service: Deleted
                    else No Cognito User
                        Service->>Service: Log warning (DB-only delete)
                    end

                    Service->>DB: softDelete(id, actorSub)
                    DB-->>Service: Soft-deleted admin
                    Service-->>API: Admin with deletedAt
                    API-->>Client: 200 OK
                else Admin Not Found
                    Service-->>API: throw NotFoundError
                    API-->>Client: 404 Not Found
                end
            else Self-delete Attempt
                Service-->>API: throw ConflictError
                API-->>Client: 409 Conflict
            end
        end
    else Token Invalid
        Middleware-->>Client: 401 Unauthorized
    end

Routes Layer

API routing is performed here. The protectedRoute middleware validates the JWT token. The handler extracts the admin_id path parameter, the actor's Cognito sub, and the actor's admin ID from the session context, then delegates to the admin service.

Source: apps/admin/src/routes/v1/admin.ts

Services Layer

This section describes business logic. It prevents self-deletion by comparing the target ID with the actor's admin ID from the session. It then finds the admin, deletes the corresponding Cognito user from the admin pool, and soft-deletes the database record.

Source: apps/admin/src/services/admin.ts

Repositories Layer

This section describes access to databases and external services. It handles Cognito username resolution, admin user deletion, and database soft-deletion.

Source: apps/admin/src/repositories/admin.ts / apps/admin/src/repositories/cognito-pool.ts

Security

  • Token validated by protectedRoute middleware before handler execution
  • Self-deletion is explicitly blocked (409 Conflict)
  • Uses the admin Cognito pool (separate from the app user pool)
  • If Cognito user is missing, DB soft-delete still proceeds (resilient to partial states)
  • Actor's Cognito sub recorded as deletedBy for audit trail