init git
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# PART 2 — biến thể `data-pipeline`
|
||||
|
||||
> **Dùng khi** `PRODUCT = data-pipeline` — sản phẩm là **dữ liệu**: ETL, ingest, kho dữ
|
||||
> liệu, báo cáo BI. Cắm khối này vào chỗ PART 2 của [`../srs.md`](../srs.md).
|
||||
>
|
||||
> **Tiêu chí G3 riêng của biến thể này**: mỗi luồng có data contract nguồn và đích · bảng
|
||||
> ánh xạ trường đầy đủ · quy tắc chất lượng có ngưỡng và hành vi khi vi phạm · **có mục đối
|
||||
> soát nguồn–đích** · đã trả lời xong chạy lại/backfill/dữ liệu đến muộn.
|
||||
|
||||
🔴 **Người dùng của bạn không nhìn thấy sản phẩm — họ nhìn thấy những con số.** Con số sai
|
||||
mà không ai biết là chế độ hỏng nguy hiểm nhất của loại sản phẩm này, vì nó im lặng. Vì vậy
|
||||
§2.6 (đối soát) và §2.5 (chất lượng) là hai mục quan trọng nhất, không phải phần phụ.
|
||||
|
||||
---
|
||||
|
||||
## 2.1 Danh sách luồng dữ liệu
|
||||
|
||||
| ID | Luồng | Nguồn | Đích | Tần suất | Kiểu | Khối lượng/lần | BR |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| FLW-01 | | | | Hằng đêm 02:00 | Toàn bộ / Tăng dần / CDC | ~… bản ghi | |
|
||||
|
||||
## 2.2 Sơ đồ lineage
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
POS[["POS API"]]
|
||||
ERP[["ERP export CSV"]]
|
||||
STG[("staging.pos_raw")]
|
||||
DW[("dw.fact_sales")]
|
||||
RPT(["Báo cáo doanh thu"])
|
||||
NGUOIDOC(["👤 Kế toán, Ban giám đốc"])
|
||||
|
||||
POS -->|FLW-01| STG
|
||||
STG -->|FLW-02| DW
|
||||
ERP -->|FLW-03| DW
|
||||
DW --> RPT
|
||||
RPT --> NGUOIDOC
|
||||
```
|
||||
|
||||
*Trụ `[( )]` = kho dữ liệu · khung đôi `[[ ]]` = nguồn ngoài, không do mình sở hữu · bo tròn
|
||||
`([ ])` = đầu ra và người đọc. Nhãn cạnh là mã luồng `FLW-nn`, khớp bảng §2.1.*
|
||||
|
||||
🔴 **Vẽ tới tận người tiêu thụ cuối** — báo cáo nào, **ai đọc**. Dừng ở bảng dữ liệu thì khi
|
||||
luồng hỏng lúc 2 giờ sáng không ai biết phải báo cho ai, và không đánh giá được mức nghiêm
|
||||
trọng.
|
||||
|
||||
**Bảng đi kèm** *(quy tắc W13)*:
|
||||
|
||||
| Luồng | Nguồn → Đích | Tần suất | SLA độ tươi | Hỏng thì ai bị ảnh hưởng | Chủ sở hữu nguồn |
|
||||
|---|---|---|---|---|---|
|
||||
| FLW-01 | POS API → staging | Hằng đêm 02:00 | D+1 08:00 | Toàn bộ chuỗi phía sau | NCC X — anh Huy |
|
||||
|
||||
## 2.3 FLW-01 — <Tên luồng>
|
||||
|
||||
### 2.3.1 Nguồn
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Hệ thống nguồn** | |
|
||||
| **Cách lấy** | API / file / CDC / queue |
|
||||
| **Ai sở hữu nguồn** | *(đầu mối khi schema đổi)* |
|
||||
| **Nguồn có báo trước khi đổi schema không** | 🔴 Không ⇒ phải có phát hiện schema drift |
|
||||
| **Cửa sổ dữ liệu sẵn sàng** | *(từ mấy giờ nguồn mới có đủ dữ liệu hôm qua)* |
|
||||
|
||||
### 2.3.2 SLA độ tươi
|
||||
|
||||
*Thay cho "thời gian phản hồi" của biến thể `screen`.*
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Dữ liệu ngày D phải sẵn sàng trước** | D+1 08:00 |
|
||||
| **Trễ tối đa chấp nhận được** | |
|
||||
| **Ai được báo khi trễ** | |
|
||||
| **Người dùng thấy gì khi dữ liệu chưa tới** | 🔴 Số cũ? Số rỗng? **Có nhãn cảnh báo không?** |
|
||||
|
||||
🔴 Câu cuối là câu hay bị bỏ nhất. Báo cáo hiển thị số của hôm kia mà không có nhãn "dữ liệu
|
||||
tới 28/08" là cách người dùng ra quyết định trên số cũ mà không biết.
|
||||
|
||||
### 2.3.3 Data contract — schema nguồn
|
||||
|
||||
| Trường nguồn | Kiểu | Có thể null | Nghĩa nghiệp vụ | Giá trị hợp lệ | Ghi chú |
|
||||
|---|---|---|---|---|---|
|
||||
|
||||
### 2.3.4 Ánh xạ trường
|
||||
|
||||
| Trường đích | Từ trường nguồn | Phép biến đổi | Khi nguồn null | Khi nguồn sai định dạng | BR |
|
||||
|---|---|---|---|---|---|
|
||||
| `store_code` | `shop.id` | upper(trim(x)) | → `UNKNOWN` | → quarantine | BR-0nn |
|
||||
| `amount` | `total` | chia 100 (nguồn lưu đơn vị nhỏ nhất) | → 0 | → quarantine | BR-0nn |
|
||||
|
||||
🔴 **Ba cột cuối là phần thay thế cho "validation + message lỗi" của biến thể `screen`.**
|
||||
Bỏ trống ⇒ kỹ sư dữ liệu tự quyết, và mỗi luồng một kiểu.
|
||||
|
||||
### 2.3.5 Khoá và trùng lặp
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **Khoá nghiệp vụ** | *(cái gì xác định một bản ghi là duy nhất)* |
|
||||
| **Nguồn có gửi trùng không** | |
|
||||
| **Trùng thì xử lý sao** | Giữ bản mới nhất / cộng dồn / báo lỗi |
|
||||
| **Bản ghi bị sửa ở nguồn** | Ghi đè / giữ lịch sử (SCD loại mấy) |
|
||||
|
||||
## 2.4 Quy tắc chất lượng dữ liệu
|
||||
|
||||
| ID | Kiểm tra gì | Ngưỡng | Vi phạm thì làm gì | Ai được báo |
|
||||
|---|---|---|---|---|
|
||||
| DQ-01 | Số bản ghi so với trung bình 7 ngày | ±30% | ⚠️ Cảnh báo, vẫn nạp | |
|
||||
| DQ-02 | Tỷ lệ `store_code` không map được | > 1% | 🛑 **Dừng luồng** | |
|
||||
| DQ-03 | Tổng tiền âm | > 0 bản ghi | 🔴 Quarantine bản ghi đó | |
|
||||
|
||||
**Ba hành vi khi vi phạm — chọn rõ một, không được để mơ hồ:**
|
||||
|
||||
| Hành vi | Nghĩa | Dùng khi |
|
||||
|---|---|---|
|
||||
| `drop` | Bỏ bản ghi, ghi log | Bản ghi rác đã biết, không ảnh hưởng tổng |
|
||||
| `quarantine` | Tách sang bảng riêng để xử lý tay | 🔴 **Mặc định nên chọn** — giữ được dữ liệu để điều tra |
|
||||
| `fail` | Dừng cả luồng | Sai lệch có thể làm hỏng báo cáo tài chính |
|
||||
|
||||
🔴 **`drop` im lặng là chế độ hỏng tệ nhất.** Số liệu thiếu mà không ai biết. Chọn `drop`
|
||||
phải kèm ngưỡng cảnh báo.
|
||||
|
||||
## 2.5 Trạng thái tương đương "màn hình rỗng"
|
||||
|
||||
| Tình huống | Xử lý | Người dùng thấy gì |
|
||||
|---|---|---|
|
||||
| Ngày không có giao dịch nào (chủ nhật, lễ) | Nạp 0 bản ghi — **không phải lỗi** | Báo cáo hiện 0, có nhãn "không có giao dịch" |
|
||||
| Nguồn không phản hồi | | |
|
||||
| Nguồn trả rỗng bất thường | 🔴 Phân biệt với ca trên bằng cách nào? | |
|
||||
|
||||
Phân biệt **"không có dữ liệu"** với **"chưa lấy được dữ liệu"** là bắt buộc. Hai thứ này
|
||||
nhìn giống nhau trên báo cáo nhưng ý nghĩa ngược nhau.
|
||||
|
||||
## 2.6 Đối soát nguồn – đích
|
||||
|
||||
🔴 **Mục bắt buộc, không được bỏ.** Đây là thứ duy nhất chứng minh dữ liệu không bị mất
|
||||
giữa đường.
|
||||
|
||||
| # | Đối chiếu gì | Nguồn | Đích | Sai lệch cho phép | Tần suất | Ai kiểm |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 1 | Số bản ghi | count(pos_api) | count(fact_sales) | 0 | Mỗi lần chạy | Tự động |
|
||||
| 2 | Tổng tiền | sum(total) | sum(amount)×100 | ≤ 1 đơn vị (làm tròn) | Hằng ngày | Tự động |
|
||||
| 3 | Đối chiếu với báo cáo hệ thống cũ | | | | Hằng tháng | Kế toán |
|
||||
|
||||
**Sai lệch vượt ngưỡng thì làm gì, ai chịu trách nhiệm xử lý:** …
|
||||
|
||||
## 2.7 Chạy lại, backfill, dữ liệu đến muộn
|
||||
|
||||
| Câu hỏi | Trả lời |
|
||||
|---|---|
|
||||
| **Chạy lại cùng một ngày hai lần** → kết quả có giống không (idempotent)? | 🔴 Không idempotent ⇒ nói rõ quy trình dọn trước khi chạy lại |
|
||||
| **Backfill** lịch sử N ngày làm thế nào? Mất bao lâu? Ảnh hưởng báo cáo đang chạy không? | |
|
||||
| **Dữ liệu đến muộn** (giao dịch hôm qua tới hôm nay) | Nạp vào ngày phát sinh hay ngày nhận? |
|
||||
| Nạp vào ngày phát sinh ⇒ **báo cáo đã chốt có thay đổi không?** | 🔴 Nếu có, ai được báo |
|
||||
| **Thất bại giữa chừng** | Rollback toàn bộ / tiếp tục từ checkpoint |
|
||||
|
||||
## 2.8 Vận hành
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Chạy tự động lúc | |
|
||||
| Chạy tay được không, ai được chạy | |
|
||||
| Cảnh báo gửi đi đâu | |
|
||||
| Ai trực khi luồng hỏng ban đêm | |
|
||||
| Hỏng bao lâu thì phải báo người dùng | |
|
||||
Reference in New Issue
Block a user