Bỏ qua

Thuộc Tài Liệu API — EP-02: Dữ liệu Định vị (Anchored Data)

API Chi Tiết — EP-02: Dữ Liệu Định Vị (Anchored Data)

Use Cases: UC-ANCHOR-001, UC-ANCHOR-002, UC-ANCHOR-003, UC-ANCHOR-004, UC-ANCHOR-005 Module: module-anchored


Quản Lý Domain & Sub Domain

GET /api/v1/domains

Mục đích: Danh sách Domain theo cấu trúc cây phân cấp (Domain → Sub Domain).

Tham chiếu: UC-ANCHOR-001, Feature EP-02-001

Phân quyền: Role: Manager, Approver

Query Parameters:

Parameter Kiểu Mô tả
search String Tìm theo tên Domain/Sub Domain
includeSubDomains Boolean Bao gồm Sub Domain (mặc định: true)
includeDeCount Boolean Đếm số Data Element mỗi Sub Domain (mặc định: false)

Response 200:

{
  "success": true,
  "data": [
    {
      "id": 1,
      "code": "DM1",
      "name": "Con người",
      "description": "Dữ liệu liên quan đến cá nhân, công dân",
      "subDomains": [
        {
          "id": 11,
          "code": "DM1.1",
          "name": "Định danh",
          "description": "Thông tin nhận dạng cá nhân",
          "dataElementCount": 15
        },
        {
          "id": 12,
          "code": "DM1.2",
          "name": "Y tế & Sức khỏe",
          "dataElementCount": 22
        }
      ]
    }
  ]
}

POST /api/v1/domains

Mục đích: Tạo Domain mới. Mã tự động sinh theo format DM{N}.

Phân quyền: Role: Manager

Request Body:

{
  "name": "Giao thông",
  "description": "Dữ liệu liên quan đến giao thông, vận tải"
}

Response 201:

{
  "success": true,
  "data": {
    "id": 6,
    "code": "DM6",
    "name": "Giao thông",
    "description": "Dữ liệu liên quan đến giao thông, vận tải",
    "createdAt": "2026-04-08T14:30:00+07:00"
  }
}

Ghi chú:code được hệ thống tự sinh. Không thể chỉnh sửa sau khi tạo (ADR: DE_CODE_IMMUTABLE).


PUT /api/v1/domains/{id}

Mục đích: Cập nhật thông tin Domain (tên, mô tả). Mã không đổi.

Phân quyền: Role: Manager

Request Body:

{
  "name": "Giao thông & Vận tải",
  "description": "Mô tả cập nhật"
}

DELETE /api/v1/domains/{id}

Mục đích: Xóa Domain.

Phân quyền: Role: Manager

Business Rules: - Domain có Sub Domain → 422 DOMAIN_HAS_CHILDREN - Domain đang được tham chiếu (matching, mapping) → 422 DOMAIN_IN_USE


POST /api/v1/domains/{domainId}/sub-domains

Mục đích: Tạo Sub Domain trong Domain. Mã tự sinh DM{N}.{M}.

Phân quyền: Role: Manager

Request Body:

{
  "name": "Phương tiện",
  "description": "Thông tin về phương tiện giao thông"
}

Response 201:

{
  "success": true,
  "data": {
    "id": 61,
    "code": "DM6.1",
    "name": "Phương tiện",
    "domainId": 6,
    "domainName": "Giao thông & Vận tải"
  }
}

PUT /api/v1/sub-domains/{id}

Mục đích: Cập nhật Sub Domain (tên, mô tả). Mã không đổi.

Phân quyền: Role: Manager


DELETE /api/v1/sub-domains/{id}

Mục đích: Xóa Sub Domain.

Phân quyền: Role: Manager

Business Rules: - Sub Domain có Data Element → 422 SUB_DOMAIN_HAS_CHILDREN


Quản Lý Data Element

GET /api/v1/data-elements

Mục đích: Danh sách Data Element (phân trang, lọc, tìm kiếm).

Tham chiếu: UC-ANCHOR-002, Feature EP-02-002

Phân quyền: Role: Manager, Approver

Query Parameters:

Parameter Kiểu Mô tả
search String Tìm theo tên, mã, mô tả
domainId Long Lọc theo Domain
subDomainId Long Lọc theo Sub Domain
status String Lọc: DRAFT, IN_REVIEW, APPROVED, PUBLISHED
page, size, sort Phân trang chuẩn

Response 200:

{
  "success": true,
  "data": {
    "items": [
      {
        "id": 101,
        "code": "DE001-DM1.1",
        "name": "Số CCCD",
        "description": "Số căn cước công dân 12 số",
        "dataType": "VARCHAR(12)",
        "subDomain": { "id": 11, "code": "DM1.1", "name": "Định danh" },
        "domain": { "id": 1, "code": "DM1", "name": "Con người" },
        "status": "DRAFT",
        "owner": null,
        "synonyms": ["so_cccd", "cccd_number", "citizen_id"],
        "createdAt": "2026-04-01T10:00:00+07:00"
      }
    ],
    "meta": { "page": 0, "size": 20, "totalElements": 500 }
  }
}

POST /api/v1/data-elements

Mục đích: Tạo Data Element mới. Mã tự sinh DE{NNN}-DM{N}.{M}. Trạng thái ban đầu: DRAFT.

