7.6 KiB
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.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
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 |