api-admin Overview
apps/admin is the REST API for 4D operations staff. It is implemented with Hono + Bun and uses PostgreSQL as its data store. It provides CRUD for admin accounts, organizations, projects, and users, as well as session management backed by AWS Cognito.
Architecture
A 4-layer structure: Routes โ Services โ Repositories โ Database.
Client Request
โ
Middlewares (auth, logging, error handling)
โ
Routes (request validation, response formatting)
โ
Services (business logic)
โ
Repositories (data access)
โ
PostgreSQL / AWS Cognito
Key differences from api-user:
| Item | api-admin | api-user |
|---|---|---|
| Database | PostgreSQL | PostgreSQL |
| Session management | Token hash stored in PostgreSQL session table | Cognito JWT only |
Endpoint List
All endpoints are versioned under the /v1 prefix.
| Path | File | Description |
|---|---|---|
/v1/auth/* |
routes/v1/auth.ts |
Login, logout, session cleanup |
/v1/admins/* |
routes/v1/admin.ts |
Admin account CRUD |
/v1/organizations/* |
routes/v1/organization.ts |
Organization CRUD |
/v1/projects/* |
routes/v1/project.ts |
Project management |
/v1/users/* |
routes/v1/user.ts |
App user management |
/v1/projects/{project_id}/users/* |
routes/v1/user-project.ts |
Project user access assignments |
/v1/ping |
routes/v1/ping.ts |
Health check |
Middleware Pipeline
| Middleware | File | Role |
|---|---|---|
requestId() |
hono/request-id |
Attaches a unique request ID for tracing |
winstonLogger() |
middlewares/winston-logger.ts |
Structured request / response logging (including duration) |
cors() |
hono/cors |
Cross-origin resource sharing |
compress() |
hono/compress |
Gzip response compression |
protectedRoute |
middlewares/protected-route.ts |
JWT verification and Cognito sub extraction |
errorHandler |
middlewares/error-handler.ts |
Centralized error handling with unified response format |
Authentication and Session Flow
sequenceDiagram
participant Admin as Service Admin
participant API as API Gateway
participant Lambda as Lambda (api-admin)
participant Cognito as AWS Cognito
participant DB as PostgreSQL
Admin->>API: POST /v1/auth/login
API->>Lambda: Forward request
Lambda->>Cognito: initiateAuth()
Cognito-->>Lambda: JWT access token
Lambda->>DB: Create session (token_hash, IP, User-Agent)
Lambda-->>Admin: 200 { token, admin }
Admin->>API: Call protected endpoint
API->>Lambda: Authorization: Bearer <token>
Lambda->>Cognito: Verify JWT
Lambda->>DB: Look up session by token_hash
DB-->>Lambda: Session active
Lambda-->>Admin: Response
Admin->>API: POST /v1/auth/logout
API->>Lambda: Forward request
Lambda->>Cognito: globalSignOut()
Lambda->>DB: Revoke session (set revoked_at)
Lambda-->>Admin: 200
Session Lifecycle
stateDiagram-v2
[*] --> Created: Admin login
Created --> Active: Session stored in DB
Active --> Expired: expires_at passed
Active --> Revoked: Admin logout
Active --> Revoked: Password reset
Active --> Revoked: Global sign-out
Expired --> CleanedUp: Scheduled cleanup job
Revoked --> CleanedUp: Scheduled cleanup job
CleanedUp --> [*]: Soft deleted (deleted_at set)
Sessions are retained for SESSION_RETENTION_DAYS (default: 90 days) after expiry before being soft-deleted.
Error Handling
All errors are returned in the following JSON format.
| Status | Usage |
|---|---|
400 Bad Request |
Invalid input data |
401 Unauthorized |
Missing or invalid authentication |
403 Forbidden |
Insufficient permissions |
404 Not Found |
Resource not found |
409 Conflict |
Resource conflict (e.g. duplicate) |
500 Internal Server Error |
Unexpected server error |
Key Environment Variables
| Variable | Required | Description |
|---|---|---|
ADMIN_COGNITO_USER_POOL_ID |
Yes | AWS Cognito User Pool ID |
ADMIN_COGNITO_CLIENT_ID |
Yes | AWS Cognito App Client ID |
ADMIN_COGNITO_REGION |
No | AWS region (default: ap-northeast-1) |
DATABASE_NAME |
Yes | PostgreSQL database name |
DATABASE_USER |
Yes | PostgreSQL user |
DATABASE_PASSWORD |
Yes | PostgreSQL password |
DATABASE_HOST |
No | PostgreSQL host (default: localhost) |
DATABASE_PORT |
No | PostgreSQL port (default: 5432) |
SESSION_CLEANUP_API_KEY |
Yes | API key for session cleanup endpoint |
SESSION_RETENTION_DAYS |
No | Days to retain expired sessions (default: 90) |
ALLOWED_ORIGINS |
No | Comma-separated CORS origins |
PORT |
No | Server port (default: 8081) |