Skip to content

Delete User

Method

REST method is adopted.

HTTP Method

DELETE: Soft-delete a user

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 User

URI

Path parameter type is integer.

/api/v1/users/{user_id}

Response (200 OK)

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

{
  "id": 1,
  "cognitoSub": "1111-aaaa-2222-bbbb",
  "organizationId": 1,
  "name": "John Doe",
  "createdAt": 1640995200000,
  "updatedAt": 1640995200000,
  "createdBy": "1111-aaaa-2222-bbbb",
  "updatedBy": "1111-aaaa-2222-bbbb",
  "deletedAt": 1640995200000,
  "deletedBy": "1111-aaaa-2222-bbbb"
}

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
User not found 404 Not Found
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 User Service
    participant Cognito as App Cognito Pool
    participant DB as PostgreSQL Database

    Client->>Middleware: DELETE /api/v1/users/{user_id}
    Middleware->>Middleware: Verify JWT & session

    alt Token Valid
        Middleware-->>API: Auth info (sub)
        API->>Service: remove(id, actorSub)
        Service->>DB: findOneByIdOnly(id)
        DB-->>Service: User record

        alt User 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 user
            Service-->>API: User with deletedAt
            API-->>Client: 200 OK
        else User Not Found
            Service-->>API: throw NotFoundError
            API-->>Client: 404 Not Found
        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 user_id path parameter and actor's Cognito sub, then delegates to the user service.

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

Services Layer

This section describes business logic. It finds the user, deletes the corresponding Cognito user from the app pool, then soft-deletes the database record. If the Cognito user is not found, it logs a warning and proceeds with the DB soft-delete only.

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

Repositories Layer

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

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

Security

  • Token validated by protectedRoute middleware before handler execution
  • Cognito user is deleted in addition to database soft-delete
  • If Cognito user is missing, DB soft-delete still proceeds (resilient to partial states)
  • Actor's Cognito sub recorded as deletedBy for audit trail