Skip to content

Nền tảng dùng chung của cụm tool SAPP (/works/sapp/tools) - FS Overview ​

File tổng quan + index của FS. Mỗi User Story là 1 file riêng trong cùng thư mục (US-P0X-<slug>.md). Các phần dùng chung (tổng quan, flow tổng, related features, NFR, Open Questions, References) đặt tập trung tại đây — file US chỉ tham chiếu ID, không lặp lại. As-built: tài liệu mô tả hành vi code tại commit e77c47a, dựng từ inventory đã qua Gate R1 — chưa gọi thử API, chưa chạy màn nào. FS của 6 nhóm sub-tool link vào đây cho: quyền truy cập (NFR-P-01), khoá tool (NFR-P-02), môi trường (NFR-P-03, §1.6) và các dịch vụ dùng chung (US-P05…P09).

FieldValue
Doc IDFS-SAPP-PLATFORM
ModeB – As-built
As-built tại commite77c47a
Last Updated2026-09-30
AuthorAI (lane ba/)
ReviewersBA
StatusDRAFT
Figma ProjectN/A — as-built, không có Figma
Related BRD../../brd/brd-as-built-v0.1-20260930.md
Related Impact MatrixN/A — Mode B

1. Tổng quan dự án &ZeroWidthSpace;

Workspace /works/sapp/tools là một khung web chung chứa 13 công cụ (sub-tool sapp.001–sapp.013) phục vụ các ticket SAPP (HubSpot, eContract 20603, 24395, 23954, 26878, 26297). FS này mô tả phần dùng chung cho mọi sub-tool: điều hướng và sidebar, cơ chế bật/tắt/ẩn/khoá tool, quản trị trạng thái tool và cấu hình hệ ngoài theo môi trường, cùng 5 dịch vụ BE mà sub-tool gọi (tra vết log SAP và quét doanh thu, dựng callback SAP, thêm option property HubSpot dev, passthrough SAPP Ops, chạy SQL danh mục trên DB Ops). Người dùng: người dùng tool (chưa xác định — OQ-P-13) và Admin CMS.

