組織削除
メソッド
REST メソッドを採用しています。
HTTP メソッド
DELETE: 組織の削除(ソフトデリート)
命名規則
クエリパラメータとノードの命名を統一し、可読性を向上させるため、リクエスト時の URI と JSON 内のノードには snake_case を使用します。
リクエストとレスポンス
ヘッダー
メタ情報はレスポンスボディではなく、HTTP ヘッダーに設定されます。
リクエストヘッダー
Authorization:Bearer <access_token>Content-Type:application/json
レスポンスヘッダー
Content-Type:application/json
組織削除
URI
パスパラメータの型は integer です。
パスパラメータ
| 名前 | 型 | 説明 |
|---|---|---|
| organization_id | integer | 必須。組織を識別する正の整数。 |
レスポンス(200 OK)
レスポンスは JSON です。組織レコードはソフトデリートされ、deletedAt と deletedBy が設定されます。行自体はデータベースに残ります。
{
"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"
}
認証要件
Amazon Cognito が発行する JSON Web Token(JWT)を用いた認証です。Authorization ヘッダーに有効な Bearer トークンが必要です。
例外処理
例外時のステータスコードは次のとおりです。
| 説明 | ステータスコード | ステータス名 |
|---|---|---|
| トークンが欠落または無効 | 401 | Unauthorized |
| 組織が見つからない | 404 | Not Found |
| 組織が既に削除済み(競合) | 409 | Conflict |
| サーバ内部エラー | 500 | Internal Server Error |
処理フロー
シーケンス図
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 層
ルーティングはここで行います。protectedRoute ミドルウェアが JWT とセッションを検証してからハンドラが実行されます。ハンドラは organization_id パスパラメータを取り出し、組織サービスに委譲します。
ソース: apps/admin/src/routes/v1/organization.ts
Services 層
ビジネスロジックの説明です。ID で組織を取得し、存在し未ソフトデリートであることを確認します。続いて所属ユーザーとプロジェクトをカスケード削除します(各ユーザーを AWS Cognito と DB から削除)。最後に deletedAt と deletedBy を設定して組織をソフトデリートします。
ソース: apps/admin/src/services/organization.ts
Repositories 層
データベースおよび外部サービスへのアクセスです。組織・ユーザー・プロジェクトの参照、ユーザーの DB 削除、プロジェクト削除、組織レコードのソフトデリート更新を扱います。
ソース: apps/admin/src/repositories/organization.ts
セキュリティ
- ハンドラ実行前に
protectedRouteミドルウェアがトークンを検証します verifySessionによりセッションの存在を確認します- パスパラメータは正の整数として検証され、インジェクションを防ぎます
- カスケード削除により、組織削除後に孤立したユーザー/プロジェクトが残りません
- AWS Cognito のユーザーも明示的に削除し、認証アイデンティティの孤立を防ぎます