Delete Organization
Method
REST method is adopted.
HTTP Method
DELETE: Delete an organization (soft delete)
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 Organization
URI
Path parameter type is integer.
Path Parameters
| Name | Type | Description |
|---|---|---|
| organization_id | integer | Required. Must be a positive integer identifying the organization. |
Response (200 OK)
Response is JSON. The organization record is soft-deleted: deletedAt and deletedBy are populated while the row remains in the database.
{
"id": 1,
"name": "Example Organization",
"createdAt": 1640995200000,
"updatedAt": 1641081600000,
"createdBy": "1111-aaaa-2222-bbbb",
"updatedBy": "1111-aaaa-2222-bbbb",
"deletedAt": 1641168000000,
"deletedBy": "3333-cccc-4444-dddd"
}
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 |
| Organization not found | 404 | Not Found |
| Organization already deleted (conflict) | 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 Organization Service
participant Repository as Organization Repository
participant Cognito as AWS Cognito
participant DB as PostgreSQL Database
Client->>Middleware: DELETE /api/v1/organizations/{organization_id}
Middleware->>Middleware: Extract Bearer token
Middleware->>Middleware: Verify JWT & session
alt Token Valid
Middleware-->>API: Auth info (sub, adminId)
API->>Service: remove(id, adminId)
Service->>Repository: findOneById(id)
Repository->>DB: SELECT FROM organizations WHERE id = ?
alt Organization Not Found
DB-->>Repository: null
Repository-->>Service: null
Service-->>API: throw NotFoundError
API-->>Client: 404 Not Found
else Organization Already Deleted
DB-->>Repository: Organization with deletedAt
Repository-->>Service: Organization (soft-deleted)
Service-->>API: throw ConflictError
API-->>Client: 409 Conflict
else Organization Found
DB-->>Repository: Organization record
Repository-->>Service: Organization (active)
Service->>Repository: findAllUsersByOrgId(orgId)
Repository->>DB: SELECT FROM users WHERE org_id = ?
DB-->>Repository: User list
loop For each user in organization
Service->>Cognito: deleteCognitoUser(user.cognitoSub)
Cognito-->>Service: User deleted
Service->>Repository: deleteUser(userId)
Repository->>DB: DELETE FROM users WHERE id = ?
DB-->>Repository: User deleted
end
Service->>Repository: findAllProjectsByOrgId(orgId)
Repository->>DB: SELECT FROM projects WHERE org_id = ?
DB-->>Repository: Project list
loop For each project in organization
Service->>Repository: deleteProject(projectId)
Repository->>DB: DELETE FROM projects WHERE id = ?
DB-->>Repository: Project deleted
end
Service->>Repository: softDeleteOrg(orgId, adminId)
Repository->>DB: UPDATE organizations SET deleted_at, deleted_by WHERE id = ?
DB-->>Repository: Organization soft-deleted
Repository-->>Service: Deleted organization
Service-->>API: Organization data with deletedAt
API-->>Client: 200 OK { id, name, deletedAt, deletedBy, ... }
end
else Token Invalid
Middleware-->>Client: 401 Unauthorized
end
Routes Layer
API routing is performed here. The protectedRoute middleware validates the JWT token and session before the handler executes. The handler extracts the organization_id path parameter and delegates to the organization service.
Source: apps/admin/src/routes/v1/organization.ts
Services Layer
This section describes business logic. It retrieves the organization by ID and verifies it exists and is not already soft-deleted. It then cascade-deletes all users belonging to the organization (removing each from AWS Cognito and the database) and all projects belonging to the organization. Finally, it soft-deletes the organization itself by populating deletedAt and deletedBy.
Source: apps/admin/src/services/organization.ts
Repositories Layer
This section describes access to databases and external services. It performs lookups for the organization, its users, and its projects. It also handles user deletion from the database, project deletion, and the soft-delete update on the organization record.
Source: apps/admin/src/repositories/organization.ts
Security
- Token validated by
protectedRoutemiddleware before handler execution - Session existence verified via
verifySession - Path parameter validated as positive integer to prevent injection
- Cascade deletion ensures no orphaned users or projects remain after organization deletion
- AWS Cognito users are explicitly removed to prevent orphaned authentication identities