openapi: "3.0.3" info: title: Nova Web Admin API version: "v1.0" description: | Open API for Nova web admin — `staffManagement` controller. **Routing**: query params `ctrl`, `api`, `ver` **Auth**: Guest (no JWT required for these endpoints) ### Success HTTP `200` — server returns the DTO object **directly** (no wrapper envelope). ```json { "user_id": "abc123", "role": "ADMIN" } ``` ### Error HTTP `4XX` / `5XX` — JSON body: ```json { "code": "110506", "message": "Invalid username or password", "details": [{ "source": "username", "issue": "invalid credentials" }] } ``` `code` format: `XXYYZZ` — `XX`=error type, `YY`=project, `ZZ`=specific error (auto-increment). - Base codes: `sysErrCode = 100500` (system), `pkgErrCode = 110500` (business) #### System errors (`1005ZZ`) | Code | Description | |------|-------------| | `100501` | Database connection error | | `100502` | Database query error | | `100503` | Unknown internal server error | | `100504` | Timeout calling external service | | `100505` | Internal data parse / unmarshal error | #### Business errors (`1105ZZ`) | Code | Description | |------|-------------| | `110506` | Invalid username or password | | `110507` | Account disabled (`is_active = false`) | | `110508` | Account locked (too many failed attempts) | | `110509` | Must change password before continuing | | `110510` | Invalid or expired OTP code | | `110512` | Duplicate `request_id` (replay attack detected) | | `110513` | User not found | | `110514` | Insufficient permissions (forbidden) | | `110515` | Invalid request data (validation failed) | | `110516` | Phone number already exists | | `110517` | Username already exists | | `110518` | Email already linked to another staff account | | `110519` | OTP session expired (5-minute intermediate window) | | `110520` | Account blocked — too many failed OTP attempts (requires admin unblock) | servers: - url: "{endpoint}" variables: endpoint: default: https://s3dommv4yh.execute-api.mx-central-1.amazonaws.com/default/dev-omni-nova-client-web description: Base URL of the Lambda / API Gateway endpoint paths: # ─── Auth ───────────────────────────────────────────────────────────────── "/?ctrl=staffManagementCtl&api=login&ver=v1": $ref: "./paths/auth.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3Dlogin%26ver%3Dv1.0" "/?ctrl=staffManagementCtl&api=verifyOTP&ver=v1": $ref: "./paths/auth.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3DverifyOTP%26ver%3Dv1.0" "/?ctrl=staffManagementCtl&api=cancelOTPSession&ver=v1": $ref: "./paths/auth.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3DcancelOTPSession%26ver%3Dv1.0" # ─── Google Auth / 2FA Setup ────────────────────────────────────────────── "/?ctrl=staffManagementCtl&api=generateGAQRCode&ver=v1": $ref: "./paths/google_auth.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3DgenerateGAQRCode%26ver%3Dv1.0" "/?ctrl=staffManagementCtl&api=enrollKeyVault&ver=v1": $ref: "./paths/google_auth.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3DenrollKeyVault%26ver%3Dv1.0" # ─── Client User ────────────────────────────────────────────────────────── "/?ctrl=staffManagementCtl&api=createClientUser&ver=v1": $ref: "./paths/client_user.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3DcreateClientUser%26ver%3Dv1.0" "/?ctrl=staffManagementCtl&api=listClientUsers&ver=v1": $ref: "./paths/client_user.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3DlistClientUsers%26ver%3Dv1.0" # ─── Staff User ─────────────────────────────────────────────────────────── "/?ctrl=staffManagementCtl&api=createStaffUser&ver=v1": $ref: "./paths/staff_user.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3DcreateStaffUser%26ver%3Dv1.0" "/?ctrl=staffManagementCtl&api=generateStaffUsername&ver=v1": $ref: "./paths/staff_user.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3DgenerateStaffUsername%26ver%3Dv1.0" "/?ctrl=staffManagementCtl&api=listStaffUsers&ver=v1": $ref: "./paths/staff_user.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3DlistStaffUsers%26ver%3Dv1.0" # ─── Config ─────────────────────────────────────────────────────────────── "/?ctrl=staffManagementCtl&api=getConfig&ver=v1": $ref: "./paths/config.yaml#/paths/~1%3Fctrl%3DuserMamagement%26api%3DgetConfig%26ver%3Dv1.0" # ─── Session ────────────────────────────────────────────────────────────── "/?ctrl=staffManagementCtl&api=init-session&ver=v1": post: operationId: initSession summary: Initialize a tracking session for staff description: | Generates a unique `tracking_id` for the current staff session. The `tracking_id` uses the Nova prefix and is backed by the database sequence. tags: [staffManagement] responses: "200": description: Session initialized — tracking ID returned. content: application/json: schema: $ref: "#/components/schemas/InitSessionResponse" example: jwt: "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..." "401": $ref: "#/components/responses/ClientError" "500": $ref: "#/components/responses/ServerError" components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT # ─── Reusable responses ─────────────────────────────────────────────────── responses: ClientError: description: | Client error (HTTP 4XX). Invalid request, missing params, validation failure, or auth error. content: application/json: schema: $ref: "#/components/schemas/ApiError" example: code: "110515" message: "Invalid request data (validation failed)" details: - source: "username" issue: "required" ServerError: description: Internal server error (HTTP 5XX). content: application/json: schema: $ref: "#/components/schemas/ApiError" example: code: "100503" message: "Unknown internal server error" details: [] schemas: # ── Base ────────────────────────────────────────────────────────────────── ApiError: $ref: "./components.yaml#/components/schemas/ApiError" # ── Session ─────────────────────────────────────────────────────────────── InitSessionResponse: $ref: "./components.yaml#/components/schemas/InitSessionResponse" # ── Auth ────────────────────────────────────────────────────────────────── LoginRequest: $ref: "./components.yaml#/components/schemas/LoginRequest" LoginResponse: $ref: "./components.yaml#/components/schemas/LoginResponse" VerifyOTPRequest: $ref: "./components.yaml#/components/schemas/VerifyOTPRequest" VerifyOTPResponse: $ref: "./components.yaml#/components/schemas/VerifyOTPResponse" CancelOTPSessionRequest: $ref: "./components.yaml#/components/schemas/CancelOTPSessionRequest" # ── Google Auth / 2FA Setup ─────────────────────────────────────────────── GenerateGAQRCodeRequest: $ref: "./components.yaml#/components/schemas/GenerateGAQRCodeRequest" GenerateGAQRCodeResponse: $ref: "./components.yaml#/components/schemas/GenerateGAQRCodeResponse" EnrollKeyVaultRequest: $ref: "./components.yaml#/components/schemas/EnrollKeyVaultRequest" EnrollKeyVaultResponse: $ref: "./components.yaml#/components/schemas/EnrollKeyVaultResponse" # ── Client User ─────────────────────────────────────────────────────────── CreateClientUserRequest: $ref: "./components.yaml#/components/schemas/CreateClientUserRequest" CreateClientUserResponse: $ref: "./components.yaml#/components/schemas/CreateClientUserResponse" ClientUserItem: $ref: "./components.yaml#/components/schemas/ClientUserItem" ListClientUsersResponse: $ref: "./components.yaml#/components/schemas/ListClientUsersResponse" # ── Staff User ──────────────────────────────────────────────────────────── CreateStaffUserRequest: $ref: "./components.yaml#/components/schemas/CreateStaffUserRequest" CreateStaffUserResponse: $ref: "./components.yaml#/components/schemas/CreateStaffUserResponse" GenerateStaffUsernameRequest: $ref: "./components.yaml#/components/schemas/GenerateStaffUsernameRequest" GenerateStaffUsernameResponse: $ref: "./components.yaml#/components/schemas/GenerateStaffUsernameResponse" StaffUserItem: $ref: "./components.yaml#/components/schemas/StaffUserItem" ListStaffUsersResponse: $ref: "./components.yaml#/components/schemas/ListStaffUsersResponse" # ── Config ──────────────────────────────────────────────────────────────── GetConfigResponse: $ref: "./components.yaml#/components/schemas/GetConfigResponse"