# CTR-nn · contracts/openapi/.yaml — OpenAPI 3.1 # Nguồn: ICD_

§3 (IF-nnn) · API_ của BA · SRS §4.1 (mã lỗi) · SEC §3 (quyền) # Quy ước: ICD §1 — số lớn là string, thời gian date-time UTC, lỗi nghiệp vụ 4xx, phân trang theo ADR-nnn openapi: 3.1.0 info: title: API version: 1.0.0 description: | Contract cho IF-nnn. Tài liệu này THẮNG bảng mô tả trong ICD/API khi lệch. Mã lỗi theo SRS §4.1; quyền theo SEC §3. servers: - url: https://api./v1 description: production - url: https://api-stg./v1 description: staging tags: - name: security: - bearerAuth: [] paths: /: get: operationId: .list summary: tags: [] x-if: IF-nnn x-roles: [ROLE-01, ROLE-02] x-error-codes: [E--0401, E--0403, E--0503] parameters: - $ref: '#/components/parameters/PageCursor' - $ref: '#/components/parameters/PageSize' responses: '200': description: Danh sách content: application/json: schema: $ref: '#/components/schemas/Page' examples: ok: value: { items: [], nextCursor: null, hasNext: false } '401': { $ref: '#/components/responses/Unauthorized' } '403': { $ref: '#/components/responses/Forbidden' } '503': { $ref: '#/components/responses/Unavailable' } post: operationId: .create summary: tags: [] x-if: IF-nnn x-roles: [ROLE-01] x-idempotency: header Idempotency-Key, giữ 24h (ADR-nnn) x-error-codes: [E--0400, E--0409, E--0503] parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Create' examples: ok: value: { name: "Cửa hàng 01" } responses: '201': description: Đã tạo content: application/json: schema: { $ref: '#/components/schemas/' } '200': description: Trùng Idempotency-Key — trả bản ghi cũ, không tạo mới content: application/json: schema: { $ref: '#/components/schemas/' } '400': { $ref: '#/components/responses/BadRequest' } '409': { $ref: '#/components/responses/Conflict' } '503': { $ref: '#/components/responses/Unavailable' } components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT parameters: IdempotencyKey: name: Idempotency-Key in: header required: true schema: { type: string, maxLength: 64 } PageCursor: name: cursor in: query schema: { type: string } PageSize: name: size in: query schema: { type: integer, minimum: 1, maximum: 100, default: 20 } schemas: Id: type: string description: Số lớn truyền dạng string (ICD §1 điểm 1) pattern: '^[0-9a-f-]{36}$' Money: type: object required: [amount, currency] properties: amount: { type: string, pattern: '^-?[0-9]+(\.[0-9]{1,2})?$', description: 'decimal dạng string' } currency: { type: string, minLength: 3, maxLength: 3, example: VND } Error: type: object required: [code, message] properties: code: { type: string, pattern: '^E-[A-Z]+-[0-9]{4}$', description: 'Mã lỗi SRS §4.1' } message: { type: string, description: 'Text hiển thị theo SRS §4.2 hoặc mã để client dịch (ICD §1 điểm 6)' } details: type: array items: type: object properties: field: { type: string } code: { type: string } : type: object required: [id, createdAt] properties: id: { $ref: '#/components/schemas/Id' } createdAt: { type: string, format: date-time, description: 'UTC ISO-8601' } Create: type: object required: [name] properties: name: { type: string, minLength: 1, maxLength: 40, description: '40 code point — khớp FLD--nn' } Page: type: object required: [items, hasNext] properties: items: { type: array, items: { $ref: '#/components/schemas/' } } nextCursor: { type: [string, 'null'] } hasNext: { type: boolean } responses: BadRequest: description: Sai dữ liệu vào content: { application/json: { schema: { $ref: '#/components/schemas/Error' }, example: { code: E--0400, message: "…" } } } Unauthorized: description: Hết phiên content: { application/json: { schema: { $ref: '#/components/schemas/Error' } } } Forbidden: description: Không đủ quyền — client không xoá dữ liệu đã nhập (ICD §6) content: { application/json: { schema: { $ref: '#/components/schemas/Error' } } } Conflict: description: Vi phạm ràng buộc nghiệp vụ (BR-nnn) content: { application/json: { schema: { $ref: '#/components/schemas/Error' } } } Unavailable: description: Phụ thuộc hỏng/timeout (FAIL FM-nn) — client cho thử lại, giữ dữ liệu đã nhập content: { application/json: { schema: { $ref: '#/components/schemas/Error' } } }