> ## Documentation Index
> Fetch the complete documentation index at: https://learn.cleeksy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quản lý & chia sẻ dữ liệu

> Quy tắc xác định nguồn dữ liệu chuẩn và chia sẻ dữ liệu giữa các app.

Trang này hướng dẫn cách thiết kế **ownership dữ liệu** và **chia sẻ dữ liệu** giữa các app để vận hành đầu-cuối mà vẫn tránh coupling và tránh “đồng bộ hỗn loạn”.

## Mục tiêu

* Xác định rõ **app nguồn (source of truth)** cho từng loại dữ liệu
* Chọn cách chia sẻ phù hợp: **publish/consume** hoặc **Data Connection**
* Biết khi nào dùng **one-way** và khi nào (hiếm) cần **two-way**
* Tránh các lỗi phổ biến: vòng lặp đồng bộ, dữ liệu mâu thuẫn, trách nhiệm không rõ

Liên quan:

* [Ranh giới App](/foundations/app-boundaries)
* [Chọn Value Slice theo SMALL](/foundations/value-slices-small)

## Ownership dữ liệu là gì?

**Ownership** trả lời câu hỏi: *“Ai chịu trách nhiệm tính đúng, đủ, và vòng đời của dữ liệu này?”*

Trong hệ thống nhiều app, ownership thường được gắn với:

* một **đơn vị chịu trách nhiệm** (Procurement, Finance, HR…)
* một **app nguồn** (nơi dữ liệu được tạo/cập nhật chính)
* các **app tiêu thụ** (chỉ đọc hoặc cập nhật phần được uỷ quyền)

<Note>
  Ownership rõ ràng giúp đơn giản hoá phân quyền, giảm tranh chấp dữ liệu và giảm chi phí thay đổi.
</Note>

## Nguyên tắc Source of truth (nguồn dữ liệu chuẩn)

Mỗi loại dữ liệu nên có **một** nguồn chính:

* Dữ liệu “yêu cầu” → thường thuộc app nơi yêu cầu được tạo và theo dõi
* Dữ liệu “xử lý nghiệp vụ chuyên môn” → thường thuộc app của bộ phận xử lý (ví dụ Procurement xử lý PO)
* Dữ liệu “danh mục chuẩn” → thường thuộc app master/reference (nếu có)

Nếu một dữ liệu có “nhiều nguồn”, hệ thống thường gặp:

* phiên bản không nhất quán (conflicting truth)
* khó audit (không biết ai đổi)
* khó thiết kế workflow và permissions

## Cách chia sẻ dữ liệu giữa các app

### 1) Publish / Consume (khuyến nghị mặc định)

Cơ chế chia sẻ theo hướng:

* App nguồn **publish** dữ liệu (một tập field/record được phép chia sẻ)
* App khác **consume** dữ liệu để sử dụng trong UI/workflow của mình

**Ưu điểm**

* Làm rõ ownership (ai publish là nguồn)
* Giảm coupling (consumer không cần “chạm” vào toàn bộ mô hình dữ liệu nguồn)
* Dễ kiểm soát quyền và phạm vi chia sẻ

**Khi nên dùng**

* Kết nối giữa các app theo kiểu handoff (bàn giao)
* Các app có ownership khác nhau
* Cần chia sẻ đọc (read-mostly) hoặc chia sẻ có kiểm soát

Xem triển khai: [Chia sẻ dữ liệu (Publish/Consume)](/build-apps/integrations/publish-consume-overview)

### 2) Data Connection fields (liên kết dữ liệu)

Liên kết record giữa entity/app để tham chiếu dữ liệu.

**Ưu điểm**

* Thao tác liên kết trực tiếp theo record
* Phù hợp cho các quan hệ dữ liệu rõ ràng

**Rủi ro**

* Dễ tạo coupling nếu dùng không kiểm soát
* Dễ “đẩy” người dùng sang app khác để sửa dữ liệu nguồn

Xem triển khai:

* [Kết nối dữ liệu một chiều (Data Connection one-way)](/build-apps/data-modeling/data-connection-one-way)
* [Kết nối dữ liệu hai chiều (Data Connection two-way)](/build-apps/data-modeling/data-connection-two-way)

