{ "schema_version": 1, "diagram_type": "architecture", "meta": { "title": "C4 Container — Hệ thống đối soát (mẫu)", "quality_profile": "showcase", "views": [ { "id": "duong-chinh", "label": "Đường chính nạp và đối soát", "focus": [ "NV", "WEB", "API", "DB" ], "note": "Người dùng tải file POS, API ghi và đối soát trên CSDL chính." }, { "id": "duong-bat-dong-bo", "label": "Nhánh bất đồng bộ", "focus": [ "API", "QUEUE", "WORKER", "POS" ], "note": "Đối soát nặng chạy nền, gọi hệ thống POS ngoài có timeout." } ] }, "components": [ { "id": "NV", "type": "external", "label": "Nhân viên đối soát", "sublabel": "ROLE-01 · trình duyệt", "pos": [ 40, 300 ], "size": [ 150, 60 ] }, { "id": "IDP", "type": "security", "label": "IdP nội bộ", "sublabel": "OIDC · IF-001", "pos": [ 560, 100 ], "size": [ 150, 60 ] }, { "id": "WEB", "type": "frontend", "label": "CMP-01 Web App", "sublabel": "SPA · SCR-01..05", "pos": [ 300, 300 ], "size": [ 150, 60 ] }, { "id": "API", "type": "backend", "label": "CMP-02 Settlement API", "sublabel": "REST/JSON · /v1", "pos": [ 560, 300 ], "size": [ 150, 60 ] }, { "id": "DB", "type": "database", "label": "CMP-03 CSDL chính", "sublabel": "PostgreSQL · SoT", "pos": [ 820, 300 ], "size": [ 150, 60 ] }, { "id": "QUEUE", "type": "messagebus", "label": "CMP-04 Hàng đợi", "sublabel": "SQS FIFO · IF-004", "pos": [ 560, 520 ], "size": [ 150, 60 ] }, { "id": "WORKER", "type": "backend", "label": "CMP-05 Worker", "sublabel": "job đối soát nền", "pos": [ 820, 520 ], "size": [ 150, 60 ] }, { "id": "POS", "type": "external", "label": "Hệ thống POS", "sublabel": "đối tác · IF-005", "pos": [ 1080, 520 ], "size": [ 150, 60 ] } ], "boundaries": [ { "kind": "region", "label": "Vùng hệ thống của ta · ap-southeast-1", "wraps": [ "WEB", "API", "DB", "QUEUE", "WORKER" ] }, { "kind": "security-group", "label": "sg-app · chỉ nhận từ ALB", "wraps": [ "API", "WORKER" ] } ], "connections": [ { "id": "nv-web", "from": "NV", "to": "WEB", "label": "HTTPS · sync", "variant": "emphasis" }, { "id": "web-api", "from": "WEB", "to": "API", "label": "REST · IF-002", "variant": "emphasis" }, { "id": "idp-api", "from": "IDP", "to": "API", "label": "JWT · IF-001", "variant": "security", "labelDy": 24 }, { "id": "api-db", "from": "API", "to": "DB", "label": "SQL · sync", "variant": "emphasis" }, { "id": "api-queue", "from": "API", "to": "QUEUE", "label": "publish · async", "variant": "dashed", "labelDy": 24 }, { "id": "queue-worker", "from": "QUEUE", "to": "WORKER", "label": "consume", "variant": "dashed" }, { "id": "worker-db", "from": "WORKER", "to": "DB", "label": "SQL · sync", "labelDy": -24 }, { "id": "worker-pos", "from": "WORKER", "to": "POS", "label": "REST · 3s ·×3", "variant": "dashed" } ], "cards": [ { "dot": "emerald", "title": "Đường chính", "items": [ "Người dùng → Web → API → CSDL chính, toàn bộ đồng bộ", "CSDL chính là single source of truth (DAT §1)" ] }, { "dot": "amber", "title": "Nhánh bất đồng bộ", "items": [ "Đối soát nặng đẩy qua hàng đợi FIFO, worker xử lý at-least-once", "Gọi POS ngoài có timeout 3s, retry 3 lần theo FAIL FM-05" ] }, { "dot": "rose", "title": "Bảo mật", "items": [ "IdP nội bộ phát JWT, API kiểm ở tầng service (SEC §3)", "API và Worker nằm trong security group chỉ nhận từ ALB" ] } ] }