> ## 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.

# Thực thể dữ liệu (Entity)

> Tạo entity và thiết kế cấu trúc dữ liệu trong app.

Entity là đơn vị trung tâm của **mô hình dữ liệu (data model)** trong Cleeksy. Mỗi app thường bắt đầu từ việc xác định các Entity chính, sau đó bổ sung **Field** và tạo **Record** trong quá trình vận hành.

## Entity là gì?

**Entity** tương đương “bảng dữ liệu” trong hệ thống. Entity chứa:

* **Fields**: các thuộc tính (cột) của dữ liệu
* **Records**: các bản ghi (dòng) được tạo và cập nhật khi công việc chạy

Liên quan:

* [Bản ghi (Record)](/build-apps/data-modeling/records)
* [Kiểu trường dữ liệu (Field types)](/build-apps/data-modeling/field-types)

## Khi nào cần tạo một Entity?

Một Entity nên được tạo khi tồn tại một “đối tượng nghiệp vụ” có vòng đời rõ ràng, ví dụ:

* Purchase Request (yêu cầu mua)
* Purchase Order (PO)
* Supplier (nhà cung cấp)
* Approval task (nhiệm vụ phê duyệt)

### Gợi ý nhận diện Entity từ scenario

Trong scenario, các **danh từ nghiệp vụ** (nouns) thường là ứng viên cho Entity.
Ví dụ trong Purchase Request: “yêu cầu mua”, “người yêu cầu”, “người phê duyệt”, “nhà cung cấp”, “PO”.

## Quy tắc thiết kế Entity (thực dụng)

### 1) Một Entity = một ownership rõ ràng

Entity nên thuộc về một app/đơn vị chịu trách nhiệm (source of truth). Nếu ownership không rõ, rủi ro dữ liệu mâu thuẫn tăng nhanh.

Tham khảo: [Ownership & chia sẻ dữ liệu (Data ownership & sharing)](/foundations/data-ownership-sharing)

### 2) Giữ Entity “gọn” cho value slice đầu tiên

Ở vòng đầu, Entity chỉ cần đủ dữ liệu để chạy end-to-end. Các trường “nice-to-have” đưa vào backlog.

Tham khảo: [Chọn Value Slice theo SMALL](/foundations/value-slices-small)

### 3) Tránh trộn nhiều khái niệm vào một Entity

Nếu một Entity có quá nhiều field thuộc nhiều chủ đề khác nhau, nên cân nhắc tách:

* theo ownership
* theo workflow khác nhau
* theo nhóm người dùng khác nhau

Tham khảo: [Ranh giới App](/foundations/app-boundaries)

## Tạo Entity trên Cleeksy (khái niệm & thao tác)

### Thông tin tối thiểu khi tạo Entity

* **Tên Entity**: ngắn, rõ nghĩa, danh từ số ít (khuyến nghị)
* **Mô tả**: 1–2 câu mô tả “Entity này dùng để làm gì”
* **Field hiển thị** (primary display): field dùng để hiển thị record trong liên kết

<Note>
  Một số field hệ thống (system fields) có thể được tạo mặc định để phục vụ audit và vận hành (ví dụ: người tạo, thời gian tạo…).
</Note>

### Sau khi tạo Entity nên làm gì?

1. Tạo các **Field tối thiểu** để tạo record và chạy workflow
2. Tạo **View** để nhập liệu và theo dõi
3. Nếu có quy trình: thiết kế **Workflow** dựa trên các trạng thái của record

Liên quan:

* [Tổng quan giao diện](/build-apps/ui-views/views-overview)
* [Thiết kế quy trình (Process Builder)](/build-apps/workflows/process-builder)

## Cấu trúc dữ liệu và liên kết (Sub-entity & Data Connection)

Trong Cleeksy, **Entity luôn nằm trong một App**. Thay vì mô hình “relationship” kiểu cơ sở dữ liệu quan hệ, Cleeksy dùng hai cơ chế chính để biểu diễn liên hệ dữ liệu:

* **Sub-entity** (bảng con) để biểu diễn dữ liệu phân cấp (parent → nhiều dòng con) trong *một* Entity
* **Data Connection** (Field liên kết) để kết nối record giữa các Entity trong cùng App hoặc giữa các App