Phân quyền: Role: Manager

Request Body:

{
  "subDomainId": 11,
  "name": "Ngày sinh",
  "description": "Ngày tháng năm sinh của công dân",
  "dataType": "DATE",
  "synonyms": ["ngay_sinh", "date_of_birth", "dob"]
}

Response 201: Data Element đã tạo với mã tự sinh.

Validation Rules: - synonyms (tu_dong_nghia): Tối đa 10 từ đồng nghĩa, mỗi từ dài không quá 50 ký tự (tránh tràn 2KB GIN index limit).


PUT /api/v1/data-elements/{id}

Mục đích: Cập nhật Data Element (tên, mô tả, synonyms, kiểu DL). Mã không đổi.

Phân quyền: Role: Manager

Business Rules: - code không thể thay đổi → 422 DE_CODE_IMMUTABLE - subDomainId không thể thay đổi (DE thuộc cố định Sub Domain)

Validation Rules: - synonyms (tu_dong_nghia): Tối đa 10 từ đồng nghĩa, mỗi từ dài không quá 50 ký tự.


DELETE /api/v1/data-elements/{id}

Mục đích: Xóa Data Element.

Phân quyền: Role: Manager

Business Rules: - DE đang có matching results → 422 DE_IN_USE - DE đã PUBLISHED → 422 DE_PUBLISHED_CANNOT_DELETE


Xem Khung Dữ Liệu Định Vị

GET /api/v1/anchored-data/tree

Mục đích: Xem toàn bộ khung dữ liệu định vị theo cấu trúc cây Domain → Sub Domain → Data Element.

Tham chiếu: UC-ANCHOR-003, Feature EP-02-003

Phân quyền: Role: Manager, Approver

Query Parameters:

Parameter Kiểu Mô tả
search String Tìm kiếm xuyên cây
domainId Long Lọc theo Domain cụ thể
expandAll Boolean Mở rộng toàn bộ cây (mặc định: false — chỉ hiển thị Domain)

Response 200:

{
  "success": true,
  "data": [
    {
      "id": 1,
      "code": "DM1",
      "name": "Con người",
      "type": "DOMAIN",
      "children": [
        {
          "id": 11,
          "code": "DM1.1",
          "name": "Định danh",
          "type": "SUB_DOMAIN",
          "children": [
            {
              "id": 101,
              "code": "DE001-DM1.1",
              "name": "Số CCCD",
              "type": "DATA_ELEMENT",
              "dataType": "VARCHAR(12)",
              "status": "DRAFT"
            }
          ]
        }
      ]
    }
  ]
}

Đề Xuất Mở Rộng Anchored Data

POST /api/v1/extension-proposals

Mục đích: Data Owner đề xuất bổ sung Sub Domain hoặc Data Element đặc thù chuyên ngành.

Tham chiếu: UC-ANCHOR-004, Feature EP-02-004

Phân quyền: - Role: Data Owner - Business Rule: Chỉ đề xuất trong Domain đã tồn tại — không tạo Domain mới → 422 EXTENSION_DOMAIN_ONLY

Request Body:

{
  "type": "DATA_ELEMENT",
  "domainId": 1,
  "subDomainId": 12,
  "name": "Mã bệnh ICD-10",
  "description": "Mã phân loại bệnh quốc tế phiên bản 10",
  "dataType": "VARCHAR(10)",
  "justification": "Cần cho hệ thống HIS của Sở Y tế, hiện chưa có trong Anchored Data"
}

Response 201:

{
  "success": true,
  "data": {
    "id": 501,
    "type": "DATA_ELEMENT",
    "status": "PENDING",
    "proposedBy": { "id": 1, "name": "Nguyễn Văn A", "org": "Sở Y tế" },
    "createdAt": "2026-04-08T15:00:00+07:00"
  }
}

GET /api/v1/extension-proposals

Mục đích: Danh sách đề xuất mở rộng.

Phân quyền: - Manager: xem tất cả đề xuất - Data Owner: chỉ xem đề xuất của mình

Query Parameters:

Parameter Kiểu Mô tả
status String PENDING, APPROVED, REJECTED
orgId Long Lọc theo đơn vị đề xuất
page, size Phân trang

PATCH /api/v1/extension-proposals/{id}/approve

Mục đích: Manager phê duyệt đề xuất. Hệ thống sinh mã tự động.

Tham chiếu: UC-ANCHOR-005, Feature EP-02-005

Phân quyền: Role: Manager

Request Body:

{
  "note": "Đề xuất hợp lệ, đã thêm vào Sub Domain Y tế & Sức khỏe"
}

Response 200:

{
  "success": true,
  "data": {
    "proposalId": 501,
    "status": "APPROVED",
    "createdEntity": {
      "id": 523,
      "code": "DE023-DM1.2",
      "name": "Mã bệnh ICD-10",
      "type": "DATA_ELEMENT"
    }
  }
}

PATCH /api/v1/extension-proposals/{id}/reject

Mục đích: Manager từ chối đề xuất kèm lý do.

Phân quyền: Role: Manager

Request Body:

{
  "reason": "Data Element tương tự đã tồn tại: DE005-DM1.2 'Mã bệnh'"
}

Validation: reason bắt buộc.

Response 200: Đề xuất đã từ chối. Data Owner nhận thông báo.


Cập nhật lần cuối: 2026-04-08