Skip to content

Feature Inventory — Nền tảng dùng chung của cụm tool SAPP (/works/sapp/tools) ​

Kiểm kê tính năng đã triển khai, dựng từ code. Đầu vào cho FS as-built (Mode B). Mọi dòng có bằng chứng file:dòng; không có bằng chứng → §8 Câu hỏi.

Công thức truy vết: ba/system-profile.md §3. Mọi đường dẫn tính từ root repo mind_keep/. AI draft — chưa qua Gate R1. Không gọi API chạy thật; mọi hành vi suy từ đọc source tại commit dưới. Phạm vi là phần dùng chung — FS của từng nhóm sub-tool (HubSpot, 20603, 24395, 23954, 26878, 26297) tham chiếu ID ở đây (E-/A-/R-) thay vì mô tả lại.

FieldValue
Projectba/projects/2026-SAPP-Works-tools
ModeB – As-built
Ngày đọc code2026-09-30
Commite77c47a
Điểm vào BA cung cấpTrang hub /works/sapp + /works/sapp/tools, registry TOOL_CODES họ sapp.*, cơ chế trạng thái/khoá tool, env_systems, auto-login SAPP Ops, SAP log trace, Ops passthrough, Ops SQL runner
Thành phần chạm tớiFE (CMS web) · BE (apps/api) · APP (chỉ màn quản trị tool, không có màn SAPP) · hệ ngoài: HubSpot CRM API, SAPP Ops REST API, SAP service, Postgres của SAPP Ops, Redis
StatusDraft