### 1) Sub-entity (bảng con) cho dữ liệu phân cấp

Dùng Sub-entity khi một đối tượng có **nhiều dòng con thuộc về chính nó**, ví dụ:

* Purchase Request có nhiều dòng hàng (items)
* Order có nhiều Order Items
* Phiếu giao việc có nhiều checklist items

**Đặc điểm**

* Sub-entity là **một Field** trong Entity cha (thường ở dạng “data table”)
* Các dòng con tồn tại trong ngữ cảnh của record cha → ownership rõ ràng, dễ vận hành

**Khi không nên dùng Sub-entity**

* Dòng con cần workflow riêng độc lập
* Dòng con cần được chia sẻ/được tham chiếu từ nhiều “cha” khác nhau
  Trong trường hợp này, nên tách thành Entity riêng và liên kết bằng Data Connection.

### 2) Data Connection (Field) để liên kết giữa Entity/App

**Data Connection** là một Field trong Entity dùng để **liên kết record** với record ở Entity khác:

* **Trong cùng App**: kết nối giữa các Entity nội bộ để tham chiếu dữ liệu
* **Giữa các App**: Data Connection **chỉ** có thể trỏ tới dữ liệu mà App hiện tại đã **consume** (từ một App khác đã publish dữ liệu trước đó).

<Note>
  Khi kết nối **giữa các App**, publish/consume là bước bắt buộc để tạo **connected app (kết nối ứng dụng)** cho App tiêu thụ. Data Connection là Field dùng để liên kết record tới connected app đó (không thay thế publish/consume).
</Note>

**One-way vs two-way**

* **One-way** phù hợp khi cần tham chiếu/hiển thị (reference, read-mostly) và muốn giảm coupling
* **Two-way** chỉ nên dùng khi ownership được định nghĩa rõ (field nào do bên nào chịu trách nhiệm) và có lý do nghiệp vụ thực sự

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)
* [Chia sẻ dữ liệu (Publish/Consume)](/build-apps/integrations/publish-consume-overview)

### 3) Patterns mô hình hoá thường dùng

* **Parent + line items**: ưu tiên Sub-entity (bảng con) trong Entity cha
  Ví dụ: `Purchase Request` có field `Items` (Sub-entity)

* **Transaction → master/reference**: dùng Data Connection one-way để tham chiếu
  Ví dụ: `Purchase Request` tham chiếu `Supplier` hoặc `Cost Center`

* **Nhu cầu tương đương “nhiều–nhiều”**: dùng Entity liên kết + Data Connection fields
  Ví dụ: `Supplier Category Link` có 2 field Data Connection: `Supplier` và `Category`
  Cách này giúp giữ ownership rõ ràng và tránh sửa chéo dữ liệu

## Ví dụ: Purchase Request (vòng đầu) và mở rộng Procurement

### Vòng đầu: 1 app Purchase Request

Entity tối thiểu:

* `Purchase Request`
* title, description, estimated cost, requester, status
* (tuỳ chọn) `Request Item` nếu cần nhiều dòng hàng

### Mở rộng: thêm app Procurement

Khi mở rộng sang Procurement, thường tách ownership:

* App Purchase Request: ownership yêu cầu và phê duyệt
* App Procurement: ownership xử lý mua sắm (PO, supplier, delivery status)

Kết nối dữ liệu:

* Procurement consume/pull thông tin request đã approved
* Purchase Request hiển thị tiến độ xử lý từ Procurement (read-only)

## Lỗi thường gặp khi thiết kế Entity

* **Tạo Entity theo màn hình** thay vì theo đối tượng dữ liệu (dẫn đến dữ liệu trùng và khó mở rộng)
* **Field quá nhiều ngay từ đầu** (đặc biệt là các field ít dùng)
* **Không chốt field hiển thị** (khi liên kết record sẽ khó đọc)
* **Thiếu ownership rõ ràng** (nhiều app cùng sửa một dữ liệu)

## Bước tiếp theo

* Thiết kế Field: [Kiểu trường dữ liệu (Field types)](/build-apps/data-modeling/field-types)
* Tạo và vận hành Record: [Bản ghi (Record)](/build-apps/data-modeling/records)
* Thiết kế View: [Tổng quan giao diện](/build-apps/ui-views/views-overview)
