7.8 KiB
7.8 KiB
Frontend API Surface (Backend: Current Spring Boot)
Use this as the exact frontend integration reference for the existing backend.
1) API Envelope
Most responses use:
type ApiResponse<T> = {
success: boolean
message: string
data: T
timestamp: string
}
Error policy (actual backend behavior)
- Business errors and validation in request payloads return HTTP
400with:{ success: false, message: "...", data: null, timestamp: "..." }
- Authorization failures return HTTP
403:{ success: false, message: "Access denied", data: null, timestamp: "..." }
- Unhandled internal exceptions return HTTP
500with:{ success: false, message: "Internal server error", data: null, timestamp: "..." }
- Authentication failures from Spring Security typically return
401and are handled by frontend interceptor. - JWT/session validation/blacklist failures can return
401or be handled by security filters before controller.
2) Global request headers
For every protected request after login:
Authorization: Bearer <accessToken>X-Tenant-Id: <tenantId>- Optional:
Accept-Language: en-USorid-ID
POST /api/auth/login also requires:
X-Tenant-Id
3) Auth APIs
POST /api/auth/login
Request:
{ username: string; password: string }
Success (200):
{
"success": true,
"message": "Login successful",
"data": {
"tokenType": "Bearer",
"accessToken": "eyJhbGciOiJIUzI1NiJ9...",
"refreshToken": "...",
"expiresInSeconds": 900
}
}
Common login failures:
401: invalid credentials from security layer400:{ message: "Invalid username or password" }400:{ message: "Account locked. Please try again in {0} seconds" }- LDAP mode + not provisioned local tenant user:
{ message: "LDAP user authenticated but not provisioned in this tenant" }
POST /api/auth/refresh
Request:
{ refreshToken: string }
Success:
{
"success": true,
"message": "Token refreshed successfully",
"data": {
"tokenType": "Bearer",
"accessToken": "...",
"refreshToken": "...",
"expiresInSeconds": 900
}
}
Failure:
400with messageRefresh token not found/Token expired or revoked
POST /api/auth/logout
Request headers:
AuthorizationandX-Tenant-Id- optional body
Success:
{ "success": true, "message": "Logout successful", "data": null }
4) Profile API
GET /api/users/me
Success:
{
"success": true,
"message": "Current user fetched successfully",
"data": {
"tenantId": "acme",
"username": "alice",
"roles": ["ADMIN", "USER_ROLE_ADMIN"],
"permissions": ["USER_MANAGE", "WORKFLOW_APPROVE", "ROLE_MANAGE"]
}
}
Use roles and permissions for:
- menu visibility
- action visibility
- route guards
5) Tenant APIs
GET /api/tenant/context
{ tenantId: "acme" }
6) User Management APIs (Workflow-first)
POST /api/users/management/requests/create
Local mode (default)
{
username: string,
password: string, // required local mode
enabled?: boolean,
roleCodes: string[]
}
LDAP mode
{
username: string,
ldapDn?: string, // optional metadata
enabled?: boolean,
roleCodes: string[]
}
Success always returns workflow request:
{
"success": true,
"message": "User management request created",
"data": {
"id": "uuid",
"resourceType": "USER_MANAGEMENT",
"resourceId": "jane",
"status": "PENDING",
"requiredSteps": 1,
"currentStep": 0
}
}
POST /api/users/management/requests/update-roles
{ username: string; roleCodes: string[] }
Returns same response shape as approval response.
7) Role Management APIs (Workflow-first)
POST /api/roles/management/requests/create
{ code: string; name: string; permissionCodes: string[] }
POST /api/roles/management/requests/update-permissions
{ code: string; permissionCodes: string[] }
Both return ApprovalResponse with request status PENDING.
8) Workflow APIs
POST /api/workflow/request
Generic endpoint for custom workflow request:
{
resourceType: string,
resourceId: string,
payload: string,
requiredSteps: number
}
GET /api/workflow/requests
Query params:
status=DRAFT|PENDING|APPROVED|REJECTED(optional)resourceType(optional)makerUsername(optional)limitdefault50, max internally clamped to200
Response list item:
{
id: "uuid",
tenantId: "acme",
resourceType: "USER_MANAGEMENT",
resourceId: "jane",
makerUsername: "alice",
payload: "{\"operation\":\"CREATE_USER\",...}",
status: "PENDING",
requiredSteps: 1,
currentStep: 0,
createdAt: "2026-04-20T08:00:00Z",
updatedAt: "2026-04-20T08:00:00Z"
}
POST /api/workflow/{id}/approve
{ notes?: string; checkerRole?: string }
- If
checkerRoleomitted, backend uses step role default (CHECKERunless overridden by system default). - Maker cannot approve own request.
- Success returns updated
ApprovalResponse.
POST /api/workflow/{id}/reject
{ notes?: string; checkerRole?: string }
Same behavior and guards as approve.
9) Module APIs (Admin only)
GET /api/modules
Returns:
{ code: string; name: string; enabled: boolean }[]
POST /api/modules/{code}/toggle
{ enabled: boolean }
Requires admin role.
10) Audit APIs (Admin only)
GET /api/audit?limit=50
Response items include at least:
id,tenantId,actor,correlationId,action,domain,resourceType,resourceId,outcome,httpMethod,requestPath,beforeState,afterState,details,createdAt.
Used for security/auditor trail and troubleshooting.
11) Statuses and RBAC to gate UI
- Approval status from backend:
DRAFT,PENDING,APPROVED,REJECTED. - User create / update role actions:
USER_MANAGEORUSER_ROLE_ADMIN - Role create / update permissions:
ROLE_MANAGEORUSER_ROLE_ADMIN - Workflow approve/reject:
WORKFLOW_APPROVEORCHECKER - Workflow list:
WORKFLOW_APPROVEORCHECKERORADMIN - Audit & modules listing/toggle:
ADMIN - Profile (
/api/users/me):USER_READORADMIN
12) Frontend negative-path checklist (QA-ready)
- Login without tenant header should fail on protected flows.
- Login with valid credentials but wrong tenant should fail on tenant-dependent services.
- Repeated wrong password:
- eventually returns lockout message after configured threshold.
- Create user (local mode) without password -> shows localized required validation error.
- Create user (LDAP mode) with password payload should still be accepted by UI only if intentionally sent; backend ignores and should not rely on it.
- Create user request duplicate username returns
400 User already exists. - Workflow approve/reject where maker == checker returns error message
Maker cannot approve own request. - Approving/rejecting without proper role returns
403. - Audit API called by non-admin should return
403. - Refresh with invalid token returns
400and clear token state.
13) Suggested QA smoke script
- Validate auth:
- login, refresh, me, logout
- Validate tenant:
- switch tenant header and ensure data partitions by tenant
- Validate management flow:
- create user (local/LDAP variant) -> should appear in workflow as
PENDING - role create -> approval created
- approve/reject -> state transition to
APPROVED/REJECTED
- create user (local/LDAP variant) -> should appear in workflow as
- Validate guard:
- hide actions by permissions and re-check with token from restricted user
14) Setup checklist
- Create
.env.local:NEXT_PUBLIC_API_BASE_URL=http://localhost:9191NEXT_PUBLIC_DEFAULT_TENANT=acmeNEXT_PUBLIC_LOCALE=en
- npm install / pnpm install
- Add Axios interceptor for auth and tenant headers
- Add 401/403 interceptor handling for logout and route redirect