E-004 — Onboard tổ chức¶
Nguồn: PRD prd-openapi-platform-2026-09-04 §5 (F2, F9) · spine
architecture-openapi-platform-2026-09-04 (AD-3, AD-20) · story chi tiết + AC ở
_bmad-output/planning-artifacts/epics.md (mục Epic E-004).
PO duyệt cấu trúc epic + ô parity: 05/09/2026 — duyệt cả danh sách epic và bảng story.
· bổ sung 11/09/2026 tối (PO chốt từng mục — UU-TIEN-GD1 §G): tách 2.4 → 2.4 đăng ký tài
khoản · 2.9 nộp hồ sơ (P4); thêm 1.9 · 1.10 người dùng TPP phía quản trị, chỉ xem (P2);
thêm 2.10 (nợ có thi công OAPI-131). Thứ tự 17–20, không dời hàng nào.
· bổ sung 12/09/2026 (PO chốt cả 8 mục — spine AD-30 lưu tệp đính kèm): thêm 1.11 kho + bảng đính kèm
đơn nộp (admin-be) · 2.11 điểm cuối nhận/trả tệp (portal-be). Thứ tự 21–22, không dời hàng nào.
· bổ sung 13/09/2026 (PO chốt OAPI-230-cô-lập-byte-kho-chung cách 1 — thu hồi SELECT trần của portal_app trên kho byte, thay bằng hàm lọc):
thêm 1.12 hàm lọc (admin-be) · 2.12 đổi câu đọc + hợp đồng (portal-be) · 1.13 REVOKE (admin-be) — ba nhịp vì chiều thu hồi
đảo AD-14; 1.2 và 2.11 đã archive nên khép bằng story mới. Thứ tự 23–25, không dời hàng nào.
· bổ sung 12/09/2026 (PO chốt): vai của người dùng trong tổ chức TPP — CHƯA LÀM, nợ có tên OAPI-205
(openapi-platform#23); 1.9/1.10 thôi trỏ «E-005» (không có story vai TPP ở đó). Không thêm hàng.
Hai cửa vào — bên thứ ba tự đăng ký, hoặc nhân sự ngân hàng nhập hộ. Cả hai đều qua thẩm định và phê duyệt, vì khoản 10 Điều 11 đặt nghĩa vụ thẩm định lên ngân hàng.
Vì sao làm — BRD tầng epic¶
Mục tiêu. Bên thứ ba vào hệ thống qua hai cửa — tự đăng ký hoặc nhân sự ngân hàng nhập hộ — và ngân hàng thẩm định rồi duyệt. Đây là phần thi hành nghĩa vụ thẩm định ở khoản 10 Điều 11.
Nhóm yêu cầu trong PRD — F2, F9¶
F2 — Hồ sơ TPP và tiếp nhận onboard¶
Hai cửa vào, một định nghĩa hồ sơ. PO chốt 04/09/2026: hồ sơ TPP vào hệ thống theo hai
đường — TPP tự đăng ký trên portal-fe (nhóm F9), hoặc nhân sự ngân hàng nhập từ admin-fe.
Cả hai đều phải qua phê duyệt. Bộ trường, quy tắc hợp lệ và trạng thái ở nhóm F2 là một
định nghĩa dùng chung; hai cửa vào không được đẻ ra hai bộ quy tắc, vì lúc đó cửa lỏng hơn
sẽ thành đường vòng của cửa chặt hơn.
- FR-008 Tạo hồ sơ TPP với mã số thuế làm định danh (TPP-ID).
- FR-009 Mã số thuế là duy nhất toàn hệ thống; hệ thống chặn tạo trùng.
- FR-010 Thẩm định mã số thuế còn hoạt động.
[ASSUMPTION C7]Chưa rõ có API tra cứu dùng được không. Giả định nhập tay, đính kèm bằng chứng, checker xác nhận; nếu có API thì thêm bước tự động chứ không bỏ bước người xác nhận. - FR-011 Loại pháp nhân TPP là trường bắt buộc, giá trị đóng: Ngân hàng · Tổ chức trung gian thanh toán · Tổ chức khác. Đổi giá trị này là thay đổi ràng buộc (xem FR-026).
- FR-012 Hồ sơ mang đủ 8 khối nội dung tối thiểu của Điều 8. Thiếu khối nào thì không cho
chuyển sang trạng thái chờ duyệt.
[ASSUMPTION]8 khối này ánh xạ thành bao nhiêu trường thật phụ thuộc mẫu hợp đồng bank đang dùng — chưa có mẫu đó. - FR-013 Trường cấp độ an toàn hệ thống thông tin của TPP, kèm tài liệu chứng minh.
- FR-014 Đính kèm tài liệu vào hồ sơ.
[ASSUMPTION C4]Chưa rõ hợp đồng ký giấy hay ký điện tử, và admin lưu bản scan hay chỉ metadata. Giả định lưu file đính kèm. - FR-015 Trạng thái hồ sơ: Nháp → Chờ duyệt → (Chờ bổ sung | Đã duyệt | Từ chối).
- FR-016 Trả hồ sơ về Chờ bổ sung kèm lý do bắt buộc (Điều 10.1).
- FR-017 Danh sách TPP có tìm kiếm và lọc theo trạng thái, loại pháp nhân, scope đang có.
- FR-018 Nhập dữ liệu TPP đang đấu nối sẵn.
[ASSUMPTION C3]Chưa rõ có TPP nào đang đấu nối trực tiếp không. Nếu có, đây không phải hệ thống trắng mà là hệ thống có dữ liệu di trú, và Điều 15.1 buộc bank đã phải lập danh mục đó rồi.
F9 — Cổng TPP tự đăng ký (portal-fe + portal-be)¶
- FR-054 Bên thứ ba tự tạo tài khoản người dùng trên
portal-fevà tự nộp hồ sơ đăng ký. - FR-055 Tách bạch hai loại danh tính của TPP — đây là chỗ dễ trộn nhất khi mở cổng tự phục vụ:
- Tài khoản người dùng của TPP: người thật đăng nhập
portal-feđể nộp và theo dõi hồ sơ. Tồn tại trước khi TPP được duyệt, vì không có nó thì không ai nộp được gì. - Credential ứng dụng:
client_idvàclient_secretdùng gọi Open API. Chỉ cấp sau khi hồ sơ được duyệt — Phụ lục 01 §1 nói TPP đăng ký credential sau khi đã thiết lập kênh an toàn với ngân hàng.
Trộn hai thứ này lại thì hoặc phải cấp credential cho một TPP chưa thẩm định, hoặc không cho ai nộp hồ sơ được. Cả hai đều sai. - FR-056 Hồ sơ TPP tự nộp dùng đúng bộ trường và đúng quy tắc hợp lệ của nhóm F2, gồm cả 8 khối Điều 8 (FR-012) và loại pháp nhân (FR-011). - FR-057 ⛔ Hồ sơ TPP tự nộp không đi thẳng tới checker. Phải có một nhân sự ngân hàng tiếp nhận và thẩm định, đóng vai maker, trước khi hồ sơ tới checker.
Lý do là pháp lý chứ không phải quy trình: Điều 11.10 đặt nghĩa vụ thẩm định lên ngân hàng. Nếu để TPP đóng vai maker thì "hai người" là TPP cộng checker — mà TPP không phải người của ngân hàng, nên ngân hàng chưa thẩm định gì cả. Hồ sơ tự nộp là đầu vào, không phải nửa đầu của cặp maker/checker. - FR-058 TPP theo dõi được trạng thái hồ sơ và bổ sung khi bị trả về Chờ bổ sung (FR-016). Lý do trả về hiển thị cho TPP; ghi chú nội bộ của ngân hàng thì không. - FR-059 Chống lạm dụng đường đăng ký công khai: giới hạn tần suất tạo tài khoản và nộp hồ sơ theo nguồn, xác minh email trước khi cho nộp, chặn dò mã số thuế bằng cách không tiết lộ mã số thuế đó đã tồn tại trong hệ thống hay chưa.
Đây là đường ghi từ Internet vào kho hồ sơ pháp lý — thứ mà giai đoạn chỉ-có-admin không có.
- FR-060 TPP xem được client_id đã cấp và yêu cầu xoay client_secret (FR-029). Yêu cầu
xoay vẫn qua phê duyệt phía ngân hàng; client_secret mới hiển thị đúng một lần (FR-028).
Bảng story → change¶
| Story | Service | Thứ tự bắt buộc | Ghi chú | Chặn bởi |
|---|---|---|---|---|
E-004/1.1 Schema Tổ chức và hồ sơ |
admin-be | 1 | cap/tpp-onboarding · mã số thuế là khoá tự nhiên, loại pháp nhân là enum bắt buộc · ⚠️ PO chốt 11/09 (tại làn admin-be, memlog change tpp-organization-schema @ d810c85): V12 BỎ trang_thai và ngay_duyet khỏi app.tpp — không SHALL, không design, không test; V11 đã ghi «cột trạng thái là nguồn sự thật thứ hai». Vòng đời/trạng thái hồ sơ là việc của 1.3. ⇒ Câu «trạng thái, ngày duyệt» ở epics.md:485 là nguyên liệu đã hết hiệu lực (⛔G1: không sửa ngược), hàng này là nơi ghi. Cùng lượt PO chốt: 8 khối Điều 8 đi bằng noi_dung jsonb (hoãn lần hai, có nợ) · tpp_profile chỉ-thêm · portal_app không SELECT trần (lệch AD-20 lần 2, vết ở OAPI-121) · đính kèm chỉ metadata |
M:E-001/1.1 · M:E-001/1.2 |
E-004/1.2 Thẩm định mã số thuế |
admin-be | 2 | cap/tpp-onboarding · nhập tay + checker xác nhận |
M:E-004/1.1 · M:E-001/3.1 |
E-004/1.3 Vòng đời hồ sơ |
admin-be | 3 | cap/tpp-onboarding · qua khung phê duyệt E-001/3.1 |
M:E-004/1.1 · M:E-001/3.1 |
E-004/2.1 Tài khoản người dùng của bên thứ ba |
portal-be | 4 | cap/tpp-self-registration · tách hẳn khỏi người dùng nội bộ |
M:E-001/0.2 · M:E-001/1.2 |
E-004/1.6 Khai bảng SUBMISSION và ma trận quyền portal_app |
admin-be | 5 | cap/schema-migration · ⛔ vật mang của E-004/2.2 · AD-14: bảng portal-be GHI vẫn do admin-be KHAI |
M:E-001/1.1 |
E-004/1.7 Khai bảng phiên cho người dùng bên thứ ba |
admin-be | 6 | cap/schema-migration · ⛔ vật mang của E-004/2.8 · AD-14 · ⚠️ phạm vi chốt bằng số đo của portal-be trước khi mở change |
M:E-001/1.1 · TK:E-004/2.8 |
E-004/2.8 Xác thực và phiên cho người dùng bên thứ ba |
portal-be | 7 | cap/tpp-self-registration · AD-19 phiên có trạng thái · khoá tạm 3 lần / 15 phút (cấu hình, ⛔ không hằng số) · quên mật khẩu câu trung lập · đổi mật khẩu trong phiên · ⛔ tách hẳn đường xác thực nội bộ (AD-20) · chặn tới khi 1.7 xong |
M:E-004/1.7 · M:E-004/2.1 · Đ:E-001/4.1 |
E-004/2.2 Đơn nộp hồ sơ |
portal-be | 8 | cap/tpp-self-registration · SUBMISSION tự chứa, không khoá ngoại tới TPP · ✅ 1.6 đã xong (admin-be 2d0909b, V5__khai_bang_submission.sql) · nay chặn bởi 2.8: nộp hồ sơ là hành động của người đã đăng nhập |
M:E-004/1.6 · M:E-004/2.8 |
E-004/2.3 Chống lạm dụng đường đăng ký công khai |
portal-be | 9 | cap/abuse-protection · căn cứ FR-059, KHÔNG phải Điều 11.9 |
M:E-004/2.1 |
E-004/1.4 Màn hồ sơ tổ chức |
admin-fe | 10 | cap/admin-console-ui · ⛔ màn riêng không modal · ô lý do nhắc hiển thị ra ngoài · PO chốt 13/09/2026: M:1.3 → Đ:1.3 — FE đi trước API vòng đời hồ sơ theo tiền lệ E-001/5.12 (Đ:2.4) và E-001/5.9 (P7, Đ:E-004/2.8): dựng trên gói (OrgList · OrgDetailScreen · OrgCreateModal) + máy chủ giả lập theo nếp port, màn tự khai chỗ chưa nối (§F); ⛔ không coi là xong khi 1.3 chưa archive và chưa nối thật · hợp đồng API 1.3 chưa có (OAPI-224 mới mở) ⇒ làn admin-fe nhắn admin-be xin openapi.yaml sớm (AD-28) |
Đ:E-004/1.3 · M:E-001/5.5 |
E-004/2.4 Màn đăng ký tài khoản |
portal-fe | 11 | cap/tpp-portal-ui · PO tách 11/09 tối (P4): CHỈ còn đăng ký tài khoản (3 bước theo gói «Đăng ký tài khoản»), nộp hồ sơ sang 2.9 · ô đồng ý hai văn bản dẫn sang 2.6 · ⛔ §F UU-TIEN-GD1: đăng ký tạm tự động kích hoạt, bước xác minh email để //TODO đúng chỗ + màn tự khai, nợ có điều kiện trả (cổng gửi thư) — đường BE là change mới có tên ở portal-be, ⛔ không vá 2.1 đã archive · ✅ hết chặn: 2.1 và 5.6 đều archive |
M:E-004/2.1 · M:E-001/5.6 · Đ:E-004/2.6 |
E-004/2.5 Tiếp nhận đơn nộp |
admin-be | 12 | cap/tpp-onboarding · ⛔ đơn KHÔNG đi thẳng tới checker |
M:E-004/2.2 · M:E-004/1.3 |
E-004/1.5 Nhập dữ liệu tổ chức đang đấu nối |
admin-be | 13 | cap/tpp-onboarding · ⚠️ BỊ CHẶN: chưa rõ có tổ chức nào |
M:E-004/1.1 · ⛔NGOÀI:chưa rõ có tổ chức nào |
E-004/2.6 Khung hai văn bản pháp lý |
portal-fe | 14 | cap/tpp-portal-ui · điều khoản 9 mục + chính sách dữ liệu 8 mục · bảng bốn cột chuyển thẻ dưới 768px |
M:E-001/5.4 |
E-004/1.8 Khai bảng phiên bản văn bản pháp lý và vết đồng ý |
admin-be | 15 | cap/schema-migration · ⛔ vật mang của E-004/2.7 · AD-14 · ⛔ không ghi đè tại chỗ: bảng phải giữ được NHIỀU phiên bản và vết ai đồng ý bản nào |
M:E-001/1.1 · TK:E-004/2.7 |
E-004/2.7 Nội dung pháp lý có phiên bản và vết đồng ý |
portal-be | 16 | cap/tpp-self-registration · ⛔ không ghi đè tại chỗ · ghi ai đồng ý PHIÊN BẢN NÀO, lúc nào |
M:E-004/1.8 |
E-004/2.9 Màn nộp hồ sơ |
portal-fe | 17 | cap/tpp-portal-ui · tách từ 2.4 11/09 tối (P4) · 8 khối theo Điều 8 · lưu nháp tự động · là hành động của người đã đăng nhập (2.8) · tuyến «Hồ sơ đăng ký» hiện là màn tự khai chưa dựng |
M:E-004/2.2 · M:E-004/2.8 · M:E-004/2.4 |
E-004/1.10 API xem người dùng bên thứ ba theo tổ chức |
admin-be | 18 | cap/tpp-onboarding · mở 11/09 tối (PO chốt P2: A3 = CHỈ XEM) · liệt kê + chi tiết app.tpp_user gom theo tổ chức (admin_app đã có SELECT từ V3) · ⛔ 2.1 (portal-be) đã archive, không đụng · ⛔ KHÔNG gán vai, KHÔNG khoá/mở trong story này — gán vai chờ nguồn vai TPP — nợ có tên OAPI-205 (openapi-platform#23; ~~E-005~~ ⛔ đo 12/09 E-005 không có story vai TPP, trỏ vào đó là trỏ chỗ trống), khoá/mở là thao tác ràng buộc (K2 + duyệt 3.1) ⇒ nợ có tên, mở story sau khi hai nguồn đó có |
M:E-004/1.1 · M:E-001/2.3 |
E-004/1.9 Màn xem người dùng bên thứ ba (phía quản trị) |
admin-fe | 19 | cap/admin-console-ui · mở 11/09 tối (PO chốt P2: A3 = CHỈ XEM) · gói AccountList({scope:"tpp"}) (cột Tổ chức + Vai trò trong tổ chức, ⛔ không nút Tạo mới) + khối «Người dùng thuộc tổ chức» trong OrgDetailScreen · cột Vai trò trong tổ chức ⛔ chưa có nguồn (nợ vai TPP OAPI-205, openapi-platform#23) ⇒ lượt đầu bỏ, ghi nợ cùng nếp OAPI-142 · ⛔ không nút gán vai / khoá / mở (xem 1.10) |
M:E-004/1.10 · M:E-001/5.5 · M:E-001/5.10 |
E-004/2.10 Giới hạn tốc độ ngoài đường đăng nhập và độ dài tối thiểu khi đổi mật khẩu |
portal-be | 20 | cap/abuse-protection · mở 11/09 tối (PO chốt — luật nợ sau archive, E-001 §Bổ sung 11/09) · nhà của issue có sẵn OAPI-131 (portal-be#28), nợ phát hiện sau khi 2.8 archive · đổi trailer **Story:** trên body issue #28 từ E-004/2.8 thành E-004/2.10 (mối nối thật; link.yaml cũ không chứa #28 — số đo làn portal-be 11/09) |
M:E-004/2.8 |
E-004/1.11 Khai bảng đính kèm của đơn nộp và kho nội dung tệp |
admin-be | 21 | cap/schema-migration · mở 12/09 (PO chốt 8 mục — AD-30) · ⛔ vật mang của E-004/2.11 · AD-14 · app.submission_attachment (metadata, nối submission, khuôn V12 tpp_attachment: ten_file · loai_mime · kich_thuoc_byte · bam · duong_dan = khoá kho db:<uuid>) + app.tep_noi_dung (bytea, xoá được — AD-30 mục 1) · GRANT portal_app INSERT/SELECT theo hàng (nếp V5), ⛔ không UPDATE/DELETE · ⛔ hình dạng do 2.11 chốt trong design.md trước, 1.11 không tự đoán — ba nhịp như cặp 1.7/2.8 · trả nợ OAPI-149 (admin-be#53) |
M:E-004/1.6 · TK:E-004/2.11 |
E-004/2.11 Điểm cuối nhận tệp đính kèm cho đơn nộp và trả tệp cho chính người nộp |
portal-be | 22 | cap/tpp-self-registration · mở 12/09 (PO chốt 8 mục — AD-30) · multipart, PDF/JPG theo magic bytes, ≤ 10 MB là cấu hình (gói design màn nộp hồ sơ khối 2: 3 tài liệu, 2 bắt buộc) · bam = sha256: tính khi nhận · trả tệp Content-Disposition: attachment + nosniff, ⛔ không inline (AD-30 mục 3) · T_iso: chỉ tệp của đơn thuộc tổ chức mình, 404 vô hình · ⛔ không quét mã độc trong story này — nợ có cổng của AD-30 · nhịp 1: chốt hình dạng bảng gửi admin-be (ghi vào issue của 1.11) trước khi viết mã nối · trả nợ OAPI-151 (portal-be#31); mở đường cho OAPI-176 (portal-fe#26) |
M:E-004/1.11 · M:E-004/2.2 |
E-004/1.12 Hàm lọc đọc byte kho tệp cho portal_app |
admin-be | 23 | cap/schema-migration · mở 13/09 (PO chốt OAPI-230-cô-lập-byte-kho-chung cách 1) · nhịp ①/③ thu hồi SELECT trần trên app.tep_noi_dung · hàm trả noi_dung chỉ khi khoá kho thuộc đính kèm của đơn người gọi (join submission_attachment_of_user, nếp V18) · ⛔ SECURITY INVOKER không đủ sau thu hồi ⇒ DEFINER hẹp + SET search_path + REVOKE FROM PUBLIC + GRANT EXECUTE portal_app · ⛔ chưa thu hồi gì ở đây (chiều THÊM — admin-be trước) |
— |
E-004/2.12 Đọc byte qua hàm lọc, bỏ SELECT trần khỏi hợp đồng |
portal-be | 24 | cap/tpp-self-registration · mở 13/09 (PO chốt OAPI-230 cách 1) · nhịp ②/③ · AttachmentJdbcRepository.FIND_CONTENT (SELECT noi_dung FROM app.tep_noi_dung) → gọi hàm của 1.12 · DatabaseContract: bỏ SELECT khỏi tập bắt buộc của app.tep_noi_dung (giữ INSERT theo cột), khai EXECUTE hàm — cổng hai chiều, THỪA cũng đỏ · T_iso giữ nguyên: 404 vô hình |
M:E-004/1.12 |
E-004/1.13 Thu hồi SELECT trần của portal_app trên app.tep_noi_dung |
admin-be | 25 | cap/schema-migration · mở 13/09 (PO chốt OAPI-230 cách 1) · nhịp ③/③ · V2x REVOKE SELECT ON app.tep_noi_dung FROM portal_app + ma trận quyền + lưới · đo has_table_privilege('portal_app','app.tep_noi_dung','SELECT') = false · ⛔ TR: bản portal-be của 2.12 phải chạy trên mọi môi trường TRƯỚC khi migration này chạy — chiều THU HỒI đảo AD-14, án lệ V7/OAPI-83-dat-updated-at-không-revoke-execute |
M:E-004/2.12 · TR:E-004/2.12 |
| Câu | Chốt | |||
| --- | --- | --- | ||
| 1 | NFR-003 không có số — bao lâu không hoạt động thì hết phiên |
15 phút (áp cả E-001/2.3) |
||
| 2 | FR-007 ghi vào đâu |
E-001/4.1 — story đã có, ⛔ không mở story mới; xem E-001 |
||
| 3 | đổi mật khẩu và đăng xuất, gói design chưa vẽ màn | làm back-end trước |
Bổ sung 07/09/2026 (PO duyệt) — hai văn bản pháp lý. 2.6 và 2.7 sinh từ hệ thống thiết kế,
trước đó không epic nào mang chúng. Chúng nằm trên đường đi bắt buộc: ô đồng ý ở màn đăng ký
tài khoản dẫn sang, nên 2.4 không hoàn thành được nếu thiếu. ⛔ Thứ tự 11–12 là thứ tự MỞ VIỆC,
không phải thứ tự phụ thuộc: 2.6 phải xong trước khi 2.4 được coi là đóng.
⚠️ 2.7 không phải trang đọc. Chỉ làm trang đọc thì không có bằng chứng ai đã đồng ý điều khoản
phiên bản nào, lúc nào — đúng loại bằng chứng thanh tra hỏi. Cùng nếp BL-03 đã chốt cho hồ sơ:
có phiên bản, không ghi đè tại chỗ. Bảng thời hạn lưu chạm Nghị định 13/2023/NĐ-CP và trục T_pii.
⛔ Phụ thuộc NGOÀI đội: câu chữ hiện tại trong thiết kế là bản nháp phục vụ thiết kế, phải thay
bằng bản do Pháp chế và Tuân thủ MSB duyệt trước khi phát hành. Cấu trúc mục thì giữ, nội dung thì không.
PO duyệt 08/09/2026 — làm KHUNG ngay, nội dung thành NỢ CÓ CỔNG. 2.6 và 2.7 không chờ
Pháp chế: nội dung là dữ liệu, không phải mã, nên khi có bản duyệt thì thay bằng cách thêm một
phiên bản, không sửa dòng mã nào. Hai ràng buộc kèm theo, cả hai là điều kiện của lượt duyệt này:
- Bản nháp mang cờ
NHAPngay TRONG chính dữ liệu phiên bản, ⛔ không phải một banner rời trên giao diện — banner là thứ quên gỡ được mà không ai đỏ. - ⛔ Cổng fail-closed: môi trường thật từ chối mở đường đăng ký công khai khi phiên bản văn
bản đang hiệu lực còn cờ
NHAP. Đây là chỗ biến nợ thành thứ không quên được; một dòng ghi chú trong tài liệu thì không.
⚠️ Vì sao phải có cổng chứ không chỉ ghi nợ: vết đồng ý của 2.7 sẽ trỏ tới một phiên bản
không có hiệu lực pháp lý — tức bằng chứng «ai đồng ý cái gì» vô giá trị đúng lúc thanh tra
hỏi, mà đó chính là thứ 2.7 sinh ra để có. Thêm nữa, Nghị định 13/2023/NĐ-CP đòi thông báo xử lý
dữ liệu cá nhân đúng nội dung (mục đích · loại dữ liệu · thời hạn lưu · quyền của chủ thể) —
sai nội dung là vi phạm thật, không phải lỗi hình thức.
Điều kiện trả nợ: Pháp chế và Tuân thủ MSB duyệt câu chữ hai văn bản — và bắt buộc trước khi
mở đăng ký cho TPP thật. Nợ ghi ở portal-fe (khung 2.6) và portal-be (phiên bản + vết đồng ý
2.7). ⚠️ Một câu chỉ Pháp chế trả lời được, hỏi cùng lượt: khi bản chính thức thay bản nháp,
người đã đồng ý bản nháp có phải đồng ý lại không — kỹ thuật làm được cả hai đường, chọn đường
nào là câu pháp lý.
Bổ sung 12/09/2026 (PO chốt cả 8 mục) — E-004/1.11 và 2.11, tệp đính kèm cho đơn nộp; spine AD-30.
Làn portal-be đo 12/09 theo yêu cầu PO: chưa có issue nào mở được cho điểm cuối tải tệp — ba nợ ở ba repo
(OAPI-149-kho-lưu-tệp-chưa-có-chủ admin-be#53 · OAPI-151-đính-kèm-tài-liệu-hồ-sơ portal-be#31 ·
OAPI-176-tải-tệp-màn-nộp-hồ-sơ portal-fe#26) cùng trỏ về một chỗ thiếu: spine không có quyết định lưu tệp
(review-compliance.md Đ5/Đ8 treo từ 04/09) và epic không có story. Trên đĩa: admin-be V12 app.tpp_attachment
chỉ metadata, nối tpp_profile, REVOKE ALL … FROM portal_app (PO 10/09, T_iso); app.submission V5
không có cột đính kèm ⇒ portal_app không có vật mang. ⇒ PO chốt AD-30 (nội dung tệp trong PostgreSQL,
bảng riêng xoá được, khoá kho db:<uuid>, PDF/JPG ≤ 10 MB theo magic bytes, không inline, quét mã độc là nợ có
cổng, tải về theo T_iso + nhật ký) và hai story này.
⛔ Hai bảng đính kèm là hai thực thể, không phải một bảng dùng chung. submission_attachment gắn với đơn
(tự chứa, portal_app ghi); tpp_attachment gắn với phiên bản hồ sơ chính thức (admin_app ghi, V12). Khi
2.5 tiếp nhận đơn, admin-be chép metadata sang tpp_attachment với cùng bam và cùng khoá kho — ⛔ không
chép byte, một hàng tep_noi_dung phục vụ cả hai. Đó là nợ có tên của 2.5, ghi ở AD-30.
⛔ Thứ tự thi công là ba nhịp, chép nguyên cặp 1.7/2.8: portal-be mở 2.11, chốt hình dạng hai bảng trong
design.md kèm lý do từng cột, chỗ chưa chắc khai là chưa chắc (tiền lệ V5 noi_dung jsonb), ghi vào issue của
1.11 → admin-be khai + GRANT đúng hình dạng đó, báo portal-be trước khi merge → portal-be nối adapter, đóng
2.11. Số thứ tự 21–22 là thứ tự merge, không phải thứ tự bắt đầu. Ba điều kiện cổng khởi động portal-be
(quyền ngoài hợp đồng · EXECUTE qua PUBLIC · CREATE/USAGE lạ) áp nguyên — trigger giữ mốc của bảng mới phải
REVOKE EXECUTE … FROM PUBLIC như V12 đã làm cho tpp_attachment_giu_moc_tao().
Thành viên trong tổ chức — HOÃN CÓ GHI (PO duyệt 07/09/2026). Mô hình một tổ chức nhiều người
dùng thuộc đợt sau: Thông tư không đòi, và giai đoạn 1 mỗi tổ chức có thể chỉ cần một tài khoản.
⛔ Nhưng phép kiểm trục T_iso phải viết theo «TẬP người dùng của tổ chức», không theo «người dùng
duy nhất của tổ chức» — kỳ vọng là 404 vô hình giữa hai tổ chức. Viết đúng cách ngay thì thêm thành
viên sau không phải viết lại mọi phép kiểm cô lập đã ký. Màn Tổ chức phía quản trị đã có khối
«Người dùng thuộc tổ chức», nên quan hệ nhiều-một là có thật trong mô hình.
Vai của người dùng trong tổ chức — CHƯA LÀM, nợ có tên OAPI-205 (openapi-platform#23; PO chốt 12/09/2026).
Đo 12/09 ở năm tầng: PRD chỉ nói «nhiều Vai» cho người dùng nội bộ; spine không AD nào; app.tpp_user
(V2→V12) không cột vai, không bảng vai/gán vai; portal-be không thi hành; gói design chỉ có mock hai giá
trị (Người đại diện · Kỹ thuật) — nguồn hình ảnh, không phải nguồn nghiệp vụ. GĐ1: mọi người dùng cùng
tổ chức quyền như nhau, cách ly giữa tổ chức bằng T_iso. ⛔ E-005 không có story vai TPP —
câu «chờ nguồn vai TPP (E-005)» ở 1.10 (11/09) là trỏ vào chỗ trống, đã sửa trỏ về nợ. Trả nợ đi ba
chặng theo thứ tự (mô hình ở PRD/spine → admin-be khai bảng theo AD-14, story riêng → thi hành ở
portal-be + hai front-end), sớm nhất cùng lúc mở mô hình thành viên ở đoạn trên; điều kiện trả ghi
trên issue.
Thứ tự trộn hai nhóm là cố ý. Phía ngân hàng (1.1–1.3) phải xong trước khi cổng bên thứ
ba mở, vì 2.5 tiếp nhận đơn cần hồ sơ chính thức đã có schema. Nhưng 2.1–2.3 chạy song
song được — chúng chỉ ghi bảng đơn.
Bổ sung 08/09/2026 (PO duyệt) — E-004/2.8, mắt xích THỨ HAI và là mắt xích chặn nhiều nhất.
PO phát hiện: gói design đã có thiết kế đăng ký/đăng nhập cho bên thứ ba, mà bảng story không
có story back-end nào cho việc đó. Đo lại, đúng: E-004/2.1 (đã archive) chỉ giao kho tài khoản
+ xác minh email; E-001/5.9 là màn và hạ tầng phiên phía giao diện của portal-fe. Toàn bộ
nửa back-end — xác thực, phiên, khoá tạm, quên mật khẩu, đổi mật khẩu — không thuộc story nào.
⛔ Đăng nhập chặn mọi story phía sau nó ở cổng bên thứ ba, kể cả 2.2: nộp hồ sơ là hành động
của một người đã đăng nhập. Vì thế 2.8 xếp trước 2.2; số thứ tự của các story sau dời
xuống. (Cập nhật cùng ngày: 2.8 nay ở thứ tự 7, sau khi 1.7 — bảng phiên — chèn vào vị trí
6. Bảng là nguồn; con số trong đoạn văn này chỉ để đọc.)
Bổ sung 08/09/2026 (PO duyệt) — E-004/1.7 và 1.8, hai cặp khai bảng còn thiếu. Cùng dạng
1.6, phát hiện khi soát 11 epic: AD-14 buộc mọi bảng do admin-be khai, kể cả bảng
portal-be ghi.
- 1.7 bảng phiên — AD-19 đòi phiên có trạng thái, kiểm thu hồi mỗi yêu cầu, tức phải có
nơi lưu. Đo trên admin-be 2d0909b: app.tpp_user 9 cột (id · email ·
email_normalized · password_hash · tpp_id · email_verified_at · disabled_at ·
created_at · updated_at), không cột nào giữ trạng thái phiên; V1–V5 không migration
nào khai bảng phiên.
⚠️ Phạm vi chốt bằng số đo của portal-be trước khi mở change — «bảng phiên trong CSDL hay
phiên giữ nơi khác mà vẫn thoả AD-19» là quyết định thiết kế của 2.8, không phải của story
này. ⛔ Làn portal-be không trả lời khi chưa được giao 2.8: kết luận lúc đó là ra quyết định
kiến trúc cho một story chưa ai giao, rồi admin-be mở story dựa trên kết luận ấy.
✅ PHẠM VI ĐÃ CHỐT 08/09/2026 — TỐI ĐA: «khai bảng + cấp quyền». Làn portal-be (được PO cho
phép trả lời) soi bốn yêu cầu của 2.8 vào schema đang có (admin-be 2d0909b, đúng ba bảng
tpp_user · tpp_user_verification · submission): thu hồi phiên — không cột nào mang được;
khoá tạm 3 lần/15 phút — không cột nào đếm được lần sai hay giữ mốc hết khoá; quên mật khẩu —
hình dạng trùng tpp_user_verification nhưng bảng đó của xác minh email, dùng chung vẫn phải
thêm cột phân loại, tức vẫn đổi schema; đổi mật khẩu — chỉ vế ghi là có sẵn.
⛔ Và vế thu hồi không có đường tránh: AD-19 cho hai hình dạng (phiên phía máy chủ hoặc
token có tra danh sách thu hồi) — hình một hiển nhiên cần bảng; hình hai cần chỗ giữ danh sách,
mà disabled_at chỉ phủ khoá tài khoản, còn một cột kiểu sessions_valid_from phủ được «rụng
TẤT CẢ phiên» nhưng không phủ được đăng xuất một phiên — muốn huỷ đúng một phiên thì phải có
định danh phiên, tức trạng thái theo từng phiên. ⇒ Dưới mọi cách đọc AD-19, 2.8 cần trạng
thái mới trong CSDL.
Ba mảnh trạng thái chưa tồn tại, để 1.7 ước lượng đúng kích thước: ① phiên theo từng phiên
(thu hồi được) · ② đếm lần đăng nhập sai + mốc hết khoá tạm · ③ mã đặt lại mật khẩu (hash, hạn, đã
dùng). ⛔ Ba mảnh không đồng nghĩa ba bảng — chia thế nào là thiết kế của 2.8, không phải
của 1.7.
⚠️ Hai điều khoản cộng lại chứ không mâu thuẫn: AD-27 đã liệt «khoá ký phiên» vào danh sách bí
mật đọc qua configtree (spine dòng 914), tức kiến trúc đã tính tới token có ký; nhưng AD-19 vẫn
đòi tra thu hồi mỗi yêu cầu ⇒ ký thôi chưa đủ, vẫn cần trạng thái.
⚠️ E-004/2.8 nhiều khả năng là lần đầu dự án dựng phiên — E-001/2.2 (xác thực nội bộ) chưa mở
issue nào. AD-20 cấm hai đường xác thực dùng chung, nên hai bên không dùng chung bảng; nhưng
bản 1.7 khai sẽ thành khuôn tham chiếu cho E-001/2.2 sau này.
⛔ HÌNH DẠNG bảng phiên do 2.8 chốt, 1.7 KHÔNG tự đoán (làn admin-be hỏi 08/09/2026, và
câu hỏi đó lộ ra một lỗ trong cách xếp thứ tự). Bảng story đặt 1.7 (khai) trước 2.8 (thiết
kế), nhưng cột gì, thu hồi biểu diễn thế nào, ba mảnh trạng thái chia thành mấy bảng — là quyết
định thiết kế của 2.8. admin-be khai trước rồi khoá portal-be vào một hình dạng họ không
chọn là lặp lại đúng lỗi 1.6 theo chiều ngược. ⇒ Thứ tự thi công thực tế là ba nhịp:
1. portal-be mở change 2.8, chốt hình dạng phiên trong design.md và gửi thẳng admin-be
(ghi vào OAPI-75) — chưa viết mã nối;
2. admin-be khai bảng + GRANT theo đúng hình dạng đó, báo portal-be TRƯỚC khi merge, merge;
3. portal-be khai hợp đồng quyền trong mã, nối adapter, đóng 2.8.
Số thứ tự trong bảng (1.7 = 6, 2.8 = 7) là thứ tự merge: bảng phải lên trunk trước mã dùng
nó. Nó không phải thứ tự bắt đầu — 2.8 bắt đầu trước để cho 1.7 đầu vào.
⛔ Nhịp 1 là nhịp MỘT CHIỀU — ràng buộc sinh từ chính ba nhịp (làn portal-be nêu 08/09/2026).
design.md của 2.8 thành đầu vào cho một migration ở repo khác, mà AD-14.1 chỉ cho THÊM.
⇒ Từ lúc admin-be merge bảng theo hình dạng portal-be giao, portal-be không sửa lại hình
dạng ấy được nữa — một cột đặt sai kiểu ở nhịp 1 là nợ vĩnh viễn, nằm trong repo của người
khác. Không phải lý do đổi ba nhịp; là lý do đổi việc của nhịp 1: hình dạng giao đi phải kèm
lý do cho từng cột, và chỗ chưa chắc phải khai là chưa chắc chứ không im lặng chọn một kiểu.
Tiền lệ để chép: V5 — cột noi_dung jsonb + noi_dung_phien_ban, admin-be khai thẳng hình dạng
thật chưa biết và mã hoá cái chưa-biết thành một cột có phiên bản, thay vì đoán tám cột.
⛔ Ba điều kiện làm cổng khởi động portal-be ĐỎ — để hai bên có cùng MỘT PHÉP THỬ thay vì cùng
một niềm tin (đo ở OAPI-51, postgres:18, fixture thật):
1. portal_app có bất kỳ quyền nào trong tám quyền mức bảng trên một bảng ngoài hợp đồng;
2. portal_app EXECUTE được bất kỳ hàm nào ngoài hợp đồng — ⛔ kể cả khi không ai GRANT gì,
vì PostgreSQL cấp EXECUTE cho PUBLIC mặc định trên mọi hàm mới. Đây là ca dễ vướng nhất:
một migration admin-be chỉ cần CREATE FUNCTION trong lược đồ app là cổng đỏ, dù không câu
GRANT nào nhắc portal_app. ⚠️ REVOKE ALL ON <bảng> không phủ hàm — phải REVOKE EXECUTE
… FROM PUBLIC, hoặc báo portal-be khai vào hợp đồng. Ca T1.30: CREATE FUNCTION app.ham_la()
không kèm GRANT ⇒ đỏ; mutation-bite xác nhận phép quét hàm là load-bearing (vô hiệu ⇒ 3 ca đỏ);
3. portal_app có CREATE trên app, hoặc USAGE trên một lược đồ ngoài app/public.
Ngược lại, một bảng mà portal_app không có quyền nào thì không xuất hiện trong tập quét —
vô hình với cổng đúng nghĩa, không phải may. Đó là lý do REVOKE ALL ON app.internal_user FROM
portal_app ở V6 an toàn.
⛔⛔ NỐI ĐUÔI LÀ LUẬT HAI CHIỀU — THU HỒI quyền cũng là thay đổi phá vỡ, y như cấp thêm (làn
portal-be đo 08/09/2026; làn admin-be đã nhận vào design.md D10 của OAPI-54). Cổng khởi động
của portal-be kiểm hàm hai chiều: quyền ngoài hợp đồng ⇒ ĐỎ thừa; quyền hợp đồng khai mà CSDL
không còn ⇒ ĐỎ thiếu. Ca cụ thể — app.dat_updated_at() (trigger updated_at, V2) lọt EXECUTE
qua PUBLIC; hợp đồng portal-be đã khai nó (DatabaseContract.java:279, «PHẢI có mặt dù repo
này KHÔNG BAO GIỜ gọi nó») nên hôm nay cổng XANH. Đo ba chiều: portal_app gọi thẳng ⇒ «trigger
functions can only be called as triggers»; UPDATE ⇒ trigger chạy, updated_at đổi; REVOKE … FROM
PUBLIC rồi UPDATE ⇒ vẫn chạy — trigger dùng quyền chủ bảng, không dùng quyền người gọi.
⇒ REVOKE an toàn, đích là admin-be REVOKE + portal-be bỏ khai. Nhưng bốn trạng thái:
| CSDL | hợp đồng | cổng |
|---|---|---|
A · chưa REVOKE |
khai allowed | XANH — hôm nay |
B · đã REVOKE |
vẫn khai | ⛔ ĐỎ thiếu |
C · đã REVOKE |
đã bỏ khai | XANH — đích |
D · chưa REVOKE |
đã bỏ khai | ⛔ ĐỎ thừa |
Đi một mình bên nào cũng rơi vào ô đỏ — nên «admin-be REVOKE trước, OAPI-51 merge sau» là
đường A→B→C và ô B đỏ. Cửa sổ đỏ ấy không tồn tại chỉ nhờ một điều dễ bỏ sót: portal-be
trên trunk hôm nay chưa quét hàm — phép quét ra đời cùng OAPI-51. ⇒ Luật gọn thay mọi bảng
thứ tự: OAPI-51 merge SAU CÙNG. (1) admin-be merge V7 REVOKE bất cứ lúc nào, tác động bằng
không — báo portal-be trước khi merge đúng nếp, nhưng là báo, ⛔ không phải chờ họ bỏ khai rồi
mới merge; (2) portal-be bỏ khai và chép REVOKE vào fixture cùng một commit, và chỉ SAU KHI
V7 đã lên main của admin-be — bỏ sớm là lưới của chính họ rơi ô D, hai file rời nhau cũng rơi ô
D; (3) OAPI-51 merge, hạ cánh thẳng ô C. (Hai làn từng viết hai bản khác nhau về bước 1–2; bản
này là bản khớp với bảng bốn trạng thái — khắc để không còn hai bản.) Điều kiện triển khai đi kèm là nếp
AD-14 sẵn có: bản admin-be mang V7 triển khai trước bản portal-be mang OAPI-51.
⚠️ Cập nhật cùng ngày — «bỏ khai» KHÔNG nằm trong OAPI-51 nữa. PO (ở làn portal-be) chốt đóng
OAPI-51 với app.dat_updated_at() vẫn khai là bắt buộc (executeAllowed = true, đúng với hôm
nay), và tách việc bỏ khai thành nợ OAPI-89 (portal-be#21) — trả khi V7 của admin-be lên
trunk. ⇒ Sau khi OAPI-51 merge, hợp đồng đòi hàm đó EXECUTE được; thứ tự ba bước ở trên đọc là:
V7 merge (bất cứ lúc nào) → OAPI-89 merge (bỏ khai + fixture REVOKE cùng commit, sau V7 trên
main) — còn OAPI-51 merge trước cả hai vì nó khai bắt buộc, không khai bỏ.
⛔⛔ NỬA SAU — chạm quy trình TRIỂN KHAI, và nếp AD-14 hiện hành đẩy ĐÚNG VÀO CHIỀU HỎNG (làn
portal-be phát hiện 08/09/2026). V7 merge vô hại — không cổng nào đọc main của admin-be.
Nhưng V7 TRIỂN KHAI vào một môi trường trước khi bản portal-be mang OAPI-89 triển khai vào
đó ⇒ CSDL không còn EXECUTE, hợp đồng vẫn đòi ⇒ portal-be từ chối khởi động ở môi trường
ấy (ô «THIẾU»). Mà AD-14 bảo «admin-be di trú TRƯỚC» — làm đúng luật hiện hành là rơi thẳng
vào ô đỏ. Nửa này không suy ra được từ nửa đầu: người đọc «thu hồi là phá vỡ» vẫn có thể merge
đúng thứ tự rồi triển khai theo AD-14 như mọi lần, và hỏng.
| nửa đầu | nửa sau | |
|---|---|---|
| chạm | quy trình merge | quy trình triển khai |
| ai đọc | làn thi công | người vận hành · uat |
| đang ở đâu | design.md D10 của OAPI-54 (sắp archive) |
comment của OAPI-83, OAPI-89 |
⟨CẦN PO CHỐT — MỘT GÓI, không phải hai, nâng lên AD-14/AD-15: (1) merge: thu hồi một quyền đã
tồn tại là thay đổi phá vỡ với repo đang khai nó, y như cấp thêm — nối đuôi hai chiều; (2) triển
khai: thứ tự «admin-be trước» của AD-14 áp cho chiều THÊM schema; chiều THU HỒI quyền thì
ngược — bên mất quyền triển khai trước bên thu hồi. Hai nửa vào spine cùng một lượt;
vào lệch lượt thì nửa sau — đang sống trong comment của hai issue — sẽ mất.⟩
(Ghi lại cận dưới của lượt trước, vì lập luận vẫn dùng được:) làn portal-be nêu 08/09:
dù đáp án là gì thì 2.8 cũng chạm một mắt xích admin-be — vai portal_app hiện chỉ có quyền
trên ba bảng; phiên trong CSDL thì cần bảng mới + GRANT, phiên ngoài CSDL thì vẫn cần
thu hồi kiểm được mỗi yêu cầu, tức vẫn đi qua một câu GRANT mới. ⇒ Khác nhau ở kích thước,
không ở việc có hay không. Phạm vi tối thiểu của 1.7 là cấp quyền; tối đa là khai bảng + cấp
quyền.
⛔⛔ CẶP «admin-be KHAI + portal-be NỐI» NAY CÓ THỨ TỰ BẮT BUỘC, không còn song song.
OAPI-51 (portal-be) mở rộng cổng khởi động để từ chối khởi động khi vai có quyền trên bất kỳ
bảng hoặc hàm nào NGOÀI hợp đồng ghim trong mã — đo trên postgres:18 với fixture thật, bốn ca âm
đều bắt được, kể cả hàm lạ mà không ai GRANT gì (PostgreSQL cấp EXECUTE cho PUBLIC mặc
định). ⇒ Từ lúc OAPI-51 lên trunk, mỗi lượt di trú của admin-be cấp thêm bất cứ thứ gì cho
portal_app sẽ CHẶN KHỞI ĐỘNG portal-be cho tới khi hợp đồng ở repo họ khai nó. Đó là chủ
đích, nhưng nó đổi cách xếp lịch: hai nửa của cặp phải nối đuôi, và lượt admin-be đi trước
thì portal-be phải có lượt khai hợp đồng ngay sau — không để cách quãng.
- 1.8 bảng phiên bản văn bản pháp lý + vết đồng ý — 2.7 cấm ghi đè tại chỗ và đòi ghi ai
đồng ý PHIÊN BẢN NÀO, lúc nào; không story nào khai bảng giữ được nhiều phiên bản ấy.
⚠️ Ma trận quyền portal_app là một nửa của mỗi story khai bảng, không phải phần phụ — portal-be
có cổng khởi động đo quyền theo cột, thiếu GRANT đúng thì nó từ chối khởi động và triệu
chứng trông như lỗi của portal-be.
PO chốt 09/09/2026 — ba đáp án cho lượt explore của 2.8:
| Câu | Chốt | |
|---|---|---|
| 1 | NFR-003 không có số — bao lâu không hoạt động thì hết phiên |
15 phút (áp cả E-001/2.3) |
| 2 | FR-007 ghi vào đâu |
E-001/4.1 — story đã có, ⛔ không mở story mới; xem E-001 |
| 3 | đổi mật khẩu và đăng xuất, gói design chưa vẽ màn | làm back-end trước |
⚠️ 2.8 KHÔNG chờ E-001/4.1 — nên ô «Chặn bởi» ghi Đ: (chặn-ĐÓNG) chứ không phải M:.
2.8 dựng đường nối + bản hiện thực tối thiểu và chạy tiếp; nhưng nó sinh một nợ trỏ vào
4.1, và story chỉ tính là xong khi 4.1 archive.
⛔ Cái giá của bản tối thiểu, làn portal-be khai thẳng — giữ nguyên văn: bản tối thiểu ghi ra
nhật ký ứng dụng (file log xoay vòng, xoá được), thứ không thoả K2 — nhật ký chỉ ghi thêm,
không vai nào sửa hay xoá được. FR-007 thoả ở mức «có ghi»; K2 cho bốn sự kiện này CHƯA thoả
cho tới khi bản thật cắm vào bảng trong vùng audit. ⚠️ K2 là một trong bốn thứ
backlog-tuan-thu.md xếp vào loại không hoãn được — hoãn thì khoảng thời gian đã chạy không cứu
lại được. Nợ này vì thế có mốc trả cứng: trước khi có TPP thật kết nối.
⚠️ Nửa còn lại của NFR-003 — «xác thực lại để thao tác nhạy cảm» — CHƯA có đáp. Làn portal-be
đi tiếp bằng một giả định khai rõ: giai đoạn 1 không bắt xác thực lại, vì cổng bên thứ ba chưa có
thao tác nào rơi vào nhóm đó (cấp và xoay khoá thuộc E-005). ⛔ Ghi trong design.md như giả
định, không như quyết định đã duyệt.
Ràng buộc đã chốt sẵn, 2.8 không được quyết lại:
- Khoá tạm 3 lần / 15 phút cho cổng bên thứ ba — ⚠️ khác con số 5 lần của bề mặt quản trị, và
khác biệt đó là chủ đích: hai bề mặt không cùng mức phơi (AD-29 mục 0, gói design 05/09).
⛔ Ngưỡng là cấu hình, không phải hằng số rải trong mã.
- Quên mật khẩu dùng câu trung lập — ⛔ không tiết lộ một email đã tồn tại trong hệ thống hay
chưa; cùng lý do 2.3 cấm tiết lộ mã số thuế đã tồn tại: đó là kênh dò.
- Phiên có trạng thái, kiểm thu hồi mỗi yêu cầu (AD-19) — như bề mặt quản trị, không có ngoại lệ.
- ⛔ Tách hẳn khỏi đường xác thực nội bộ (AD-20): portal_app không chạm bảng người dùng nội bộ,
và ngược lại. Cùng ranh giới mà 2.1 đã dựng cho bảng tài khoản.
⚠️ E-001/5.9 (portal-fe) phụ thuộc story này — màn đăng nhập, khoá tạm, quên mật khẩu, đổi mật
khẩu đều cần nửa back-end ở đây. Ghi ra vì bảng E-001 không nói 5.9 chờ ai; nếu portal-fe
mở 5.9 trước khi 2.8 xong thì họ sẽ dựng giao diện cho một hợp đồng chưa tồn tại.
⚠️ 2.8 RẤT CÓ THỂ LÀ MỘT CẶP NỮA — đang đo, chưa kết luận (làn oapi-portal-be nêu 08/09/2026).
AD-19 đòi phiên có trạng thái, kiểm thu hồi mỗi yêu cầu, tức phải có nơi lưu phiên. Đo trên
admin-be 2d0909b: app.tpp_user có 9 cột, không cột nào giữ phiên; V1–V5 không migration
nào khai bảng phiên. ⇒ Nếu 2.8 cần bảng, nó là cặp admin-be khai + portal-be nối, đúng
khuôn 1.6, và mắt xích admin-be phải mở TRƯỚC. Làn portal-be đo kỹ rồi báo trước khi
viết; kết luận về tới thì bảng story bổ sung dòng tương ứng.
⛔ Đây là cách một cặp thiếu lộ ra trước khi chặn thay vì lúc đang thi công — ngược hẳn ca 1.6,
nơi làn phải dừng hẳn một story để chờ.
Bổ sung 08/09/2026 (PO duyệt) — E-004/1.6, mắt xích bảng story thiếu. Làn oapi-portal-be
phát hiện khi đo trước lúc mở change cho 2.2: story ấy giao cho portal-be ghi SUBMISSION,
nhưng portal-be không được có dòng di trú (AD-14, cưỡng chế bằng PomInvariantsTest), và
không story nào khai bảng đó — grep SUBMISSION trên epics.md ra ba dòng, cả ba nằm trong
chính 2.2. Spine đã trả lời sẵn câu «ai khai»: «Bảng portal-be ghi (ví dụ SUBMISSION) vẫn do
admin-be khai» (AD-14). Tức đây không phải xung đột kiến trúc, mà là bảng story thiếu một
dòng so với chính spine. Số thứ tự của các story từ 2.2 trở đi dời xuống một bậc.
⚠️ Ma trận quyền là nửa dễ quên nhất của 1.6. portal-be nay có cổng khởi động đo quyền
theo cột (OAPI-36/OAPI-37, đã lên trunk): bảng mới mà thiếu GRANT đúng cho portal_app thì
portal-be từ chối khởi động — đúng thiết kế, nhưng nó sẽ trông như lỗi của portal-be.
⚠️ Tiền lệ E-004/2.1 đã để lại đúng lỗ này và không ai thấy. OAPI-14 mở ở admin-be với
trailer trỏ story E-004/2.1, nên trong bảng story 2.1 chỉ có một dòng, service portal-be —
phần việc admin-be khai bảng vô hình với mọi phép đo, kể cả tool/epic-status.sh. Nó archive
rồi nên không lộ; lần này lộ vì việc chưa làm. ⇒ Từ nay việc khai bảng cho một service khác là
một STORY, không phải một issue kèm theo.
Bổ sung 11/09/2026 tối (PO chốt từng mục — UU-TIEN-GD1 §G). Ba việc chạm epic này:
- P4 — tách
2.4. Nửa đăng ký chỉ cần2.1(đã archive) +5.6(đã archive) + khung văn bản2.6; nửa nộp hồ sơ cần2.2màportal-bechưa bắt đầu. Gộp thì B1 chờ cả chuỗi nộp hồ sơ.2.9mangM:2.4vì tuyến hồ sơ đi từ tài khoản đã kích hoạt. - P2 — A3 chỉ xem. PO chọn mức thấp nhất trong bốn phương án (xem · xem + khoá/mở · đúng gói xem
- gán vai · hoãn). Lý do: «gán vai trong tổ chức» chưa có nguồn ở tầng nào (~~vai TPP thuộc
E-005, chưa story khai bảng~~ — đính chính 12/09:
E-005không có story vai TPP; nợ trỏ vềOAPI-205, openapi-platform#23) nên lấy đúng gói là lặp lại ca ba cột củaE-001/5.11; khoá/mở kéoE-001/4.1và3.1vào đường găng A3. Hai phần bỏ là nợ có tên, ⛔ không phải cắt phạm vi. - P6 — BÁC (ghi ở
E-005): đơn khai ứng dụng chỉ sau khi tổ chức được duyệt ⇒ chuỗi A5 (1.1→1.2→1.3→2.5) nằm trên đường găng của B3.
Các nhóm việc (feature)¶
Hệ Admin
- Phía ngân hàng — 13 story · 🟡 còn 20 mốc
- Cổng bên thứ ba — 12 story · 🟡 còn 19 mốc
Hệ Portal
- Cổng bên thứ ba — 12 story · 🟡 còn 19 mốc