1.1 Bối cảnh &ZeroWidthSpace;

  • Không có tường đăng nhập ở /works/*; hệ thống không phân biệt người dùng tool (inventory §6). Việc giới hạn tool dựa trên trạng thái tool do Admin đặt và mã bí mật (NFR-P-02).
  • Các tool gọi nhiều hệ ngoài (HubSpot, SAPP Ops REST + DB, SAP service) trên nhiều môi trường; BE giữ credential để trình duyệt không bao giờ cầm (NFR-P-04).
  • Lịch sử: cổng chặn từng "mở khi không chắc" (fail-open), đã đổi sang fail-closed (shared/integration/README.md dòng #39FE; fe/src/ui/components/works/shared/tool-gate.tsx:78-83).

1.2 Mục tiêu &ZeroWidthSpace;

[Assumption] — BA chưa trả lời G-05 / OQ-P-18. Giả định làm việc: cho đội làm ticket SAPP một chỗ duy nhất để dựng dữ liệu test và tra cứu trên các hệ SAPP theo đúng môi trường, không cần cầm credential hệ ngoài. Không có KPI được xác nhận.

1.3 In Scope &ZeroWidthSpace;

Phạm vi đã truy vết (inventory platform §1):

  • Điều hướng /works/sapp → /works/sapp/tools, chọn tool đích, shell (sidebar, breadcrumb, giao diện, ghi nhớ) — US-P01.
  • Cổng chặn tool (tải trạng thái, fail-closed, ẩn / tắt / khoá, mở khoá bằng mã) — US-P02.
  • Quản trị tool / nhóm tool (web /cms/tools, app mobile, API /tools, /tool-groups) — US-P03.
  • Cấu hình hệ ngoài theo môi trường (env_systems) — US-P04.
  • Dịch vụ dùng chung: SAP log trace + scan-runs + manual-scan (US-P05), sign-callback (US-P06), thêm option property HubSpot dev (US-P07), SAPP Ops passthrough + auto-login + ping (US-P08), Ops SQL runner + panel SQL dùng chung (US-P09).
  • Quyền truy cập của toàn bộ controller be/apps/api/src/sapp/*.controller.ts (NFR-P-01).

1.4 Out Of Scope &ZeroWidthSpace;

  • Hành vi riêng của 13 sub-tool → 6 FS nhóm (§3).
  • Logic nghiệp vụ trong dịch vụ SAPP chung của từng ticket (econtract, 23954, 24395, 26878, 26297) — chỉ ghi phần credential dùng chung.
  • Nội dung danh mục SQL SAPP_26878_SQL_STATEMENTS, s26297.* — chỉ ghi cơ chế chạy.
  • Bên trong hệ ngoài (HubSpot, SAP service, SAPP Ops, LMS); workspace /works/naucode-kahrs (dùng chung cổng chặn nhưng ngoài dự án).
  • Chi tiết UI app mobile quản trị tool (chỉ ghi điểm vào + field chính).

1.5 Roles And Permissions &ZeroWidthSpace;

Role IDRole NameDescriptionPermission Summary
R1Người dùng toolBất kỳ ai mở /works/sapp/* — Assumption (OQ về G-01): đối tượng cụ thể chưa xác nhận (OQ-P-13)Không đăng nhập. Thấy/mở tool theo trạng thái tool (NFR-P-02); gọi được mọi API /api/v1/sapp/* (NFR-P-01)
R2Admin CMSTài khoản CMS đăng nhập — FactQuyền tools:*, tool_groups:*, env_systems:* (read/create/update/delete) — be/apps/api/src/tool/tool.controller.ts:35-137, be/apps/api/src/tool-group/tool-group.controller.ts:32-116, be/apps/api/src/env-system/env-system.controller.ts:32-100

1.6 Môi trường &ZeroWidthSpace;

Môi trường được chọn bằng đoạn cố định trong đường dẫn API (/api/v1/sapp/{prod|staging|dev}/…), mỗi môi trường là một route riêng; route không khai báo cho môi trường nào thì môi trường đó không gọi được (be/apps/api/src/sapp/sapp-ops.controller.ts:61-66, be/libs/constants/src/lib/hubspot/hubspot.enum.ts:1-5).

Hệ ngoàiprodstagingdevBằng chứng
HubSpot CRMPortal prod (SAPP_PROD_HUBSPOT_*)⚠️ = portal prod — cố ý theo comment code: "Staging is a client-facing environment selection only — it deliberately reuses the prod portal credentials (there is no dedicated staging portal)". Mọi thao tác HubSpot "staging" chạm dữ liệu prod (OQ-P-03)Portal dev (SAPP_DEV_HUBSPOT_*)be/libs/constants/src/lib/hubspot/hubspot.constants.ts:14-31
SAPP Ops REST (tự đăng nhập)SAPP_OPS_*_PRODSAPP_OPS_*_STAGINGSAPP_OPS_*_DEVbe/libs/constants/src/lib/sapp/sapp-ops.constants.ts:17-36
SAPP Ops REST (bộ cũ)Một bộ SAPP_BASE_API_URL + SAPP_API_TOKEN cho mọi môi trường — môi trường thật phụ thuộc giá trị đang cấu hình (G-09)be/libs/constants/src/lib/sapp/sapp.constants.ts:22-25
Postgres SAPP Ops (SQL runner)Không có key, không có routeSAPP_OPS_DB_*_STAGINGSAPP_OPS_DB_*_DEVbe/libs/constants/src/lib/sapp/sapp-26878-sql.constants.ts:272-307
SAP serviceSAPP_SAP_*_PRODSAPP_SAP_*_STAGING (không dùng lại prod)SAPP_SAP_*_DEVbe/libs/modules/src/lib/sapp/sap-log.common.service.ts:79-113
Redis mind_keep (token Ops)sapp:ops:token:prodsapp:ops:token:stagingsapp:ops:token:devbe/libs/constants/src/lib/sapp/sapp-ops.constants.ts:66-67

Chi tiết key: US-P04.

1.7 Chốt chặn prod có thật &ZeroWidthSpace;

Chỉ những chỗ dưới đây thực sự không thể ghi prod ở tầng BE (Fact). Mọi chỗ khác — gồm Ops passthrough (US-P08) và HubSpot qua "staging" — đều có đường ghi prod (OQ-P-02, OQ-P-03).

Chốt chặnCơ chế chặnUSBằng chứng
Ops SQL runnerKhông có bộ key DB prod và không có route prod; chỉ chạy câu trong danh mục, không nhận SQL thôUS-P09be/libs/constants/src/lib/sapp/sapp-26878-sql.constants.ts:272-307, be/apps/api/src/sapp/sapp-ops.controller.ts:2404-2442, be/libs/modules/src/lib/sapp/sapp-ops-sql.common.service.ts:62-73
Quét doanh thu thủ công (manual-scan)Không có route prod và dịch vụ từ chối prod (13050)US-P05be/apps/api/src/sapp/sapp.controller.ts:3991-4015, be/libs/modules/src/lib/sapp/sap-log.common.service.ts:228-236
Dựng callback SAP (sign-callback)Không có route prod và dịch vụ từ chối prod (13050)US-P06be/apps/api/src/sapp/sapp.controller.ts:4017-4047, be/libs/modules/src/lib/sapp/sap-log.common.service.ts:290-296
Thêm option property HubSpotChỉ có route dev (môi trường cố định dev trong code)US-P07be/apps/api/src/sapp/sapp.controller.ts:821-846, :1101
(FS nhóm) Tool 26297Không có route prodFS 26297inventory platform X-5

2. Luồng tổng quan của dự án &ZeroWidthSpace;

text
[Admin CMS] ── US-P04 cấu hình env_systems (URL/credential theo môi trường)
          └── US-P03 bật/tắt, ẩn/hiện, khoá tool + nhóm

[Người dùng tool]
  /works/sapp ──→ US-P01 chọn tool đích / sidebar
                    ↓ mở tool
                  US-P02 cổng chặn (fail-closed → tắt / ẩn / khoá → mở khoá)
                    ↓ tool mở
                  Sub-tool (FS nhóm) ──gọi──→ dịch vụ dùng chung:
                      ├─ US-P05 SAP log / đợt quét / quét thủ công ──→ SAP service
                      ├─ US-P06 dựng callback SAP đã ký ────────────→ SAP service
                      ├─ US-P07 thêm option property ──────────────→ HubSpot dev
                      ├─ US-P08 Ops passthrough (auto-login) ───────→ SAPP Ops REST
                      └─ US-P09 SQL danh mục ───────────────────────→ Postgres SAPP Ops (dev/staging)
  ⚠️ Mọi API /api/v1/sapp/* gọi được trực tiếp, không qua cổng chặn (NFR-P-01)

3. Các tính năng liên quan &ZeroWidthSpace;

MãTính năng liên quanLink tài liệuLoại liên quanMục bị ảnh hưởng ở feature kiaMục ảnh hưởng ở feature hiện tạiMô tả ảnh hưởng
REL-01FS HubSpot (sapp.001–004)00-overviewBe AffectedUS-H01…H06US-P01, US-P02, US-P04, NFR-P-01, NFR-P-03Chạy trong shell + cổng chặn; token HubSpot theo môi trường; staging = portal prod
REL-02FS 20603 eContract (sapp.005, 012, 013)00-overviewBe AffectedUS-E01…E06US-P01, US-P02, US-P04, NFR-P-01Shell + cổng chặn; key DB econtract prod trong env_systems
REL-03FS 24395 (sapp.006, 007)00-overviewBe AffectedUS-I01…I06US-P08 BR-12, NFR-P-03Bulk product dùng bộ xác thực Ops cũ; tab "Staging" ghi HubSpot prod
REL-04FS 23954 (sapp.008, 009)00-overviewBe AffectedUS-T01…T05US-P01, US-P02, NFR-P-01, NFR-P-03Shell + cổng chặn; HubSpot theo môi trường
REL-05FS 26878 (sapp.010)00-overviewBe AffectedUS-D02, US-D03, US-D17, US-D18US-P05, US-P06, US-P07, US-P08, US-P09Sub-tool duy nhất dùng SAP log / quét / callback / option / passthrough
REL-06FS 26297 (sapp.011)00-overviewBe AffectedUS-S01, US-S02US-P08 (auto-login), US-P09 (panel SQL)Dùng chung đăng nhập Ops và panel/SQL runner
REL-07Workspace /works/naucode-kahrs— (ngoài dự án)Be AffectedCổng chặn của workspace đóUS-P02Dùng chung component cổng chặn
REL-08SAP service (hệ ngoài)shared/api-docs/sapp.md §SAP log traceAffects—US-P05, US-P06Cron quét tuần, bộ ký, webhook nằm ở SAP service; công tắc SAP_REVENUE_RECOGNITION_ENABLED
REL-09SAPP Ops REST API + DB (hệ ngoài)shared/api-docs/sapp.md §SAPP Ops passthrough / §SQL runnerAffects—US-P08, US-P09Rule nghiệp vụ Ops do Ops quyết; lỗi Ops chuyển nguyên câu
REL-10HubSpot CRM API (hệ ngoài)shared/api-docs/sapp.md §add optionAffects—US-P07, NFR-P-03HubSpot thay cả mảng option; option theo từng loại đối tượng

4. User Story Index &ZeroWidthSpace;

US IDTên User StoryFileRolePriorityStatus
US-P01Mở workspace SAPP, duyệt sidebar và mở một toolUS-P01-hub-mo-tool.mdR1N/A — as-builtDraft
US-P02Truy cập tool đang bật / ẩn / khoá (mở khoá bằng mã bí mật)US-P02-khoa-tool.mdR1N/A — as-builtDraft
US-P03Quản trị trạng thái tool và nhóm toolUS-P03-quan-tri-trang-thai-tool.mdR2N/A — as-builtDraft
US-P04Cấu hình kết nối hệ ngoài theo môi trường (env_systems)US-P04-cau-hinh-env-systems.mdR2N/A — as-builtDraft
US-P05Tra vết log SAP và theo dõi / kích hoạt đợt quét doanh thuUS-P05-sap-log-va-quet-doanh-thu.mdR1 (qua 26878)N/A — as-builtDraft
US-P06Đóng vai SAP: dựng callback đã kýUS-P06-callback-sap.mdR1 (qua 26878)N/A — as-builtDraft
US-P07Thêm option vào property danh sách của HubSpot devUS-P07-option-property-hubspot-dev.mdR1 (qua 26878)N/A — as-builtDraft
US-P08Đọc / ghi SAPP Ops qua passthrough (auto-login, kiểm tra kết nối)US-P08-ops-passthrough.mdR1 (qua 26878; auto-login cả 26297)N/A — as-builtDraft
US-P09Chạy câu SQL đã lập danh mục trên DB OpsUS-P09-ops-sql-runner.mdR1 (qua 26878, 26297)N/A — as-builtDraft

Status Draft = as-built chờ Gate R2.

Truy vết hành động inventory → US: A-01, A-03…A-07, A-09 → P01 · A-02, A-08 → P02 · A-10, A-11 → P03 · A-12 → P04 · A-13…A-15 → P05 · A-16 → P06 · A-17 → P07 · A-18, A-19, A-21 → P08 · A-20 → P09 (đủ 21/21).

5. Non-functional Requirements &ZeroWidthSpace;

IDRequirementApplies To (US/màn/API)Acceptance Criteria
NFR-P-01Toàn bộ API /api/v1/sapp/* (259 route) là @Public() — không cần đăng nhập, không permission, không system API key, kể cả route ghi prod. Fact (hiện trạng tại e77c47a), ⚠️ Observed — cố ý hay bug: OQ-P-01. Đếm decorator: sapp.controller.ts 128 · sapp-ops.controller.ts 103 · sapp-26297.controller.ts 28. Interceptor xác thực toàn cục bỏ qua khi có cờ public; guard system API key có sẵn nhưng chỉ dùng ở app-version / erd-version / resource. Bằng chứng: be/apps/api/src/sapp/sapp.controller.ts:157-174, be/apps/api/src/sapp/sapp-ops.controller.ts:73, :635, be/apps/api/src/sapp/sapp-26297.controller.ts:43, :79, be/apps/api/src/interceptors/grpc-auth.interceptor.ts:28-35, be/apps/api/src/app/app.module.ts:97, be/apps/api/src/guards/system-api-key.guard.ts:10-25. Tài liệu API nói khác (DR-P-02)Mọi route SAPP, mọi FS nhóm (US-P05…P09 và toàn bộ route của sub-tool)Gọi bất kỳ route /api/v1/sapp/* (kể cả prod/sapp-ops/users POST) không kèm token / API key → không bị từ chối vì xác thực (hành vi hiện tại). FS nhóm link mục này thay vì mô tả lại quyền
NFR-P-02Khoá / tắt / ẩn tool chỉ chặn ở giao diện (FE); cổng chặn fail-closed; trạng thái mở khoá nằm trong sessionStorage. (a) FE đóng tool khi không chắc: không có trong danh sách public, chưa có dòng DB, hoặc đọc trạng thái lỗi. (b) Không API /sapp/* nào kiểm trạng thái tool hay mã bí mật — comment BE tự nhận "UX gate, not an authorization boundary". (c) Mở khoá lưu mk:tool-unlocked:<code> trong sessionStorage theo phiên, FE không gửi bằng chứng lên API. (d) Route kiểm mã public, không giới hạn tần suất. (b)(c)(d) là ⚠️ Observed (OQ-P-04, OQ-P-05). Bằng chứng: fe/src/ui/components/works/shared/tool-availability.ts:9-28, fe/src/ui/components/works/shared/tool-gate.tsx:12, :109-113, :130-156, :197-200, be/apps/api/src/tool/tool-public.controller.ts:74-97; Grep ToolService|verifySecret trong be/apps/api/src/sapp, be/libs/modules/src/lib/sapp = 0US-P01, US-P02, US-P03; mọi sub-tool(a) Xoá dòng tools của một mã → tool hiện "Tool chưa mở". (b) Tắt tool rồi gọi thẳng API của nó → vẫn chạy. (c) Đóng tab → phải nhập lại mã
NFR-P-03Môi trường chọn bằng đoạn cố định trong route, không có tham số môi trường tự do; staging HubSpot = portal prod (bảng §1.6). Bằng chứng: be/apps/api/src/sapp/sapp-ops.controller.ts:61-66, be/libs/constants/src/lib/hubspot/hubspot.constants.ts:19-26Mọi dịch vụ theo môi trường; FS HubSpot, 24395, 23954, 26878Gọi staging/hubspot/... → dùng token SAPP_PROD_HUBSPOT_ACCESS_TOKEN; môi trường không có route → 404
NFR-P-04Credential hệ ngoài chỉ nằm ở BE, không tới trình duyệt (Ops username/password + token, SAP HMAC secret, DB Ops, token HubSpot); BE đọc từ env_systems lúc gọi. ⚠️ Observed: giá trị lưu dạng rõ trong DB, và secretValue tool trả lại qua API admin (OQ-P-12). Bằng chứng: be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:39-134, be/libs/modules/src/lib/sapp/sap-log.common.service.ts:56-68, :286-315, be/libs/database/src/lib/entities/env/env-system.entity.ts:10-11US-P04…P09Không response nào của US-P05…P09 chứa password / secret / token Ops (ping chỉ trả { ok: true })
NFR-P-05Timeout và giới hạn: danh sách trạng thái tool 10 s (tối đa 1000 tool); đăng nhập Ops 30 s, lời gọi Ops 10 phút; SAP service 30 s; SAP log limit 1–200 mỗi bảng; SQL 15 s/câu, SELECT ≤ 200 dòng. Bằng chứng: fe/src/ui/components/works/shared/use-tools-state.ts:51-52, be/libs/constants/src/lib/sapp/sapp-ops.constants.ts:38-41, be/libs/constants/src/lib/sapp/sapp.constants.ts:38, be/libs/constants/src/lib/sapp/sap-log.constants.ts:42-77, be/libs/constants/src/lib/sapp/sapp-26878-sql.constants.ts:309-313US-P02, P05, P08, P09Vượt giới hạn → lỗi tương ứng (13041, 13057, timeout)
NFR-P-06Không có thông báo, job hay audit trail phía mind_keep cho các dịch vụ dùng chung: không mail / push / MQTT / Discord / cron; chỉ log lỗi phía server. Cron quét tuần nằm ở SAP service. Bằng chứng: Grep mqtt|mailService|discord|telegram|@Cron trong be/apps/api/src/sapp, be/libs/modules/src/lib/sapp = 0; Grep sapp trong be/apps/schedule/src = 0US-P03…P09Không có bản ghi ai đã chạy thao tác ghi nào (kể cả prod)
NFR-P-07Ghi nhớ trên trình duyệt, xuống cấp an toàn: mk:works:sapp:last-tool, …:sidebar-collapsed, …:theme-dark, …:nav-groups-closed (localStorage); đọc/ghi lỗi → dùng mặc định, không báo lỗi. Bằng chứng: fe/src/ui/components/works/shared/last-tool.ts:10, fe/src/ui/pages/works/sapp/tools/shell.tsx:51-53, fe/src/ui/components/works/shared/use-persisted-flag.ts:15-46US-P01Chặn storage trình duyệt → workspace vẫn dùng được với mặc định
NFR-P-08Token Ops giữ trong Redis theo môi trường, một lượt đăng nhập mỗi môi trường khi có yêu cầu đồng thời (trong một tiến trình); 401 → đăng nhập lại + thử lại 1 lần. Bằng chứng: be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:43-49, :87-181US-P08 (và FS 26297)5 yêu cầu đồng thời khi chưa có token → 1 lượt đăng nhập

6. Open Questions &ZeroWidthSpace;

Owner mặc định: BA (ý đồ nghiệp vụ) · BE lead (hành vi code). Due: trước Gate R2. Mọi OQ đang Open.

IDQuestionOwnerDue DateStatusBlocks (US)
OQ-P-01259 route /api/v1/sapp/* đều @Public(), kể cả route ghi prod (NFR-P-01) — cố ý hay bug? Ai được phép dùng? (inventory R-18, Q-01; G-02; DR-P-02)BA + BE leadTrước Gate R2OpenToàn bộ US-P01…P09 + mọi FS nhóm
OQ-P-02Ops passthrough mở đủ thao tác ghi trên prod (tạo user/lớp/lịch/đơn/giao dịch, xoá/huỷ lịch, chuyển học viên, xác nhận giao dịch, resync SAP), không chốt chặn prod ở tầng dùng chung — cố ý hay bug? (inventory R-22; G-03)BA + BE leadTrước Gate R2OpenUS-P08, FS 26878
OQ-P-03Chọn "staging" HubSpot thực chất dùng portal prod — code ghi là cố ý; người dùng tool có biết không, và thao tác ghi "staging" của sub-tool có được phép chạm dữ liệu prod? Cố ý (được chấp nhận) hay bug? (inventory R-20, Q-02; G-04; DR-P-01)BATrước Gate R2OpenUS-P04, US-P07; FS HubSpot, 24395, 23954, 26878
OQ-P-04Khoá/tắt tool chỉ chặn ở giao diện; mở khoá chỉ ở sessionStorage, FE không gửi bằng chứng lên API — mức bảo vệ này cố ý hay bug/rủi ro? (inventory R-14, R-15, Q-05)BATrước Gate R2OpenUS-P02
OQ-P-05Route kiểm mã bí mật public, không giới hạn tần suất (khoá "năm của ngày" chỉ vài trăm giá trị) — cố ý hay bug? (inventory R-16)BE leadTrước Gate R2OpenUS-P02
OQ-P-06Tool đang ẩn vẫn đọc được trạng thái và kiểm mã qua route theo mã — cố ý hay bug? (inventory R-13, Q-06; DR-P-07)BE leadTrước Gate R2OpenUS-P02, US-P03
OQ-P-07sortBy của danh sách tool public là chuỗi tự do ghép thẳng vào câu sắp xếp — cố ý hay bug? (inventory R-45, Q-07)BE leadTrước Gate R2OpenUS-P02
OQ-P-08Token Ops còn hạn < 30 s vẫn được giữ 30 phút (có thể giữ token đã chết, được cứu bởi nhánh 401) — cố ý hay bug? (inventory R-26, Q-08; DR-P-04)BE leadTrước Gate R2OpenUS-P08
OQ-P-09Route dựng callback SAP ký sẵn trên dev/staging là public — ai cũng giả được callback SAP hợp lệ — cố ý hay bug? (inventory R-37, Q-10)BA + BE leadTrước Gate R2OpenUS-P06
OQ-P-10SQL runner trả nguyên thông báo lỗi Postgres (tên cột, ràng buộc) qua route public — cố ý (để tester sửa) hay bug? (inventory R-42, Q-11)BE leadTrước Gate R2OpenUS-P09
OQ-P-11Component khoá cũ (năm cố định 2003, kiểm ở trình duyệt) không tool nào dùng — di sản cần xoá hay còn kế hoạch dùng? Cố ý giữ hay bug (code chết)? (inventory R-46, Q-12)FE leadTrước Gate R2OpenUS-P02
OQ-P-12Secret hệ ngoài và giá trị khoá tool lưu dạng rõ; API admin trả lại giá trị khoá — cố ý (được chấp nhận) hay bug? (inventory R-47, Q-13)BA + BE leadTrước Gate R2OpenUS-P03, US-P04
OQ-P-13Ai là người dùng /works/sapp (owner / QA SAPP / Ops SAPP / BA…)? Hệ thống không phân biệt vai trò (inventory Q-04; G-01)BATrước Gate R2OpenRole R1 ở US-P01, P02, P05…P09
OQ-P-14Trên DB prod hiện tool nào đang tắt / ẩn / khoá, loại khoá gì? Seed mặc định "không khoá" (inventory Q-03; G-09)BATrước Gate R2OpenUS-P02, US-P03
OQ-P-15Hai cơ chế xác thực Ops cùng tồn tại (bộ cũ SAPP_API_TOKEN xoay tay vs tự đăng nhập). Ai xoay token cũ, có kế hoạch bỏ không? (inventory R-30, Q-09)BA + BE leadTrước Gate R2OpenUS-P04, US-P08; FS 24395
OQ-P-16Đã xác nhận mọi mã sapp.001–sapp.013 có dòng trong tools, dưới nhóm bật + hiện, trên prod chưa (việc #39FE/#41BE)? Thiếu dòng = tool đóng (inventory Q-14)BE leadTrước Gate R2OpenUS-P01, US-P03
OQ-P-17Tên chuẩn của tool là tên trong mã/DB hay nhãn sidebar (vd sapp.010 "SAPP 26878: Create deal instance" vs "Test data theo luồng")? (inventory Q-15)BATrước Gate R2OpenUS-P01, US-P03
OQ-P-18Mục đích nghiệp vụ của việc nhóm tool theo số ticket, và ai quyết thêm/bỏ tool khỏi workspace? (inventory Q-16; G-05)BATrước Gate R2OpenUS-P03; §1.2
OQ-P-19(Phát hiện khi viết FS R3, chưa có ở inventory) Mã lỗi 13058 dùng cho cả "Failed to update the SAPP Ops class schedule" và "No LMS API URL is configured…" (26297); 13059 cho cả xoá lịch Ops và "A learner LMS token is required" — cố ý hay bug? Bằng chứng: be/libs/constants/src/lib/error-codes/error-codes.constants.ts:812-820, :834-845BE leadTrước Gate R2OpenUS-P08; FS 26297
OQ-P-20Dựng callback chạy được (201) nhưng webhook staging từ chối body bộ ký dựng (400) — FS mô tả là "đã triển khai, chưa chạy được"? (G-08; shared/external/sapp/sapp-26878/2026-09-22-mind-sign-callback-lech-dto.md:15-18)BATrước Gate R2OpenUS-P06; FS 26878 US-D17
OQ-P-21(Phát hiện khi viết FS R3) Hộp xác nhận xoá biến môi trường nói "Services that read it fall back to their defaults", nhưng dịch vụ SAPP không có mặc định mà báo lỗi thiếu cấu hình — cố ý hay bug (câu chữ sai)? Bằng chứng: fe/src/ui/pages/cms/(env-systems)/page.tsx:189 vs be/libs/modules/src/lib/sapp/sap-log.common.service.ts:99-106FE leadTrước Gate R2OpenUS-P04
OQ-P-22(Phát hiện khi viết FS R3) Mã lỗi dùng lẫn: sign-callback lỗi trả 13052 "Failed to trigger the manual revenue-recognition sweep"; manual-scan nhận mọi 403 từ SAP service đều trả 13050 "…cannot run against production" — cố ý hay bug? Bằng chứng: be/libs/modules/src/lib/sapp/sap-log.common.service.ts:249-254, :318-328BE leadTrước Gate R2OpenUS-P05, US-P06

6b. Drift: tài liệu ↔ code (Mode B/C — Mode A ghi N/A) &ZeroWidthSpace;

Không tự chọn bên đúng — mỗi dòng cần owner quyết. shared/api-docs/ chỉ lane be/ được sửa.

IDTài liệu nóiCode đang làm (bằng chứng file:dòng)Ảnh hưởngOwner quyết
DR-P-01shared/api-docs/sapp.md:12 §Overview: HubSpot "across two portals (prod / dev)" (inventory DR-01)Ba môi trường; staging dùng lại credential portal prod — be/libs/constants/src/lib/hubspot/hubspot.constants.ts:14-31Người đọc doc không biết "staging" ghi prod (NFR-P-03)BE lane
DR-P-02shared/api-docs/sapp.md:14 §Overview: "the three routes below are currently marked @Public() … (temporary)" (inventory DR-02)Toàn bộ 259 route SAPP @Public(), kể cả route ghi prod — be/apps/api/src/sapp/sapp.controller.ts:174, be/apps/api/src/sapp/sapp-ops.controller.ts:635, be/apps/api/src/sapp/sapp-26297.controller.ts:79Đánh giá rủi ro sai (NFR-P-01, OQ-P-01)BE lane
DR-P-03shared/api-docs/sapp.md:1128-1131 §SAPP Ops authentication: token dò theo access_token/accessToken/token/id_token/idToken/jwt, "chưa kiểm với API thật" (inventory DR-03)Danh sách có thêm act, comment code nói đây là trường đang dùng thật (data.tokens.act) — be/libs/constants/src/lib/sapp/sapp-ops.constants.ts:43-63Doc thiếu trường thực dùngBE lane
DR-P-04shared/api-docs/sapp.md:1096-1098: cache token tới exp − 60 s; 30 phút nếu token opaque; tối đa 24 h (inventory DR-04)Thêm nhánh: hạn còn < 30 s → vẫn cache 30 phút — be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:195-200OQ-P-08BE lane
DR-P-05shared/api-docs/sapp.md:2474 §SAPP Ops passthrough; be/.agents/maps/modules/tool.md §3: "Twenty read/write operations" / "~20 thao tác Ops" (inventory DR-05)33 thao tác mỗi môi trường (35 ở dev/staging tính 2 route SQL) — be/apps/api/src/sapp/sapp-ops.controller.ts:634-2442Doc thiếu 13 thao tácBE lane
DR-P-06shared/api-docs/sapp.md:2241 §SAP log trace: "Two read-only endpoints" (inventory DR-06)Section còn manual-scan (kích hoạt quét) và sign-callback (dựng callback ký) — không chỉ đọc — be/apps/api/src/sapp/sapp.controller.ts:3991-4047Doc bỏ sót route có tác độngBE lane
DR-P-07shared/api-docs/tools.md:24-25 §Overview: route /tools/public/* "only expose effectively visible tools" (inventory DR-07)GET /tools/public/code/:code và verify trả/kiểm cả tool đang ẩn — be/libs/modules/src/lib/tool/service.ts:125-134, :214-221OQ-P-06BE lane
DR-P-08shared/api-docs/tools.md:29-32; comment fe/src/data/models/tool.interface.ts:8-12: "The public by-code route (GET /tools/code/:code)" (inventory DR-08)GET /tools/code/:code yêu cầu quyền tools:read; route public là /tools/public/code/:code — be/apps/api/src/tool/tool.controller.ts:50-53Dễ gọi nhầm route cần đăng nhập (lịch sử #39FE)BE lane (doc) · FE lane (comment)
DR-P-09shared/api-docs/tools.md:11 §Overview: registry ở mind_keep_cms_ui/src/data/constants/tool-codes.ts (inventory DR-09)Đường dẫn thực tế fe/src/data/constants/tool-codes.ts — fe/src/data/constants/tool-codes.ts:1-57Đường dẫn cũ (trước monorepo)BE lane
DR-P-10shared/api-docs/tool-groups.md:30-35: nhóm sapp có sapp.* (10) tool (inventory DR-10)Registry có 13 mã sapp.*; migration seed thêm sapp.011–013 — fe/src/data/constants/tool-codes.ts:32-44, be/libs/database/migrations/1786300000000-seed-tool-sapp-26297.ts:14-19Số tool saiBE lane
DR-P-11(Phát hiện khi viết FS R3) Câu chữ panel SQL fe/src/ui/components/works/sapp/sapp-26878-step-sql.tsx:442: "route chạy SQL là route DUY NHẤT của tool này cần JWT"Route `devstaging/sapp-ops/sql/statusrunlà@Public()như mọi route SAPP —be/apps/api/src/sapp/sapp-ops.controller.ts:2405, :2417, :2431, :2443`

7. References &ZeroWidthSpace;

  • BRD: ../../brd/brd-as-built-v0.1-20260930.md
  • Impact Matrix: N/A — Mode B
  • Solution Decision: ../../../project-decisions.md (Gate R1 Approved, R2 confirm 60 US)
  • Figma: N/A — as-built, không có Figma
  • API Spec: shared/api-docs/sapp.md, shared/api-docs/tools.md, shared/api-docs/tool-groups.md, shared/api-docs/env-system.md (xem Drift §6b)
  • Code đã đọc: chi tiết ở working/ai-drafts/feature-inventory-platform-20260930.md §9. Đọc thêm khi viết FS (R3): fe/src/ui/pages/cms/(tools)/page.tsx, fe/src/ui/pages/cms/(env-systems)/page.tsx, fe/src/ui/components/cms/(tools)/create-form.tsx, update-form.tsx, fe/src/ui/components/cms/(env-systems)/create-form.tsx, app/lib/screens/tool_form_screen.dart, tool_group_form_screen.dart, fe/src/ui/components/works/sapp/sapp-26878-step-sql.tsx, sapp-26878-step-scan.tsx, sapp-26878-manual-scan.tsx, sapp-26878-step-option.tsx, sapp-26878-flows.ts (5985-6030), fe/src/data/services/sapp/sap-log.service.ts, sapp-ops.service.ts, be/libs/constants/src/lib/error-codes/error-codes.constants.ts, be/libs/interface/src/lib/dto/sapp/sap-log.dto.ts, be/libs/interface/src/lib/dto/hubspot/hubspot-property.dto.ts
  • Nguồn mục đích ("So that"): shared/external/sapp/sapp-26878/0005-sapp-26878-phase2-us04-tra-loi-ops-mind.md, shared/external/sapp/sapp-26878/2026-09-22-mind-sign-callback-lech-dto.md
  • Meeting Notes / Q&A: working/ai-drafts/gate-r1-summary-20260930.md (G-01…G-10 chưa có trả lời)

Template Conformance Check &ZeroWidthSpace;

Quét mục lục từng file US so với ba/_workflow/templates/fs/User-Story.md (Metadata · 1 US Statement · 2 Dependencies/DoR · 3 Business Rules có cột "Đã cover bởi (AC)" + "Nguồn code" · 4 Design: mỗi màn có UI States / Fields / Filter-Search-Sort / Actions / AC (G/W/T) / Negative AC · 5 Cross-feature AC). Section không áp dụng giữ heading + N/A — <lý do>.

US fileSection thiếuTrạng thái
US-P01-hub-mo-tool.md(đủ) — M1 Fields/Filter N/A có lý do✅
US-P02-khoa-tool.md(đủ) — Filter N/A (không phải List)✅
US-P03-quan-tri-trang-thai-tool.md(đủ) — M3 UI States / Filter N/A (ngoài phạm vi truy vết chi tiết)✅
US-P04-cau-hinh-env-systems.md(đủ)✅
US-P05-sap-log-va-quet-doanh-thu.md(đủ) — M3 Fields N/A (chỉ có nút)✅
US-P06-callback-sap.md(đủ) — UI States N/A (dịch vụ, UI thuộc FS 26878)✅
US-P07-option-property-hubspot-dev.md(đủ) — UI States N/A (dịch vụ, UI thuộc FS 26878)✅
US-P08-ops-passthrough.md(đủ) — UI States N/A (dịch vụ); M2 Fields N/A✅
US-P09-ops-sql-runner.md(đủ)✅