# CTR-nn · contracts/asyncapi/-events.yaml — AsyncAPI 3.0 # Nguồn: ICD_

§4 (hợp đồng sự kiện) · DOM_

§5 (domain event) · DAT §4.1 (outbox/saga) · SEC §5 (PII) # Quy ước: at-least-once, người nhận khử trùng bằng eventId; breaking change ⇒ eventVersion mới + channel mới asyncapi: 3.0.0 info: title: Events version: 1.0.0 description: | Sự kiện phát từ CMP-nn qua IF-nnn. File này THẮNG bảng ICD §4 khi lệch. Không chứa PII ngoài id trừ khi SEC §5 cho phép đích danh. defaultContentType: application/json servers: prod: host: protocol: sqs # kafka | sqs | amqp | eventbridge description: production channels: orderPlaced: address: ..v1 description: Phát khi aggregate commit xong (DOM §5); publish qua outbox (ADR-nnn) messages: OrderPlaced: $ref: '#/components/messages/OrderPlaced' operations: publishOrderPlaced: action: send channel: { $ref: '#/channels/orderPlaced' } summary: CMP-nn publish — IF-nnn x-if: IF-nnn x-producer: CMP-nn x-consumers: [CMP-06, CMP-09] x-ordering: theo partition key x-delivery: at-least-once · DLQ giữ 14 ngày (FAIL FM-nn) components: messages: OrderPlaced: name: OrderPlaced title: Đơn hàng đã đặt contentType: application/json headers: $ref: '#/components/schemas/EventHeaders' payload: $ref: '#/components/schemas/OrderPlacedPayload' examples: - name: ok headers: { eventId: "018f…", eventVersion: "1.0", occurredAt: "2026-09-22T03:00:00Z", correlationId: "req-…" } payload: { orderId: "018f…", customerId: "018e…", sellerIds: ["018d…"], totalAmount: { amount: "150000.00", currency: "VND" } } schemas: EventHeaders: type: object required: [eventId, eventVersion, occurredAt, correlationId] properties: eventId: { type: string, description: 'Khoá khử trùng cho consumer (ICD §4)' } eventVersion: { type: string, pattern: '^[0-9]+\.[0-9]+$' } occurredAt: { type: string, format: date-time } correlationId: { type: string, description: 'Truyền xuyên suốt từ request gốc (ICD §1 điểm 8)' } Money: type: object required: [amount, currency] properties: amount: { type: string, pattern: '^-?[0-9]+(\.[0-9]{1,2})?$' } currency: { type: string, minLength: 3, maxLength: 3 } OrderPlacedPayload: type: object additionalProperties: false required: [orderId, sellerIds, totalAmount] properties: orderId: { type: string } customerId: { type: [string, 'null'], description: 'null = Guest' } sellerIds: { type: array, items: { type: string }, minItems: 1 } totalAmount: { $ref: '#/components/schemas/Money' }