MOUT/MOIT — DOT Table Engine (ghi chú thiết kế vòng 1)
MOUT / MOIT — DOT Table Engine — Ghi chú thiết kế (vòng 1)
Date: 2026-06-18 | Status: DISCUSSION + PREVIEW (chưa enact) | Author: Cowork (Claude) cùng Huyên Preview live: https://vps.incomexsaigoncorp.vn/ui-preview/mcp-writes/mout-dot-table-v1.html Source file VPS: /opt/incomex/docs/mcp-writes/ui-preview/mout-dot-table-v1.html Liên quan:
iu-mow-mot-event-foundation-requirements.md§6.3 (MOIT) §6.4 (MOUT) ·td-matrix-dimensions.md(Pivot v4.0/Điều 26) ·dieu35-dot-governance-law.mdv5.2 · MOT design system v1.2 (mot-theme-v1.css). Mục đích note: vòng sau nhớ ý đồ, không bàn lại từ đầu.
1. Đề bài vòng này (từ Huyên)
- MOW, MOT đã cơ bản xong UI. Vòng này bàn MOIT và MOUT.
-
95% MOIT đã nằm trong vùng input của MOT; còn thiếu 1 MOIT kiểu ma trận 2 chiều (bảng hàng × cột).
- Báo cáo dạng ma trận chiếm ~50% (50% còn lại inline trong MOT vùng 3).
- Ý đồ: gọi DOT, nêu số cột + thứ tự cột → ra bảng. Điều kiện: mọi trường phải có sẵn trong DB. Truy vấn số liệu là việc riêng. Mục tiêu: dựng bảng báo cáo nhanh bằng / hơn Excel.
- MOUT: các cột nên có số tổng dưới cùng; ví dụ tối đa 12 cột, bật SUM ở bất cứ cột nào → hỏi khả thi không.
- Cột trái cùng luôn là STT 1,2,3… mặc định, đếm theo số hàng dữ liệu. Cần kết nối dữ liệu truy vấn ↔ khung (SUM + đếm STT).
- Yêu cầu: Cowork đóng vai người thiết kế hệ thống, tự chốt cách tiếp cận rồi thực hiện, không chỉ làm theo.
2. Kết luận khả thi (chốt)
- SUM bật/tắt từng cột + dòng tổng dưới cùng: KHẢ THI. Mấu chốt: tổng query-side, không client-side.
- Dòng tổng là một phần output của DOT (
{columns, rows, totals}), SUM chạy ở SQL trên toàn tập đã lọc; khung chỉ vẽ lại. - Lý do: client-side chỉ cộng được trang đang xem (sai khi phân trang) + vi phạm Điều 28 (Nuxt = render shell, cộng tiền là logic nghiệp vụ).
- Tổng quát hơn SUM: mỗi cột khai
agg = none|sum|avg|count|min|max(mặc định none).
- Dòng tổng là một phần output của DOT (
- STT 1..N: KHẢ THI, và phải là cột synthetic của khung, KHÔNG phải field DB.
- Không bao giờ lưu / query. Khung chèn cột 0, đánh số
offset + i + 1. - Đánh số sau khi đã sort (DOT trả rows đã ORDER BY). Phân trang: STT chạy tiếp (51,52…), không quay về 1. Dòng tổng không có STT (hiện Σ / để trống).
- Không bao giờ lưu / query. Khung chèn cột 0, đánh số
- Kết nối dữ liệu ↔ khung rất gọn: DOT lo số liệu + tổng + thứ tự; khung lo STT (đếm thuần) + định dạng + vẽ dòng tổng. Khung không tính một đồng nào.
3. Quyết định kiến trúc (do Cowork chốt vai system designer)
3.1 Tách hai nửa
Một báo cáo = skeleton (khung) + data_function (số liệu) + params (lọc/kỳ).
- Nửa khung = config thuần: cột nào, thứ tự, type, canh lề, cột nào tổng, STT on/off.
- Nửa số liệu = hàm DOT có tên đã duyệt (khớp MOUT §6.4 "DOT Function Registry", vd
fn_doanh_thu_theo_khach). - Cùng khung bind nhiều hàm; cùng hàm render nhiều khung. Đây là chỗ "nhanh hơn Excel".
3.2 Điều kiện đủ để DOT dựng bảng (siết chặt đề bài)
"Field có trong DB" là cần nhưng chưa đủ. Mỗi cột phải khai 3 thứ:
- source binding — field/biểu thức nuôi cột.
- display type — text/number/currency/date/percent/status → quyết định canh lề, định dạng, agg hợp lệ.
- agg — none/sum/avg/count/min/max. → Điều kiện đúng: field phải có trong field_registry với type đã duyệt. MOIT và MOUT dùng chung field_registry — một field khai một lần cả mặt nhập (widget MOIT) lẫn mặt xuất (format+agg MOUT). Một từ vựng field, hai khuôn mặt.
3.3 Một engine, ba profile (một schema, đổi mode)
- MOUT-List — báo cáo phẳng. STT + cột cố định liệt kê (khớp "nêu số cột, thứ tự cột"), dòng tổng bật/tắt từng cột, sort, phân trang, số liệu query-fed. ← trọng tâm vòng này.
- MOIT-Grid — ma trận nhập 2 chiều. Hàng × cột cố định, ô sửa được, tổng theo cột + tổng theo hàng + STT. ← cái MOIT 2 chiều còn thiếu. Ngoại lệ: tổng recompute client-side hợp lệ vì đang nhập, dữ liệu là toàn lưới trước mắt, không phân trang.
- MOUT-Pivot — ma trận cột động sinh từ một chiều dữ liệu (vd 12 tháng / N sản phẩm), tổng cả 2 trục (tổng hàng + tổng cột + tổng chung). Nền đã có ở Luật Pivot v4.0 / Điều 26 /
td-matrix-dimensions.md.
Ngã ba cốt tử: List = bạn enumerate cột; Pivot = cột do dữ liệu quyết định, không enumerate. Đừng cố một config diễn đạt cả hai — chọn theo loại báo cáo.
3.4 Contract khai báo (một schema)
{ table_id, title, mode:"list|grid|pivot", stt:true,
columns:[ {key,label,src:"field_registry.field_id",type,align,agg,editable} ], // pivot: thay bằng {row_dim,col_dim,metric,agg}
data:{ fn:"fn_*_đã_duyệt", params:{} },
totals_row:true }
stt,totals_row= primitive bật/tắt.columnsenumerated cho list/grid; pivot dùng row_dim/col_dim/metric.
4. Guard / phản biện (phải nhớ)
- Cấm khung cộng tiền. Totals = query-side. Nếu hiện "tổng tạm trang hiện tại" thì phải dán nhãn rõ là tạm.
- Cột % / dẫn xuất: CẤM agg=sum (cộng % vô nghĩa). Type system chặn, hoặc cho công thức tính lại tổng riêng. (Bẫy kinh điển Excel.)
- STT presentation-only, không persist, đánh số sau sort, offset-aware khi phân trang.
- Tổng phụ thuộc bộ lọc, không phụ thuộc sort. Đổi sort → tổng giữ; đổi filter → query lại tổng.
- "12 cột" = ngưỡng MỀM (Huyên xác nhận: con số đại khái, không quan trọng). Đề xuất: STT = cột 0 ngoài 12; quá 12 → cuộn ngang + freeze STT; in/xuất Excel không bị chặn cứng.
- Không đánh nhau với Excel ở ad-hoc. Có nút Xuất Excel làm cửa thoát ở ranh giới.
5. Vì sao nhanh hơn / bằng Excel
Khối dựng sẵn đã gõ kiểu & duyệt → không viết công thức, không chỉnh format, không quét vùng SUM (hết bug kéo thiếu dòng). Tổng đúng theo thiết kế (khai ở cột, chạy ở SQL). Khung tái dùng: nhân bản + đổi lọc kỳ = xong. Mở lại = số liệu live, không phải bản chụp tĩnh.
6. Preview đã dựng (vòng này)
mout-dot-table-v1.html (link luôn mot-theme-v1.css, đồng ngôn ngữ MOW/MOT):
- MOUT-List tương tác: tick cột, gạt Σ từng cột số, bật phân trang (chứng minh STT chạy tiếp + tổng giữ nguyên), panel JSON khai báo cập nhật live.
- MOIT-Grid: lưới nhập số, tổng cột + tổng hàng + grand total recompute khi gõ, flow tag direct/queue.
- MOUT-Pivot: cột quý động, tổng 2 trục + grand total.
- Mục "nhanh hơn Excel" + contract reference JSON + guard list.
7. Open items cho vòng sau
- MOUT-Pivot chi tiết: chọn row_dim/col_dim/metric qua UI; map vào 9 trục phân loại (
td-matrix-dimensions.md); subtotal theo nhóm (group → grand total) — pivot territory, chưa làm ở List v1. - field_registry: chốt schema field (type + display + agg hợp lệ) dùng chung MOIT/MOUT; nối với input KIT F01–F10 của MOT Studio.
- DOT Function Registry: đăng ký/duyệt hàm tổng hợp; params chuẩn (kỳ, vùng, filter) + governance (D0-G birth gate).
- Sort/lọc UI cho MOUT-List + tương tác với totals (re-query khi đổi filter).
- Export Excel escape hatch.
- Permission filter at backend (MOUT §6.4) + realtime gateway (push governance / pull report tĩnh — §13 open Q6).
- Quy ước đặt tên building block cho MOUT/MOIT (song song F/E/L/C của MOT): vd cột =
K, bảng =B, hàm số liệu =Q? — chờ Huyên chốt.
Ghi chú vòng 1 — sẽ bổ sung khi Huyên phản hồi preview.