1. Phạm vi đã truy vết ​

  • Trong phạm vi:
    • Điều hướng: /works/sapp (chuyển hướng), /works/sapp/tools (chọn tool đích), khung (shell) chung cho mọi route tool: sidebar theo nhóm, breadcrumb, theme, ghi nhớ tool dùng gần nhất.
    • Registry tool FE (registry.ts — nhóm/slug/nhãn) và TOOL_CODES (mã vĩnh viễn sapp.NNN).
    • Trạng thái runtime của tool do BE giữ theo code: bật/tắt, ẩn/hiện, khoá bí mật, nhóm tool; API public /tools/public* + API quản trị /tools, /tool-groups; màn quản trị /cms/tools (web) và màn quản trị tool trên app mobile (chỉ ghi nhận điểm vào).
    • Cổng chặn tool phía FE (ToolGate) và component SecretGate (không được dùng).
    • Cấu hình môi trường: literal prod|staging|dev trong route, bảng env_systems, các bộ key theo hệ ngoài.
    • Dịch vụ BE dùng chung: auto-login SAPP Ops (SappAuthCommonService), SAP log trace (SapLogCommonService), SAPP Ops passthrough (SappOpsCommonService + SappOpsController), Ops SQL runner (SappOpsSqlCommonService), route thêm option property HubSpot dev, wiring module.
    • Component UI dùng chung: SapLogTrace/SapLogTraceSummary, Select, Checkbox, DatePicker, HubspotPropertyField, shared.tsx, utils.ts (chỉ liệt kê, không đi sâu).
    • Quyền truy cập của toàn bộ controller be/apps/api/src/sapp/*.controller.ts.
  • Ngoài phạm vi (dừng truy vết tại đây):
    • Hành vi riêng của 13 sub-tool (sapp.001–013) — do 6 inventory nhóm khác đảm nhận.
    • Logic nghiệp vụ trong SappCommonService (econtract, 23954, 24395, 26878) và Sapp26297CommonService — chỉ ghi phần credential dùng chung.
    • Nội dung catalogue SQL (SAPP_26878_SQL_STATEMENTS, SAPP_26297_SQL_STATEMENTS) — chỉ ghi cơ chế chạy.
    • Hệ ngoài (HubSpot, SAP, SAPP Ops, LMS) bên trong; workspace /works/naucode-kahrs (dùng chung ToolGate nhưng ngoài dự án).
    • Chi tiết UI admin /cms/tools và màn app mobile (chỉ ghi điểm vào).

2. Điểm vào (Entry points) ​

IDLoạiTên / đường dẫn người dùng thấyBằng chứng
E-01Màn web/works/sapp — không có màn riêng, chuyển thẳng sang /works/sapp/toolsfe/app/works/sapp/page.tsx:17-19
E-02Màn web/works/sapp/tools — màn "chọn tool đích" (đang mở tool… / không kiểm tra được / chưa có tool nào được mở)fe/app/works/sapp/tools/page.tsx:10-12, fe/src/ui/pages/works/sapp/tools/index-redirect.tsx:35-91
E-03Màn web (khung chung)Shell "SAPP Tools · HubSpot · Ops · SAP" bọc mọi route /works/sapp/tools/*: sidebar, breadcrumb Works › SAPP › <tool>, nút "Về Works", công tắc giao diện tốife/app/works/sapp/tools/layout.tsx:25-27, fe/src/ui/pages/works/sapp/tools/shell.tsx:72-442
E-04Màn web13 route tool /works/sapp/tools/<slug> xếp trong 6 nhóm (xem §4 bảng registry)fe/src/ui/pages/works/sapp/tools/registry.ts:39-111, fe/src/ui/pages/works/sapp/tools/registry.ts:124-126
E-05Màn web (admin)/cms/tools — "Manage tool availability, visibility, and secret locks"fe/app/cms/(tools)/tools/page.tsx:7-18
E-06Màn mobile (admin)Màn danh sách/sửa tool và nhóm tool (gọi /api/v1/tools, /api/v1/tool-groups)app/lib/screens/tool_admin_list_screen.dart:17, app/lib/services/tool_service.dart:19, app/lib/services/tool_group_service.dart:20
E-07APIGET /api/v1/tools/public — danh sách tool hiệu lực đang hiện (không cần đăng nhập)be/apps/api/src/tool/tool-public.controller.ts:29-45
E-08APIGET /api/v1/tools/public/code/:code — trạng thái hiệu lực của một toolbe/apps/api/src/tool/tool-public.controller.ts:47-64
E-09APIPOST /api/v1/tools/public/code/:code/verify — kiểm tra mã bí mậtbe/apps/api/src/tool/tool-public.controller.ts:79-97
E-10API (admin)GET/POST /api/v1/tools, GET /api/v1/tools/code/:code, POST /api/v1/tools/code/:code/verify, GET/PATCH/DELETE /api/v1/tools/:idbe/apps/api/src/tool/tool.controller.ts:35-137
E-11API (admin)/api/v1/tool-groups (list, code/:code, :id, CRUD)be/apps/api/src/tool-group/tool-group.controller.ts:25-116
E-12API (admin)/api/v1/env-systems CRUD — nơi nhập URL/credential hệ ngoàibe/apps/api/src/env-system/env-system.controller.ts:25-100
E-13APIPOST /api/v1/sapp/{prod|dev|staging}/sap-log/tracebe/apps/api/src/sapp/sapp.controller.ts:3841, :3856, :3871
E-14APIPOST /api/v1/sapp/{prod|dev|staging}/sap-log/scan-runsbe/apps/api/src/sapp/sapp.controller.ts:3886, :3901, :3916
E-15APIGET /api/v1/sapp/{dev|staging}/sap-log/manual-scan (không có bản prod)be/apps/api/src/sapp/sapp.controller.ts:3991, :4003
E-16APIPOST /api/v1/sapp/{dev|staging}/sap-log/sign-callback (không có bản prod)be/apps/api/src/sapp/sapp.controller.ts:4017-4047
E-17APIPOST /api/v1/sapp/dev/hubspot/{deals|contacts}/properties/{property}/options (chỉ dev)be/apps/api/src/sapp/sapp.controller.ts:821-846, :1101
E-18APISAPP Ops passthrough /api/v1/sapp/{prod|staging|dev}/sapp-ops/… — 33 thao tác × 3 môi trường (dev/staging thêm 2 route SQL)be/apps/api/src/sapp/sapp-ops.controller.ts:73, :634-2386
E-19APIGET /api/v1/sapp/{prod|staging|dev}/sapp-ops/pingbe/apps/api/src/sapp/sapp-ops.controller.ts:634, :645, :656
E-20APIGET /api/v1/sapp/{dev|staging}/sapp-ops/sql/statusbe/apps/api/src/sapp/sapp-ops.controller.ts:2404, :2430
E-21APIPOST /api/v1/sapp/{dev|staging}/sapp-ops/sql/runbe/apps/api/src/sapp/sapp-ops.controller.ts:2416, :2442
E-22Dịch vụ nội bộ (không có route)Auto-login SAPP Ops — cố ý không mở endpoint loginbe/apps/api/src/sapp/sapp-ops.controller.ts:68-70, be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:39-134

3. Hành động người dùng / hệ thống &ZeroWidthSpace;

"Viewer" = bất kỳ ai mở /works/* (không có tường đăng nhập — xem R-18, Q-04).

IDAi (role)Làm gìĐiểm vàoKết quả quan sát đượcBằng chứng
A-01ViewerMở /works/sappE-01Bị chuyển thẳng sang /works/sapp/toolsfe/app/works/sapp/page.tsx:17-19
A-02Hệ thống (shell)Tải trạng thái mọi tool một lần khi vào workspaceE-03 → E-07Gọi GET /tools/public?page=1&limit=1000, timeout 10 s; kết quả chia sẻ cho mọi route con, không gọi lạife/src/ui/components/works/shared/use-tools-state.ts:40-77, fe/src/ui/pages/works/sapp/tools/shell.tsx:74, :426
A-03Hệ thốngChọn tool đích khi vào /works/sapp/toolsE-02Mở tool dùng gần nhất nếu còn mở; nếu không, tool mở đầu tiên theo thứ tự registry; không có → "Chưa có tool nào được mở"; lỗi đọc → "Không kiểm tra được trạng thái tool". Điều hướng kiểu thay thế (Back không quay về trang chọn)fe/src/ui/pages/works/sapp/tools/index-redirect.tsx:41-90, fe/src/ui/components/works/shared/tool-availability.ts:41-54
A-04ViewerXem sidebar danh sách toolE-03Tool xếp theo 6 nhóm; tool không có trong danh sách public bị ẩn; tool đóng hiện nhãn "Off" và không bấm được; nhóm không còn tool nào bị ẩn cả tiêu đề; trong lúc tải: tool hiện mờ, không bấm đượcfe/src/ui/pages/works/sapp/tools/shell.tsx:254-395
A-05ViewerThu/mở một nhóm trong sidebarE-03Lựa chọn được nhớ trên trình duyệt; nhóm chứa tool đang mở không thu đượcfe/src/ui/pages/works/sapp/tools/shell.tsx:272-305, :506-550
A-06ViewerThu sidebar thành thanh icon; bật/tắt giao diện tốiE-03Cả hai lựa chọn được nhớ; trên điện thoại sidebar thành ngăn kéo phủ mànfe/src/ui/pages/works/sapp/tools/shell.tsx:81-105, :151-168, :210-224
A-07ViewerMở một tool (qua sidebar hoặc link chia sẻ)E-04Cổng chặn hiển thị theo thứ tự: đang tải → không kiểm tra được → "Tool chưa mở" (không có/ẩn) → "Tool đã bị tắt" → "Tool đang khoá" → nội dung toolfe/src/ui/components/works/shared/tool-gate.tsx:88-267
A-08ViewerNhập mã bí mật (ô chữ hoặc chọn ngày) để mở khoá toolE-04 → E-09Đúng → mở khoá cho phiên trình duyệt hiện tại (theo code); sai → "Mã bí mật không đúng"; lỗi khác → thông báo theo mã lỗife/src/ui/components/works/shared/tool-gate.tsx:184-264, fe/src/data/services/cms/(tools)/verify-secret.service.ts:24-37
A-09Hệ thốngGhi nhớ tool vừa mởE-03Lưu slug vào trình duyệt để lần sau A-03 quay lại đúng toolfe/src/ui/pages/works/sapp/tools/shell.tsx:122-126, fe/src/ui/components/works/shared/last-tool.ts:10-26
A-10Admin (quyền tools:*)Tạo/sửa/xoá tool: bật/tắt, ẩn/hiện, loại + giá trị khoá, gán/gỡ nhómE-05, E-06 → E-10Mã trùng bị từ chối; nhóm không tồn tại bị từ chối; groupId rỗng = gỡ nhómbe/libs/modules/src/lib/tool/service.ts:34-63, :154-193
A-11Admin (quyền tool_groups:*)Quản lý nhóm tool (ô dù bật/tắt, ẩn/hiện cho mọi tool con)E-05, E-06 → E-11Xoá nhóm → tool con thành không nhóm (không bị xoá)be/apps/api/src/tool-group/tool-group.controller.ts:32-116, be/libs/database/src/lib/entities/tool/tool.entity.ts:37-39
A-12Admin (quyền env_systems:*)Nhập URL/credential các hệ ngoài theo môi trườngE-12Mọi dịch vụ SAPP đọc giá trị lúc gọi, không cần khởi động lạibe/apps/api/src/env-system/env-system.controller.ts:32-100, be/libs/modules/src/lib/env-system/env-system-map.common.service.ts:38-55
A-13Sub-tool (hiện chỉ 26878)Tra vết log SAP theo deal / event / entry / class / transactionE-13BE ký HMAC rồi trả nguyên dữ liệu các bảng log; FE hiện bảng + dòng thời gian có chấm màu trạng tháibe/libs/modules/src/lib/sapp/sap-log.common.service.ts:165-188, fe/src/ui/components/works/sapp/sap-log-trace.tsx:301-452, fe/src/ui/components/works/sapp/sapp-26878-tool.tsx:37
A-14Sub-toolXem tiến độ các đợt quét ghi nhận doanh thuE-14Trả danh sách lượt quétbe/libs/modules/src/lib/sapp/sap-log.common.service.ts:191-213, fe/src/ui/components/works/sapp/sap-log-trace.tsx:517
A-15Sub-toolKích hoạt quét doanh thu ngay (không chờ cron tuần)E-15triggered=false = tính năng đang tắt (không phải lỗi); prod bị từ chốibe/libs/modules/src/lib/sapp/sap-log.common.service.ts:227-271
A-16Sub-toolDựng callback SAP đã ký để đóng vai SAPE-16Trả lệnh/callback dùng được 1 lần; credential không rời BE; prod bị từ chốibe/apps/api/src/sapp/sapp.controller.ts:3948-3989, be/libs/modules/src/lib/sapp/sap-log.common.service.ts:286-331
A-17Sub-toolThêm một option vào property dạng danh sách của HubSpot devE-17Giữ nguyên các option cũ, thêm option mới cuối danh sách; option đã có → added=falsebe/libs/modules/src/lib/hubspot/common.service.ts:715-800
A-18Sub-toolĐọc/ghi dữ liệu SAPP Ops (danh mục, môn, cơ sở, khoá, lớp, lịch, giáo viên, học viên, user, sản phẩm, đơn, giao dịch, resync SAP) theo môi trườngE-18BE đăng nhập Ops thay người dùng, trả dữ liệu Ops; lỗi Ops kèm thông điệp gốcbe/libs/modules/src/lib/sapp/sapp-ops.common.service.ts:65-126, :286-887
A-19Sub-toolKiểm tra kết nối OpsE-19Trả { ok: true } — không bao giờ trả tokenbe/libs/modules/src/lib/sapp/sapp-ops.common.service.ts:280-296
A-20Sub-tool (26878, 26297)Hỏi môi trường có chạy SQL được không; chạy một câu SQL đã lập danh mục theo id + tham sốE-20, E-21configured=false là câu trả lời bình thường; chạy xong trả câu lệnh (không kèm giá trị), số dòng, thời gianbe/apps/api/src/sapp/sapp-ops.controller.ts:82-108, be/libs/modules/src/lib/sapp/sapp-ops-sql.common.service.ts:106-195
A-21Hệ thốngTự đăng nhập SAPP Ops và giữ tokenE-22Token lưu Redis theo môi trường; gặp 401 → xoá token, đăng nhập lại, thử lại đúng 1 lầnbe/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:87-181

4. Dữ liệu &ZeroWidthSpace;

Registry tool FE (nhóm hiển thị ↔ slug ↔ code)

Nhóm sidebar (registry.ts)Slug → TOOL_CODES.codeBằng chứng
SAPP Common Hubspot Toolshs-clone-prod-to-dev→sapp.001 · hs-snapshot-property→sapp.002 · hs-get-property→sapp.003 · hs-pipeline→sapp.004fe/src/ui/pages/works/sapp/tools/registry.ts:43-51, fe/src/data/constants/tool-codes.ts:32-35
SAPP 20603 - EContractecontract→sapp.005 · econtract-timeline→sapp.012 · econtract-error-stats→sapp.013registry.ts:53-67, tool-codes.ts:36, :43-44
SAPP 24395 - Tự động ghi nhận doanh thusapp-24395→sapp.006 · sapp-24395-products→sapp.007registry.ts:70-84, tool-codes.ts:37-38
SAPP 23954 - Ticket Ownersapp-23954→sapp.008 · sapp-23954-snapshot→sapp.009registry.ts:86-96, tool-codes.ts:39-40
SAPP 26878 - Doanh thu thực hiện (Ops → HubSpot → SAP)sapp-26878→sapp.010registry.ts:98-103, tool-codes.ts:41
SAPP 26297 - Chuyển nhượng học viênsapp-26297→sapp.011registry.ts:105-110, tool-codes.ts:42

(Đường dẫn rút gọn registry.ts = fe/src/ui/pages/works/sapp/tools/registry.ts; tool-codes.ts = fe/src/data/constants/tool-codes.ts.)

Bảng / kho dữ liệu

Entity / bảngFieldTypeBắt buộcMặc định / enumBằng chứng
toolscodevarchar(100)Có, unique<family>.NNN, vd sapp.001be/libs/database/src/lib/entities/tool/tool.entity.ts:13-17
toolsnamevarchar(255)Có—tool.entity.ts:19-20
toolsisEnabledbooleanCótruetool.entity.ts:22-23
toolsisVisiblebooleanCótruetool.entity.ts:25-26
toolssecretTypevarchar(50)Cónone · fixed_value · year_of_datetool.entity.ts:28-29, fe/src/data/enums/tool.enum.ts:1-5
toolssecretValuetextKhôngnull; lưu dạng rõtool.entity.ts:31-32
toolsgroupIduuid → tool_groupsKhôngxoá nhóm → SET NULLtool.entity.ts:34-39
tool_groupscode / name / isEnabled / isVisible / descriptionvarchar / varchar / bool / bool / textcode, name bắt buộccode unique; enabled/visible truebe/libs/database/src/lib/entities/tool/tool-group.entity.ts:5-24
tools (seed)13 dòng sapp.001–sapp.013——Seed chỉ có code + name (+ nhóm sapp cho 011–013) → mặc định bật, hiện, không khoábe/libs/database/migrations/1783700000000-create-tools.ts:6-15, :33, be/libs/database/migrations/1786300000000-seed-tool-sapp-26297.ts:14-19, 1786400000000-seed-tool-sapp-20603-econtract-timeline.ts:20
Shape public tool (PublicToolDto)code, name, isEnabled, isVisible, secretType, requiresSecret, group——*giá trị hiệu lực = nhóm AND tool; không có id, secretValuebe/libs/modules/src/lib/tool/service.ts:105-123
env_systemskey (unique) / valuevarchar(255) / textkey bắt buộcMật khẩu/secret lưu dạng rõ trong valuebe/libs/database/src/lib/entities/env/env-system.entity.ts:4-12
env_systems — HubSpotSAPP_{PROD,DEV}_HUBSPOT_{API_URL,ACCESS_TOKEN,CLIENT_SERCET}—Chỉ ACCESS_TOKEN được đọcstaging dùng lại bộ PRODbe/libs/constants/src/lib/env-system/env-system.constants.ts:6-11, be/libs/constants/src/lib/hubspot/hubspot.constants.ts:10-32, be/libs/modules/src/lib/hubspot/common.service.ts:47-58
env_systems — Ops (auto-login)SAPP_OPS_{API_URL,USERNAME,PASSWORD}_{PROD,STAGING,DEV}—Đủ 3 key/env—env-system.constants.ts:19-27, be/libs/constants/src/lib/sapp/sapp-ops.constants.ts:17-36
env_systems — Ops (cũ, một bộ)SAPP_BASE_API_URL, SAPP_API_TOKEN—Cả 2Token xoay tay, không theo envenv-system.constants.ts:17-18, be/libs/constants/src/lib/sapp/sapp.constants.ts:22-25, be/libs/modules/src/lib/sapp/common.service.ts:278-302
env_systems — Ops DB (SQL runner)SAPP_OPS_DB_{HOST,PORT,NAME,USERNAME,PASSWORD}_{DEV,STAGING}—Trừ PORTPORT mặc định 5432; không có bộ PRODenv-system.constants.ts:28-37, be/libs/constants/src/lib/sapp/sapp-26878-sql.constants.ts:281-307
env_systems — SAP serviceSAPP_SAP_{API_URL,CLIENT_ID,HMAC_SECRET}_{PROD,STAGING,DEV}—Đủ 3 key/env (manual-scan chỉ cần URL)staging không dùng lại prodenv-system.constants.ts:47-55, be/libs/modules/src/lib/sapp/sap-log.common.service.ts:79-113, :340-355
Redissapp:ops:token:{prod|staging|dev} → { token, expiresAt }JSON—TTL xem R-26be/libs/constants/src/lib/sapp/sapp-ops.constants.ts:66-67, be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:27-31, :171-176
localStorage (trình duyệt)mk:works:sapp:last-tool · mk:works:sapp:sidebar-collapsed · mk:works:sapp:theme-dark · mk:works:sapp:nav-groups-closedstring / "1"/"0" / JSON mảng id nhóm—Không đọc được storage → dùng mặc định, không lỗife/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-46
sessionStoragemk:tool-unlocked:<code> = "1"string—Mất khi đóng tab/phiênfe/src/ui/components/works/shared/tool-gate.tsx:12, :111, :199

5. Rule & validation tìm thấy &ZeroWidthSpace;

IDRule (ngôn ngữ nghiệp vụ)LoạiÁp dụng ởBằng chứngNghi là bug?
R-01Mỗi tool có mã vĩnh viễn dạng sapp.NNN (3 chữ số, tăng dần), gắn với slug route; không bao giờ dùng lại hay đánh số lại. FE chỉ giữ mã + tên, mọi trạng thái do BE quyếtđiều kiệnA-02, A-10fe/src/data/constants/tool-codes.ts:4-20, fe/CLAUDE.md:3-22Không
R-02Mã tool là duy nhất; tạo/sửa trùng mã bị từ chối; gán vào nhóm không tồn tại bị từ chốivalidationA-10be/libs/modules/src/lib/tool/service.ts:35-44, :162-174Không
R-03Trạng thái hiệu lực của tool = trạng thái nhóm và trạng thái tool; tool không thuộc nhóm coi như nhóm bật/hiệncông thứcA-02, A-07be/libs/modules/src/lib/tool/service.ts:105-113Không
R-04Danh sách public chỉ gồm tool đang hiện và thuộc nhóm đang hiện (hoặc không nhóm)điều kiệnA-02be/libs/modules/src/lib/tool/common.service.ts:113-119Không
R-05"Đóng khi không chắc" (fail-closed): tool không có trong danh sách public = đóng; tool có trong registry nhưng chưa có dòng trong bảng tools cũng đóngđiều kiệnA-04, A-07fe/src/ui/components/works/shared/tool-availability.ts:9-28, fe/src/ui/components/works/shared/tool-gate.tsx:144-156Không
R-06Không đọc được danh sách trạng thái (mạng, timeout, 4xx/5xx) → mọi tool đóng và hiển thị lý do; không chọn tool đíchđiều kiệnA-02, A-03, A-07fe/src/ui/components/works/shared/use-tools-state.ts:41-76, fe/src/ui/components/works/shared/tool-gate.tsx:130-142, fe/src/ui/pages/works/sapp/tools/index-redirect.tsx:39-47Không
R-07Tool chỉ được mở khi hiện và bậtđiều kiệnA-04, A-07fe/src/ui/components/works/shared/tool-availability.ts:26-28Không
R-08Chọn tool đích: ưu tiên tool dùng gần nhất nếu còn mở, rồi tool mở đầu tiên theo thứ tự registry; không bao giờ đưa vào tool đóngđiều kiệnA-03fe/src/ui/components/works/shared/tool-availability.ts:41-54Không
R-09Sidebar: tool đóng không phải link, gắn nhãn "Off"; nhóm không còn tool hiện bị ẩn; nhóm chứa tool đang mở không thu đượcđiều kiệnA-04, A-05fe/src/ui/pages/works/sapp/tools/shell.tsx:267-277, :290, :334-372Không
R-10Sidebar tự thu thành icon khi màn rộng < 1280 px (nếu viewer chưa chọn); giao diện theo cài đặt hệ điều hành nếu chưa chọngiới hạnA-06fe/src/ui/pages/works/sapp/tools/shell.tsx:59, :94-105Không
R-11Ba loại khoá: không khoá (luôn hợp lệ) · giá trị cố định (khớp chính xác) · năm của ngày (năm ngày nhập = giá trị khoá); ngày không đọc được → lỗi TOOL_SECRET_INVALIDvalidationA-08be/libs/modules/src/lib/tool/service.ts:235-260Không
R-12Kiểm tra mã bị từ chối khi nhóm tắt (GROUP_DISABLED) hoặc tool tắt (TOOL_DISABLED) — kiểm trước khi so mãtrạng tháiA-08be/libs/modules/src/lib/tool/service.ts:222-233Không
R-13Kiểm tra mã và đọc trạng thái theo mã không xét tool có đang ẩn không — tool ẩn vẫn đọc được trạng thái và vẫn kiểm tra mã đượcđiều kiệnE-08, E-09be/libs/modules/src/lib/tool/service.ts:125-134, :214-221, be/libs/modules/src/lib/tool/common.service.ts:161-167⚠️ Observed
R-14Mở khoá chỉ lưu ở trình duyệt (sessionStorage) theo mã tool, hết khi đóng phiên; FE không gửi bằng chứng mở khoá lên APItrạng tháiA-08fe/src/ui/components/works/shared/tool-gate.tsx:109-113, :197-200⚠️ Observed
R-15Khoá/tắt tool chỉ chặn ở giao diện: không API /sapp/* nào kiểm tra trạng thái tool hay mã bí mật (comment BE tự nhận "UX gate, not an authorization boundary")điều kiệnA-07, A-13…A-20be/apps/api/src/tool/tool-public.controller.ts:74-77; Grep ToolService|ToolCommonService|verifySecret trong be/apps/api/src/sapp, be/libs/modules/src/lib/sapp = 0 kết quả⚠️ Observed
R-16Kiểm tra mã bí mật public không giới hạn tần suất, không cần đăng nhập (khoá "năm của ngày" chỉ có vài trăm giá trị khả dĩ)giới hạnA-08be/apps/api/src/tool/tool-public.controller.ts:79-97; Grep Throttl trong be/apps/api/src, be/libs = 0 kết quả; shared/api-docs/tools.md:192-194⚠️ Observed
R-17Thông báo lỗi mở khoá theo mã: tool tắt / nhóm tắt / tool không còn / sai định dạng / lỗi cấu hình máy chủ (mã lỗi dạng đăng nhập) / mặc địnhvalidationA-08fe/src/ui/components/works/shared/tool-gate.tsx:49-67Không
R-18Mọi route /api/v1/sapp/* (259 route: 128 + 103 + 28) đánh dấu @Public() — không cần đăng nhập, không permission, không system API key; interceptor toàn cục bỏ qua xác thực khi có cờ publicquyềnE-13…E-21 và mọi route sub-toolbe/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⚠️ Observed
R-19Môi trường được chọn bằng đoạn cố định trong đường dẫn (prod/staging/dev), mỗi môi trường là một route riêng — không có tham số môi trường tự do; route không khai báo cho env nào thì env đó không gọi đượcđiều kiệnE-13…E-21be/apps/api/src/sapp/sapp-ops.controller.ts:61-66, be/libs/constants/src/lib/hubspot/hubspot.enum.ts:1-5Không
R-20Chọn môi trường staging cho HubSpot thực chất dùng token portal prod (không có portal staging) — mọi thao tác HubSpot "staging" chạm dữ liệu prodđiều kiệnMọi sub-tool gọi HubSpot với stagingbe/libs/constants/src/lib/hubspot/hubspot.constants.ts:19-26⚠️ Observed
R-21Thêm option property HubSpot: chỉ portal dev; value bắt buộc (bỏ khoảng trắng), label mặc định = value; property phải là dạng danh sách; option đã có thì không thêm (trả added=false); gửi lại toàn bộ danh sách cũ + option mới ở cuốivalidationA-17be/apps/api/src/sapp/sapp.controller.ts:821-840, be/libs/modules/src/lib/hubspot/common.service.ts:722-789Không
R-22Ops passthrough mở đủ thao tác ghi trên prod (tạo môn/cơ sở/khoá/lớp/lịch/giáo viên/user/sản phẩm/đơn/giao dịch, sửa lớp/phòng/lịch, huỷ và xoá lịch, chuyển học viên, xác nhận giao dịch, resync SAP) — không kèm điều kiện chặn prod nào ở tầng dùng chungquyềnA-18be/apps/api/src/sapp/sapp-ops.controller.ts:739, :799, :958, :1063, :1156, :1261, :1366, :1417, :1477, :1497, :1591, :1651, :1667, :1861, :1912, :1963, :2074, :2179, :2230, :2290, :2350⚠️ Observed
R-23Ops passthrough không tự kiểm tra rule nghiệp vụ của Ops (ngày học tương lai, giá > 0, định dạng giờ…) — để Ops quyết; lỗi Ops trả về kèm câu thông báo gốc; Ops trả success=false với HTTP 200 cũng coi là lỗivalidationA-18be/libs/modules/src/lib/sapp/sapp-ops.common.service.ts:73-77, :94-126Không
R-24Số trang/kích thước trang không phải số nguyên dương thì bị bỏ qua (dùng mặc định) thay vì gửi sang OpsvalidationA-18be/apps/api/src/sapp/sapp-ops.controller.ts:48-59Không
R-25Auto-login Ops: URL + user + mật khẩu đọc theo môi trường từ env_systems; thiếu một trong ba → lỗi 13030 SAPP_OPS_AUTH_NOT_CONFIGUREDvalidationA-21be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:58-84Không
R-26Token Ops giữ tới (hạn JWT − 60 s); token không có hạn → 30 phút; tối đa 24 h; nếu hạn còn lại < 30 s thì vẫn giữ 30 phútcông thứcA-21be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:189-202, be/libs/constants/src/lib/sapp/sapp-ops.constants.ts:77-84⚠️ Observed
R-27Chỉ HTTP 401 mới kích hoạt đăng nhập lại + thử lại đúng 1 lần; 403 không thử lạiđiều kiệnA-21be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:121-134, be/libs/constants/src/lib/sapp/sapp-ops.constants.ts:86-92Không
R-28Nhiều yêu cầu cùng lúc chỉ tạo một lượt đăng nhập mỗi môi trường (trong một tiến trình)giới hạnA-21be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:43-49, :98-105Không
R-29Đăng nhập Ops lỗi → 13031; đăng nhập được nhưng không thấy token → 13032; token được dò theo danh sách trường ưu tiên, có act, cố ý loại rft (refresh token)validationA-21be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:154-169, be/libs/constants/src/lib/sapp/sapp-ops.constants.ts:43-63Không
R-30Tồn tại song song hai cách xác thực Ops: bộ cũ SAPP_BASE_API_URL + SAPP_API_TOKEN (một bộ cho mọi môi trường, phải xoay tay khi hết hạn) và bộ auto-login theo môi trườngtrạng tháiSub-tool dùng SappCommonService (vd 24395 products) vs Ops passthroughbe/libs/modules/src/lib/sapp/common.service.ts:278-302, be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:33-38Không
R-31SAP log: thiếu URL / client id / HMAC secret của môi trường → lỗi 13037 và log nêu tên key thiếuvalidationA-13, A-14, A-16be/libs/modules/src/lib/sapp/sap-log.common.service.ts:79-113Không
R-32Tra vết SAP cần ít nhất một khoá lọc trong 5 khoá (deal_id, event_id, entry_id, class_code, transaction_id); nhiều khoá thì AND; tra theo deal_id trả cả dòng phase 1 (hoá đơn, thanh toán)validationA-13be/libs/modules/src/lib/sapp/sap-log.common.service.ts:132-144, :156-164, be/libs/constants/src/lib/sapp/sap-log.constants.ts:79-89Không
R-33limit 1–200, áp cho từng bảng; FE mặc định 50, offset 0giới hạnA-13, A-14be/libs/modules/src/lib/sapp/sap-log.common.service.ts:146-154, be/libs/constants/src/lib/sapp/sap-log.constants.ts:72-77, fe/src/ui/components/works/sapp/sap-log-trace.tsx:317-321Không
R-34Khoá lọc rỗng bị bỏ trước khi ký và gửi (chuỗi rỗng không coi là điều kiện lọc)validationA-13, A-14be/libs/modules/src/lib/sapp/sap-log.common.service.ts:357-369Không
R-35Kích hoạt quét thủ công và dựng callback ký sẵn bị từ chối trên prod (lỗi SAP_SCAN_NOT_ALLOWED_ON_PROD), và không có route prodđiều kiệnA-15, A-16be/libs/modules/src/lib/sapp/sap-log.common.service.ts:228-236, :290-296; route chỉ dev/staging be/apps/api/src/sapp/sapp.controller.ts:3991-4047Không
R-36Quét thủ công: triggered=false nghĩa là tính năng đang tắt (công tắc SAP_REVENUE_RECOGNITION_ENABLED), trả như kết quả bình thường; 403 và 429 có mã lỗi riêng; triggered=true chỉ là đã vào hàng đợitrạng tháiA-15be/libs/modules/src/lib/sapp/sap-log.common.service.ts:215-271Không
R-37Callback SAP ký sẵn: mặc định status=SUCCEEDED, role=POSITIVE; chỉ gửi trường tester nhập; kết quả dùng 1 lần trong ~300 s. Route public → bất kỳ ai gọi được cũng dựng được callback hợp lệ trên dev/stagingđiều kiệnA-16be/apps/api/src/sapp/sapp.controller.ts:3964-3983, :4017-4047, be/libs/constants/src/lib/sapp/sap-log.constants.ts:54-64⚠️ Observed
R-38SQL runner chỉ chạy câu lệnh có trong danh mục theo id; không nhận SQL do người gọi gửi; giá trị được bind qua drivervalidationA-20be/libs/modules/src/lib/sapp/sapp-ops-sql.common.service.ts:62-73, :116-122, :52-60Không
R-39SQL runner không thể chạy trên prod: không có bộ key prod và không có route prodđiều kiệnA-20be/libs/constants/src/lib/sapp/sapp-26878-sql.constants.ts:272-307, be/apps/api/src/sapp/sapp-ops.controller.ts:2404-2442Không
R-40SQL: tham số thiếu/rỗng → dừng (13056), không bind NULL; placeholder còn sót sau khi thay → lỗivalidationA-20be/libs/modules/src/lib/sapp/sapp-ops-sql.common.service.ts:132-163Không
R-41SQL: một mục nhiều câu chạy trong một transaction; timeout 15 s/câu; SELECT tối đa 200 dònggiới hạnA-20be/libs/modules/src/lib/sapp/sapp-ops-sql.common.service.ts:25-38, :165-174, be/libs/constants/src/lib/sapp/sapp-26878-sql.constants.ts:309-313Không
R-42SQL: lỗi DB trả nguyên thông điệp của Postgres (tên cột, ràng buộc) cho người gọi qua route publicđiều kiệnA-20be/libs/modules/src/lib/sapp/sapp-ops-sql.common.service.ts:181-193⚠️ Observed
R-43SQL: id câu lệnh trùng giữa các danh mục tool → dịch vụ từ chối khởi độngvalidationA-20be/libs/constants/src/lib/sapp/sapp-ops-sql.constants.ts:7-32Không
R-44FE phân loại trạng thái dòng log SAP theo từ khoá, ưu tiên: lỗi (FAIL, ERROR, REJECT, TIMEOUT, CANCEL, INVALID) → đang xử lý (NOT_SYNCED, PENDING, RETRY…) → thành công (SUCCESS, SYNCED, SENT…) → không rõcông thứcA-13fe/src/ui/components/works/sapp/sap-log-summary.tsx:160-200Không
R-45Danh sách public nhận trường sắp xếp (sortBy) dạng chuỗi tự do và ghép thẳng vào câu ORDER BYvalidationE-07be/libs/modules/src/lib/tool/common.service.ts:109, :128, be/libs/interface/src/lib/dto/base/request.dto.ts:19-23⚠️ Observed
R-46Component SecretGate (khoá bằng ngày, năm phải là 2003, kiểm tra hoàn toàn ở trình duyệt) có trong code nhưng không tool nào dùngđiều kiện—fe/src/ui/components/works/sapp/secret-gate.tsx:14-47, :73-74; Grep SecretGate trong fe/ chỉ ra chính file đó⚠️ Observed
R-47Mật khẩu/secret hệ ngoài (Ops, Ops DB, SAP HMAC, HubSpot token) và secretValue tool lưu dạng rõ; API admin trả lại secretValuetrạng tháiA-10, A-12be/libs/database/src/lib/entities/env/env-system.entity.ts:10-11, be/libs/database/src/lib/entities/tool/tool.entity.ts:31-32, be/libs/modules/src/lib/tool/common.service.ts:6-20⚠️ Observed
R-48Tool mới seed qua migration mặc định bật + hiện + không khoátrạng tháiA-10be/libs/database/migrations/1783700000000-create-tools.ts:33, :41, be/libs/database/migrations/1786300000000-seed-tool-sapp-26297.ts:14-19Không

Trạng thái & chuyển trạng thái của một tool khi viewer mở (FE, ToolGate):

text
[ĐANG TẢI] --(đọc danh sách lỗi)--> [KHÔNG KIỂM TRA ĐƯỢC]           (R-06)
[ĐANG TẢI] --(code không có trong danh sách / isVisible=false)--> [CHƯA MỞ]   (R-05)
[ĐANG TẢI] --(isEnabled=false)--> [ĐÃ BỊ TẮT]
[ĐANG TẢI] --(secretType ≠ none và phiên chưa mở khoá)--> [ĐANG KHOÁ]
[ĐANG KHOÁ] --(verify valid=true)--> [MỞ]  (nhớ trong sessionStorage đến hết phiên)
[ĐANG TẢI] --(visible & enabled & (none hoặc đã mở khoá))--> [MỞ]

Trạng thái token Ops mỗi môi trường (BE, SappAuthCommonService):

text
[CHƯA CÓ TOKEN] --(gọi lần đầu → login ok)--> [TOKEN TRONG REDIS]
[TOKEN TRONG REDIS] --(hết expiresAt)--> [CHƯA CÓ TOKEN]
[TOKEN TRONG REDIS] --(Ops trả 401)--> xoá token → login lại → thử lại 1 lần

6. Quyền, tích hợp, thông báo, job &ZeroWidthSpace;

LoạiChi tiếtBằng chứng
Quyền — workspace FE/works/sapp/* không có tường đăng nhập; FE chỉ đọc route public để quyết định hiện/ẩn/khoáfe/src/ui/components/works/shared/use-tools-state.ts:25-38, fe/src/data/models/tool.interface.ts:38-54
Quyền — tool public/tools/public, /tools/public/code/:code, /tools/public/code/:code/verify: @Public()be/apps/api/src/tool/tool-public.controller.ts:29-30, :47-48, :79-80
Quyền — tool admin/tools* yêu cầu đăng nhập + quyền tools (read/create/update/delete)be/apps/api/src/tool/tool.controller.ts:35-38, :50-53, :67-70, :100-102, :117-119, :135-137
Quyền — nhóm tool/tool-groups* yêu cầu quyền tool_groupsbe/apps/api/src/tool-group/tool-group.controller.ts:32-34, :49-51, :66-68
Quyền — env_systems/env-systems* yêu cầu quyền env_systems (read/create/update/delete)be/apps/api/src/env-system/env-system.controller.ts:32-34, :48-50, :63-65, :80-82, :98-100
Quyền — SAPPToàn bộ 259 route /api/v1/sapp/* @Public(), gồm route ghi trên prod (R-18, R-22). SystemApiKeyGuard có sẵn nhưng chỉ dùng ở app-version / erd-version / resourcebe/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, be/apps/api/src/guards/system-api-key.guard.ts:10-25
Tích hợp ngoài — HubSpot CRM APIToken theo môi trường (prod, dev; staging = prod) đọc từ env_systems lúc gọi; thiếu → 12001 HUBSPOT_ENV_NOT_CONFIGUREDbe/libs/modules/src/lib/hubspot/common.service.ts:47-58, be/libs/constants/src/lib/hubspot/hubspot.constants.ts:10-32
Tích hợp ngoài — SAPP Ops REST APIĐăng nhập POST {baseUrl}/api/v1/auth/login, bearer token cache Redis; timeout login 30 s; request Ops thường timeout 10 phútbe/libs/constants/src/lib/sapp/sapp-ops.constants.ts:38-41, :69-74, be/libs/constants/src/lib/sapp/sapp.constants.ts:38
Tích hợp ngoài — SAP serviceTrace/scan-runs ký HMAC (secret chỉ ở BE), timeout 30 s; manual-scan GET không xác thực; sign-callback gửi client id + secret trong body tới signerbe/libs/modules/src/lib/sapp/sap-log.common.service.ts:56-68, :238-242, :298-315, be/libs/constants/src/lib/sapp/sap-log.constants.ts:42-70
Tích hợp ngoài — Postgres SAPP OpsKết nối trực tiếp dev/staging cho SQL runnerbe/libs/modules/src/lib/sapp/sapp-ops-sql.common.service.ts:83-104, :166-174
Hạ tầng — RedisToken Ops sapp:ops:token:{env}be/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:109-111, :136-144, :176
WiringSappCommonModule cung cấp 6 service dùng chung (Auth, Common, SapLog, Ops, OpsSql, 26297); SappModule gắn 3 controllerbe/libs/modules/src/lib/sapp/module.ts:11-30, be/apps/api/src/sapp/sapp.module.ts:7-11
APP (Flutter)Không có màn SAPP; chỉ màn quản trị tool/nhóm tool (Grep -i sapp trong app/lib = 3 dòng, đều là gợi ý/ghi chú mã tool)app/lib/models/tool.dart:3, app/lib/screens/tool_form_screen.dart:168, app/lib/screens/tool_group_form_screen.dart:153
Thông báo (mail / push / MQTT / Discord)Không thấy — Grep mqtt|mailService|discord|telegram|@Cron trong be/apps/api/src/sapp/*.ts, be/libs/modules/src/lib/sapp/*.ts = 0 kết quả(kết quả Grep)
Job / cronKhông có job phía mind_keep; cron quét doanh thu tuần nằm ở SAP service (ngoài hệ thống)be/libs/modules/src/lib/sapp/sap-log.common.service.ts:215-217; Grep sapp trong be/apps/schedule/src = 0 kết quả

7. Drift — tài liệu nói khác code &ZeroWidthSpace;

IDTài liệu (file + section)Tài liệu nóiCode đang làmBằng chứng
DR-01shared/api-docs/sapp.md:12 §OverviewHubSpot "across two portals (prod / dev)"Ba môi trường; staging dùng lại credential portal prodbe/libs/constants/src/lib/hubspot/hubspot.constants.ts:14-31
DR-02shared/api-docs/sapp.md:14 §Overview"the three routes below are currently marked @Public() … (temporary)"Toàn bộ 259 route SAPP đều @Public(), kể cả route ghi prodbe/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
DR-03shared/api-docs/sapp.md:1128-1131 §SAPP Ops authenticationToken dò theo access_token/accessToken/token/id_token/idToken/jwt; "chưa kiểm với API thật"Danh sách có thêm act — và comment code nói đây là trường đang thực sự dùng (data.tokens.act)be/libs/constants/src/lib/sapp/sapp-ops.constants.ts:43-63
DR-04shared/api-docs/sapp.md:1096-1098 §SAPP Ops authenticationCache token tới exp − 60 s; 30 phút nếu token opaque; tối đa 24 hThêm nhánh không ghi trong doc: hạn còn < 30 s → vẫn cache 30 phútbe/libs/modules/src/lib/sapp/sapp-auth.common.service.ts:195-200
DR-05shared/api-docs/sapp.md:2474 §SAPP Ops passthrough; be/.agents/maps/modules/tool.md §3 ("~20 thao tác Ops")"Twenty read/write operations"33 thao tác mỗi môi trường (35 ở dev/staging tính cả 2 route SQL)Đếm route @(Get|Post|Put|Delete)('<env>/sapp-ops/…') trong be/apps/api/src/sapp/sapp-ops.controller.ts:634-2442
DR-06shared/api-docs/sapp.md:2241 §SAP log trace"Two read-only endpoints"Section còn có manual-scan (kích hoạt quét) và sign-callback (dựng callback ký) — không chỉ đọcbe/apps/api/src/sapp/sapp.controller.ts:3991-4047
DR-07shared/api-docs/tools.md:24-25 §OverviewRoute /tools/public/* "only expose effectively visible tools"GET /tools/public/code/:code và verify trả/kiểm cả tool đang ẩnbe/libs/modules/src/lib/tool/service.ts:125-134, :214-221
DR-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)"GET /tools/code/:code yêu cầu quyền tools:read; route public là /tools/public/code/:codebe/apps/api/src/tool/tool.controller.ts:50-53
DR-09shared/api-docs/tools.md:11 §OverviewRegistry ở mind_keep_cms_ui/src/data/constants/tool-codes.tsĐường dẫn thực tế fe/src/data/constants/tool-codes.tsfe/src/data/constants/tool-codes.ts:1-57
DR-10shared/api-docs/tool-groups.md:30-35Nhóm sapp có sapp.* (10) toolRegistry có 13 mã sapp.*; migration seed thêm sapp.011–013fe/src/data/constants/tool-codes.ts:32-44, be/libs/database/migrations/1786300000000-seed-tool-sapp-26297.ts:14-19

8. Câu hỏi cho BA (code không trả lời được) &ZeroWidthSpace;

IDCâu hỏiVì sao cầnChặn bước sau?
Q-01Toàn bộ API /api/v1/sapp/* (259 route) không cần đăng nhập, kể cả ghi dữ liệu thật trên prod (Ops: tạo user/lớp/đơn/giao dịch, xoá lịch, confirm giao dịch, resync SAP — R-22; econtract retry prod). Đây là cố ý (công cụ nội bộ, chấp nhận rủi ro) hay bug/nợ bảo mật? Ai được phép dùng? (R-18, R-22, DR-02)Quyết định ghi thành BR ("tool mở cho mọi người có link") hay Open Issue bảo mật; ảnh hưởng mọi FS nhómCó
Q-02Chọn "staging" cho HubSpot thực chất ghi vào portal prod (R-20). Người dùng tool có biết điều này không; các thao tác ghi HubSpot "staging" của sub-tool (tạo contact/deal/ticket) có được phép chạm dữ liệu prod?Viết đúng rule môi trường trong FS mọi nhóm dùng HubSpotCó
Q-03Trên DB prod hiện tại tool nào đang bị tắt/ẩn/khoá và loại khoá gì? Code seed mặc định "không khoá" (R-48) nên không suy ra đượcMô tả quyền truy cập thực tế từng tool trong FSCó
Q-04Đối tượng sử dụng /works/sapp là ai (dev/QA nội bộ, BA, đội SAPP)? Không có đăng nhập nên hệ thống không phân biệt vai tròViết Actor/role trong FSCó
Q-05Khoá tool chỉ là UX gate: API không kiểm trạng thái tool (R-15), mở khoá chỉ ở sessionStorage (R-14), verify không giới hạn tần suất (R-16). Đây là mức bảo vệ được chấp nhận hay cần coi là rủi ro?Ghi BR "khoá tool" đúng bản chấtKhông
Q-06Tool đang ẩn vẫn đọc được trạng thái và kiểm tra mã qua route public (R-13, DR-07) — cố ý hay bug?Quyết định BR hay OQKhông
Q-07sortBy của danh sách public ghép thẳng vào ORDER BY (R-45) — cố ý hay bug?Rủi ro kỹ thuật cần ghi OQKhông
Q-08Nhánh cache token 30 phút khi hạn còn < 30 s (R-26) — cố ý hay bug? (có thể giữ token đã chết, được cứu bởi retry 401)Ghi rule token đúngKhông
Q-09Hai cơ chế xác thực Ops cùng tồn tại (R-30). Sub-tool nào còn dùng SAPP_API_TOKEN xoay tay; có kế hoạch bỏ không? Ai chịu trách nhiệm xoay token?Mô tả vận hành/điều kiện tiên quyết trong FSKhông
Q-10Route dựng callback SAP ký sẵn trên dev/staging là public (R-37) — chấp nhận việc ai cũng giả được callback SAP trên staging?Rủi ro, ghi OQKhông
Q-11SQL runner trả nguyên thông báo lỗi Postgres qua route public (R-42) — cố ý (để tester sửa công thức) hay cần che bớt?Quyết định BR hay OQKhông
Q-12SecretGate (khoá cứng năm 2003, chỉ ở trình duyệt) không được dùng (R-46) — di sản cần xoá hay còn kế hoạch dùng?Tránh mô tả nhầm như tính năng đang chạyKhông
Q-13Secret hệ ngoài và secretValue lưu dạng rõ trong DB (R-47) — đã được chấp nhận?Ghi ràng buộc bảo mật/NFRKhông
Q-14Việc #39FE/#41BE còn mở: đã 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? (fail-closed → thiếu dòng = tool đóng, R-05)Điều kiện tiên quyết khi phát hành toolKhông
Q-15Tên chuẩn của tool là tên trong TOOL_CODES/DB hay nhãn sidebar? Có chỗ khác nhau, vd sapp.010 "SAPP 26878: Create deal instance" vs nhãn "Test data theo luồng" (fe/src/data/constants/tool-codes.ts:41, fe/src/ui/pages/works/sapp/tools/registry.ts:101)Thống nhất tên trong FSKhông
Q-16Mục đích nghiệp vụ của cách nhóm tool theo số ticket SAPP (20603, 24395, …) và ai quyết định thêm/bỏ tool khỏi workspace?Viết phần tổng quan/BRDKhông

9. Nhật ký nguồn đã đọc &ZeroWidthSpace;

File / sectionMục đích
ba/_workflow/templates/feature-inventory/Template.mdKhung §1–§9
ba/system-profile.md §3Công thức truy vết
ba/projects/2026-SAPP-Works-tools/project-context.mdPhạm vi dự án, nhóm tài liệu
ba/projects/2026-SAPP-Works-tools/working/ai-drafts/feature-inventory-hubspot-20260930.md (đầu file)Thống nhất định dạng với inventory nhóm khác
fe/CLAUDE.md (§Tool codes, §DatePicker)Luật TOOL_CODES
fe/app/works/sapp/page.tsx, fe/app/works/sapp/tools/page.tsx, fe/app/works/sapp/tools/layout.tsxRoute hub, index, layout
fe/src/ui/pages/works/sapp/tools/registry.ts, index-redirect.tsx, shell.tsxNhóm tool, chọn tool đích, sidebar, lưu trạng thái trình duyệt
fe/src/ui/components/works/shared/{tool-availability.ts, tool-gate.tsx, use-tools-state.ts, tools-state-context.tsx, last-tool.ts, use-persisted-flag.ts}Cơ chế đóng/mở, khoá, ghi nhớ
fe/src/data/constants/tool-codes.tsRegistry mã tool
fe/src/data/models/tool.interface.ts, fe/src/data/enums/tool.enum.tsShape public, loại khoá
fe/src/data/services/cms/(tools)/get-public.service.ts, verify-secret.service.tsRoute FE gọi
fe/src/ui/components/works/sapp/secret-gate.tsx + Grep SecretGateComponent khoá cũ, xác nhận không dùng
fe/src/ui/components/works/sapp/sap-log-trace.tsx (301-360), sap-log-summary.tsx (160-238) + Grep importerTra vết SAP phía FE, luật màu trạng thái
fe/src/ui/components/works/sapp/ (Grep ^export trong shared.tsx, utils.ts, select.tsx, checkbox.tsx, date-picker.tsx, hubspot-property-field.tsx; property-tool.tsx:25-30)Liệt kê component dùng chung
fe/src/data/constants/api.ts (178-341)URL SAPP phía FE, kiểu env
fe/src/data/services/sapp/sap-log.service.ts (1-40) + ls fe/src/data/services/sappService FE dùng chung
fe/app/cms/(tools)/tools/page.tsxMàn admin tool web
be/apps/api/src/tool/tool-public.controller.ts, tool.controller.ts (20-70 + Grep), tool.module.ts (Grep)API tool public/admin
be/apps/api/src/tool-group/tool-group.controller.ts (Grep)Quyền nhóm tool
be/libs/modules/src/lib/tool/service.ts, common.service.tsRule hiệu lực, verify, danh sách public
be/libs/database/src/lib/entities/tool/tool.entity.ts, tool-group.entity.tsBảng tools, tool_groups
be/libs/interface/src/lib/dto/tool/tool.dto.ts (Grep + 175-190), be/libs/interface/src/lib/dto/base/request.dto.tsDTO lọc/verify, phân trang
be/libs/database/migrations/1783700000000-create-tools.ts (Grep), 1786300000000-seed-tool-sapp-26297.ts, Grep seed 012/013Seed tool
be/apps/api/src/decorators/public.decorator.ts, be/apps/api/src/guards/system-api-key.guard.ts + Grep usageCơ chế public / API key
be/apps/api/src/interceptors/grpc-auth.interceptor.ts (20-45), be/apps/api/src/app/app.module.ts (Grep), be/apps/api/src/main.ts (15-52)Xác thực toàn cục, versioning, CORS
be/apps/api/src/sapp/sapp.module.ts, sapp.controller.ts (150-200, 815-847, 3930-4050 + Grep route), sapp-ops.controller.ts (1-200 + Grep route), sapp-26297.controller.ts (40-78 + Grep route)Quyền, route theo env, đếm route
be/libs/modules/src/lib/sapp/module.tsWiring service
be/libs/modules/src/lib/sapp/sapp-auth.common.service.tsAuto-login Ops
be/libs/modules/src/lib/sapp/sap-log.common.service.tsSAP log trace
be/libs/modules/src/lib/sapp/sapp-ops.common.service.ts (Grep outline, 79-135, 280-300)Ops passthrough plumbing
be/libs/modules/src/lib/sapp/sapp-ops-sql.common.service.tsSQL runner
be/libs/modules/src/lib/sapp/common.service.ts (Grep outline, 255-313)Phần credential Ops dùng chung (bộ cũ)
be/libs/modules/src/lib/hubspot/common.service.ts (20-60, 715-800)Token HubSpot, thêm option
be/libs/modules/src/lib/env-system/env-system-map.common.service.ts, be/apps/api/src/env-system/env-system.controller.ts (Grep), be/libs/database/src/lib/entities/env/env-system.entity.tsenv_systems
be/libs/constants/src/lib/{env-system/env-system.constants.ts, hubspot/hubspot.constants.ts, hubspot/hubspot.enum.ts, sapp/sapp-ops.constants.ts, sapp/sap-log.constants.ts, sapp/sapp.constants.ts, sapp/sapp-26878-sql.constants.ts (270-315), sapp/sapp-ops-sql.constants.ts}Key, TTL, giới hạn, timeout
be/libs/interface/src/lib/dto/sapp/sap-log.dto.ts (Grep)DTO SAP log
Grep Throttl, ToolService|verifySecret (sapp), mqtt|mail|discord|telegram|@Cron (sapp), sapp (be/apps/schedule/src)Xác nhận không có throttle / kiểm tra tool / thông báo / job
app/lib Grep -i sapp; app/lib/services/tool_service.dart, tool_group_service.dart, app/lib/screens/tool_admin_list_screen.dart (Grep)Xác nhận APP không có màn SAPP
shared/api-docs/sapp.md §Overview (1-32), §SAPP Ops authentication (1084-1133), §SAP log trace (2239-2275, 2345-2350), §add option (2427-2445), §SAPP Ops passthrough (2472-2520), §SQL runner (2674-2722)Đối chiếu doc → Drift
shared/api-docs/tools.md (8-33, 64-73, 134-200 + Grep)Đối chiếu doc tool
shared/api-docs/tool-groups.md (30-40), shared/api-docs/env-system.md (1-30 Grep)Đối chiếu doc nhóm tool, env_systems
shared/integration/README.md dòng #39FE, #40BE, #41BE (Grep sapp|works|tool)Lịch sử fail-closed, verify public, việc còn mở
shared/runbooks/sapp/README.md (đầu file)Bối cảnh vận hành SAPP
be/.agents/maps/modules/tool.md (6-125)Bản đồ module tool/SAPP — đối chiếu