## One-way vs Two-way: quy tắc quyết định

### One-way (khuyến nghị)

**Một chiều** nghĩa là:

* dữ liệu chảy theo một hướng: nguồn → tiêu thụ
* consumer không sửa dữ liệu nguồn (hoặc chỉ sửa phần được uỷ quyền thông qua cơ chế rõ ràng)

**Khi phù hợp**

* Hầu hết trường hợp handoff giữa bộ phận
* Trạng thái/thuộc tính thuộc ownership của app nguồn
* Mục tiêu là “xem để làm việc tiếp” hoặc “xem để theo dõi”

### Two-way (chỉ dùng khi cần, có điều kiện)

**Hai chiều** nghĩa là:

* cả hai phía có thể cập nhật một phần dữ liệu và cần phản chiếu lẫn nhau

**Chỉ nên dùng khi**

* ownership được định nghĩa theo “phân vùng field” (field ownership rõ)
* quy tắc đồng bộ và xử lý xung đột đã rõ
* có lý do nghiệp vụ thực sự (không chỉ vì tiện)

**Dấu hiệu không nên dùng two-way**

* “Ai cũng có thể sửa mọi thứ”
* “Cứ đồng bộ cho chắc”
* “Chưa rõ ai chịu trách nhiệm khi dữ liệu sai”

<Warning>
  Two-way làm tăng chi phí vận hành và rủi ro dữ liệu mâu thuẫn. Nếu chưa chắc, nên bắt đầu bằng one-way.
</Warning>

## Thiết kế chia sẻ dữ liệu theo từng câu hỏi

1. **Dữ liệu thuộc về ai?** (đơn vị chịu trách nhiệm)
2. **Nguồn được tạo/cập nhật ở đâu?** (app nguồn)
3. **App khác cần dùng dữ liệu để làm gì?** (chỉ đọc, tham chiếu, hay cập nhật phần được uỷ quyền)
4. **Chỉ số và audit cần theo dõi gì?** (ai đổi, đổi khi nào, theo bước nào)
5. **Độ nhạy dữ liệu và policy truy cập** (ai được xem/sửa)

## Ví dụ: Purchase Request và Procurement

### Mô hình ownership đề xuất

* **App Purchase Request** (nguồn): sở hữu dữ liệu yêu cầu (mục đích, mô tả, chi phí dự kiến, trạng thái phê duyệt)
* **App Procurement** (nguồn): sở hữu dữ liệu xử lý mua sắm (PO, nhà cung cấp, trạng thái đặt hàng/nhận hàng)

### Chia sẻ theo publish/consume (đề xuất)

* Purchase Request **publish** các yêu cầu đã được phê duyệt (các field cần cho procurement)
* Procurement **consume** để tạo/điều phối công việc mua sắm
* Procurement **publish** trạng thái xử lý (read-only cho requester theo dõi)
* Purchase Request **consume** để hiển thị tiến độ cho người yêu cầu

Kết quả:

* ownership rõ, mỗi app tập trung đúng “phần việc”
* dữ liệu không bị sửa chéo
* UI của mỗi nhóm người dùng đơn giản hơn

## Anti-patterns cần tránh

* **Nhập lại dữ liệu** giữa các app thay vì kết nối qua publish/consume + connected app (kết nối ứng dụng) (dẫn đến lệch dữ liệu)
* **Two-way mặc định** cho mọi liên kết
* **Không có app nguồn**: nhiều app cùng sửa cùng record
* **Chia sẻ quá rộng**: publish “tất cả mọi thứ” thay vì publish đủ dùng
* **Không có policy**: ai cũng xem/sửa dữ liệu nhạy cảm

## Bước tiếp theo

* Ra quyết định controls: [Controls trong hệ thống (workflow vs validation vs roles)](/foundations/controls-in-system)
* Áp dụng trong delivery loop: [Inner loop: delivery cycle (chu kỳ triển khai)](/sdd/inner-loop-delivery-cycle)
* Cấu hình tính năng: [Cổng dữ liệu (Data source)](/build-apps/integrations/data-sources-overview)
