Giao diện
SAPP HubSpot tools (sapp.001–004) - 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-H0X-<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.Tài liệu as-built: mô tả hành vi code tại commit
e77c47a, dựng từ đọc source (chưa gọi API hay chạy màn nào). Nguồn Fact: feature-inventory-hubspot-20260930.md (đã qua Gate R1). Mã gốc inventory (A-xx, R-xx, Q-xx, DR-xx) được ghi kèm để truy vết.
| Field | Value |
|---|---|
| Doc ID | FS-SAPP-HUBSPOT |
| Mode | B – As-built |
| As-built tại commit | e77c47a |
| Last Updated | 2026-09-30 |
| Author | AI (lane ba/) |
| Reviewers | BA |
| Status | DRAFT |
| Figma Project | N/A — as-built, không có Figma |
| Related BRD | ../../brd/brd-as-built-v0.1-20260930.md |
| Related Impact Matrix | N/A — Mode B (as-built), không có Impact Analysis |
1. Tổng quan dự án ​
Bốn sub-tool trong workspace /works/sapp/tools, nhóm sidebar "SAPP Common Hubspot Tools", thao tác trên định nghĩa dữ liệu HubSpot CRM của hai portal SAPP (prod và dev): tra cứu định nghĩa property (sapp.003), clone property từ prod sang dev (sapp.001), xem lịch sử thay đổi property trên một bản ghi (sapp.002), và quản lý pipeline — xem, clone prod → dev, nhân bản trong cùng portal (sapp.004). Nhóm người dùng: "Người dùng tool" — Assumption (OQ-H-01 về G-01).
1.1 Bối cảnh ​
- Fact (code): 4 tool không có bảng DB riêng; dữ liệu là property / pipeline / lịch sử property sống trong HubSpot. Cả 4 tool đi qua service HubSpot riêng (
be/libs/modules/src/lib/hubspot/common.service.ts) và HTTP client REST tự viết (be/libs/services/src/lib/hubspot/hubspot.service.ts) — không qua service SAPP (be/libs/modules/src/lib/sapp/common.service.ts); controller gọi thẳng service HubSpot (be/apps/api/src/sapp/sapp.controller.ts:163). - Fact (code): "prod" và "staging" dùng chung token portal prod; "dev" dùng token portal dev. Mọi lời gọi đi tới cùng host
https://api.hubapi.com, phân biệt portal chỉ bằng token (be/libs/constants/src/lib/hubspot/hubspot.constants.ts:14-31,be/libs/services/src/lib/hubspot/hubspot.service.ts:35). - Pain point / trigger nghiệp vụ:
[Assumption]— tool phục vụ việc dựng và kiểm tra cấu hình HubSpot dev cho khớp prod khi test các luồng SAPP. Chưa có xác nhận từ BA (OQ-H-04; không có tài liệu trongshared/external/sapp/**cho 4 tool này).
1.2 Mục tiêu ​
[Assumption] — chưa có câu trả lời BA (OQ-H-04, G-05):
- Giúp người dùng tool đọc nhanh định nghĩa property / pipeline mà không cần quyền admin HubSpot.
- Đồng bộ định nghĩa property / pipeline từ prod sang dev để môi trường test giống prod.
- Tái dựng giá trị property của một bản ghi tại một thời điểm để điều tra sự cố.
Không có KPI / ràng buộc thời gian (as-built).
1.3 In Scope ​
Phạm vi đã truy vết ở inventory §1:
- 4 màn web:
/works/sapp/tools/hs-get-property(US-H01),/works/sapp/tools/hs-clone-prod-to-dev(US-H02),/works/sapp/tools/hs-snapshot-property(US-H03),/works/sapp/tools/hs-pipeline(US-H04, US-H05, US-H06). - Các API BE mà 4 màn gọi (inventory E-05…E-12): get property, clone property prod → dev, property-history, list/get pipeline, clone pipeline prod → dev, duplicate pipeline trong cùng portal (dev và prod).
- Các route cùng nhóm không có UI (biến thể
staging, gọi trực tiếp API) — mô tả ở §2.2, không thành US.
1.4 Out Of Scope ​
- Gate truy cập tool (ẩn / tắt / khoá mã bí mật theo
code) → US-P02. - Mở workspace, sidebar, "tool dùng gần nhất" → US-P01.
- Đọc credential từ
env_systems→ US-P04. - Cơ chế
@Public()/ guard toàn cục → NFR-P-01. - Thêm option cho property HubSpot dev → US-P07 (dùng bởi sapp-26878, không thuộc 4 tool).
- Component chọn property dùng chung (
hubspot-property-field) — không được 4 tool này dùng. - Route "Suggested trace properties" và "Property history timeline (trace)" (
be/apps/api/src/sapp/sapp.controller.ts:1538-1701) — không màn nào trong 4 tool gọi (OQ-H-12).
1.5 Roles And Permissions ​
| Role ID | Role Name | Description | Permission Summary |
|---|---|---|---|
| R1 | Người dùng tool | Assumption (OQ-H-01 về G-01): người qua được gate của từng tool sapp.001–004. Code không có role riêng, không phân biệt người chỉ đọc (Property, Snapshot) và người được ghi (Clone, Pipeline) | FE: gate chung theo code tool (US-P02). BE: mọi route công khai — xem NFR-P-01 |
| R2 | Bên gọi API trực tiếp | Bất kỳ ai gọi được /api/v1/sapp/* (Fact — inventory A-10) | Như R1 ở BE, không qua gate FE (§2.2) |
2. Luồng tổng quan của dự án ​
text
[Workspace /works/sapp/tools — US-P01] → [Gate tool theo code — US-P02]
↓ chọn tool trong nhóm "SAPP Common Hubspot Tools"
├─ "Property" (sapp.003) → [US-H01 Tra định nghĩa property] đọc prod | dev
├─ "Clone" (sapp.001) → [US-H02 Clone property prod → dev] đọc prod, ghi dev
├─ "Snapshot" (sapp.002) → [US-H03 Lịch sử property trên 1 bản ghi] đọc prod | dev
└─ "Pipeline" (sapp.004) → [US-H04 Xem pipeline + stage] đọc prod | dev
├─ env = Prod → [US-H05 Clone pipeline prod → dev] ghi dev
└─ env = Prod | Dev → [US-H06 Nhân bản trong cùng portal] ghi dev | ⚠️ PRODLink flow nếu có: N/A — as-built, không có Figma / flow riêng.
2.1 Ma trận đọc / ghi môi trường (Fact — inventory §5) ​
| Tool | Đọc | Ghi | Ghi vào prod? |
|---|---|---|---|
| sapp.003 Get property (US-H01) | prod hoặc dev (UI); API còn có staging (= prod) | — | Không |
| sapp.002 Snapshot property (US-H03) | prod hoặc dev | — | Không |
| sapp.001 Clone prod to dev (US-H02) | prod (nguồn) + dev (kiểm tra tồn tại) | dev (tạo property) | Không |
| sapp.004 Pipeline (US-H04…H06) | prod hoặc dev | dev (clone prod → dev; duplicate trong dev) và prod (duplicate trong prod) | Có — US-H06 (inventory A-09 / E-12) |
2.2 Route API không có UI — inventory A-10 (⚠️ Observed) ​
Các route E-05…E-12 hoạt động độc lập với gate FE và gọi được trực tiếp (quyền: NFR-P-01). Ngoài những gì UI mở, API còn có:
| Route không có UI | Hành vi | Bằng chứng |
|---|---|---|
GET /api/v1/sapp/staging/hubspot/{deals|contacts}/properties/:property | Trả cùng dữ liệu như prod (dùng token prod). Tickets không có biến thể staging | be/apps/api/src/sapp/sapp.controller.ts:592,1054,596-597; be/libs/constants/src/lib/hubspot/hubspot.constants.ts:19-26 |
POST …/{prod|dev}/hubspot/{deals|tickets}/pipelines/:pipelineId/duplicate với label rỗng / chỉ khoảng trắng | Qua được validate; BE rơi về label nguồn, tìm thấy chính pipeline nguồn và trả nó như thành công, không tạo gì (⚠️ Observed — OQ-H-10) | be/libs/interface/src/lib/dto/hubspot/hubspot-pipeline.dto.ts:52-55; be/libs/modules/src/lib/hubspot/common.service.ts:1068,1081-1084 |
| Mọi route ghi (clone property, clone / duplicate pipeline, kể cả duplicate prod) | Gọi được không cần đăng nhập, không qua gate tool | be/apps/api/src/sapp/sapp.controller.ts:616,929,957,985,1078,1171,1275,1303,1331 |
UI chỉ cho chọn Prod / Dev, không có Staging (OQ-H-11).
3. Các tính năng liên quan ​
| Mã | Tính năng liên quan | Link tài liệu | Loại liên quan | Mục bị ảnh hưởng ở feature kia | Mục ảnh hưởng ở feature hiện tại | Mô tả ảnh hưởng |
|---|---|---|---|---|---|---|
| REL-H-01 | Hub + gate tool (nền tảng) | US-P01, US-P02 | Affects | Trạng thái tool sapp.001…sapp.004 | Trigger vào màn M1 của mọi US-H | Tool bị ẩn / tắt / khoá thì người dùng không vào được màn; BE không kiểm tra lại |
| REL-H-02 | Cấu hình kết nối env_systems (nền tảng) | US-P04 | Affects | Khoá SAPP_PROD_HUBSPOT_ACCESS_TOKEN, SAPP_DEV_HUBSPOT_ACCESS_TOKEN | Mọi action gọi HubSpot | Thiếu token môi trường → lỗi 12001; token đọc mỗi lần gọi |
| REL-H-03 | Thêm option property HubSpot dev | US-P07 | Be Affected | Property dev mà US-P07 thêm option | US-H02 - action Clone to dev | [Assumption] quan hệ dữ liệu: cùng thao tác trên định nghĩa property của portal dev; không có lời gọi code giữa hai tool |
| REL-H-04 | HubSpot portal prod (hệ thống ngoài, người dùng CRM thật) | N/A — hệ thống ngoài | Be Affected | Danh sách pipeline deal / ticket của portal prod | US-H06 - action Duplicate (env = Prod) | Pipeline mới được tạo thật trong prod (⚠️ Observed — OQ-H-03) |
4. User Story Index ​
| US ID | Tên User Story | File | Role | Priority | Status |
|---|---|---|---|---|---|
| US-H01 | Tra định nghĩa một property | US-H01-get-property.md | R1 | N/A — as-built | Draft |
| US-H02 | Clone property từ prod sang dev | US-H02-clone-property.md | R1 | N/A — as-built | Draft |
| US-H03 | Xem lịch sử thay đổi property trên một bản ghi | US-H03-snapshot-property.md | R1 | N/A — as-built | Draft |
| US-H04 | Xem danh sách pipeline và stage | US-H04-xem-pipeline.md | R1 | N/A — as-built | Draft |
| US-H05 | Clone pipeline từ prod sang dev | US-H05-clone-pipeline.md | R1 | N/A — as-built | Draft |
| US-H06 | Nhân bản pipeline trong cùng portal | US-H06-nhan-ban-pipeline.md | R1 | N/A — as-built | Draft |
Status = Draft: as-built chờ Gate R2. Truy vết hành động inventory: A-01, A-02, A-11 → US-H01 · A-03 → US-H02 · A-04 → US-H03 · A-05, A-06 → US-H04 · A-07 → US-H05 · A-08, A-09 → US-H06 · A-10 → §2.2 · A-11 (popup lỗi) áp dụng cho cả 4 tool qua NFR-H-04.
5. Non-functional Requirements ​
| ID | Requirement | Applies To (US/màn/API) | Acceptance Criteria |
|---|---|---|---|
| NFR-H-01 | Quyền truy cập API: không lặp ở đây — xem NFR-P-01 (toàn bộ /api/v1/sapp/* là @Public()). Với nhóm này, điều đó gồm cả route ghi dev và route ghi prod (inventory R-01, ⚠️ Observed — OQ-H-02) | Mọi US-H, route E-05…E-12 | Như NFR-P-01 |
| NFR-H-02 | Credential theo môi trường đọc từ env_systems ở mỗi lần gọi; thiếu token → lỗi 12001 "HubSpot access token is not configured for this environment" (HTTP 400). "staging" dùng token prod (inventory R-09, R-10). Chi tiết cấu hình → US-P04 | Mọi action gọi HubSpot | Xoá / để trống token môi trường X → mọi thao tác trên X trả 12001; khôi phục → hoạt động lại không cần restart (be/libs/modules/src/lib/hubspot/common.service.ts:47-58) |
| NFR-H-03 | Host HubSpot cố định https://api.hubapi.com; khoá SAPP_*_HUBSPOT_API_URL khai báo nhưng không dùng (inventory R-28, DR-07) | Mọi action | Đổi giá trị SAPP_*_HUBSPOT_API_URL không đổi host được gọi (be/libs/services/src/lib/hubspot/hubspot.service.ts:35) |
| NFR-H-04 | Báo lỗi thống nhất: API lỗi → popup có tiêu đề theo thao tác, nội dung message (code); lỗi không có mã → nội dung là thông điệp lỗi thô (inventory A-11) | Mọi màn US-H | Mỗi US liệt kê tiêu đề popup ở Error cases; nội dung khớp message (code) của bảng mã lỗi 12001…12008 (be/libs/constants/src/lib/error-codes/error-codes.constants.ts:466-505) |
| NFR-H-05 | Trong lúc gọi API, nút hành động đổi chữ ("Fetching…", "Cloning…", "Checking…", "Loading…", "Duplicating…") và mọi ô nhập / chọn của màn bị khoá | Mọi màn US-H | Bấm hành động → không sửa được input cho tới khi có kết quả / lỗi |
| NFR-H-06 | Log: lỗi được ghi log BE theo tên handler. Không có thông báo (mail / push / MQTT / Discord), không có job / cron (inventory §6) | Mọi US-H | Chỉ popup trên UI; không có kênh thông báo nào khác |
| NFR-H-07 | Idempotent theo khoá tự nhiên: clone / duplicate không bao giờ ghi đè đích — property so theo name, pipeline so theo label; đích đã có → trả bản hiện có (inventory R-04, R-21) | US-H02, US-H05, US-H06 | Gọi hai lần cùng input → lần hai không tạo thêm, trả cùng bản ghi |
6. Open Questions ​
| ID | Question | Owner | Due Date | Status | Blocks (US) |
|---|---|---|---|---|---|
| OQ-H-01 | Ai (role / nhóm) được dùng 4 tool? Có cần phân biệt người chỉ đọc (Property, Snapshot) và người được ghi (Clone, Pipeline)? (inventory Q-01; G-01) | BA | Trước Gate R2 | Open | Tất cả |
| OQ-H-02 | Toàn bộ API của 4 tool (kể cả ghi dev và ghi prod) công khai — chấp nhận hay nợ bảo mật? Có kế hoạch siết xác thực? (inventory Q-02; G-02; chi tiết chung ở NFR-P-01) | BA / BE | Trước Gate R2 | Open | US-H02, US-H05, US-H06 |
| OQ-H-03 | Duplicate pipeline trong portal prod — cố ý hay bug? Nếu cố ý: ai được làm, có cần bước xác nhận riêng khi ghi prod? Hiện chỉ có modal nhập label, subtitle ghi "into prod portal" (inventory Q-03, R-20; G-03) | BA | Trước Gate R2 | Open | US-H06 |
| OQ-H-04 | Mục đích nghiệp vụ của từng tool (vd clone prod → dev để dựng dữ liệu test cho dự án nào)? Dùng cho §1.1, §1.2 và "So that" của mọi US (inventory Q-04; G-05) | BA | — | Open | Tất cả (không chặn) |
| OQ-H-05 | Clone property: dev đã có cùng tên → trả bản dev cũ nhưng popup vẫn "Clone completed … is now available in the dev portal" — cố ý hay bug? Người dùng có cần được báo "đã có sẵn, không cập nhật"? Có cần ghi đè (code có sẵn tuỳ chọn ghi đè nhưng không bật)? (inventory Q-05, R-07) | BA | — | Open | US-H02 |
| OQ-H-06 | Mọi lỗi HubSpot khi đọc property (token hỏng, rate limit, 5xx) đều báo "HubSpot property not found" (12003) — cố ý hay bug? (inventory Q-06, R-08, DR-06) | BA / BE | — | Open | US-H01, US-H02 |
| OQ-H-07 | Snapshot với tên property không tồn tại: code không báo lỗi riêng, hiện "No history entries" — cần chạy thật để xác nhận HubSpot phản hồi; hành vi mong muốn? (inventory Q-07) | BA | — | Open | US-H03 |
| OQ-H-08 | Target time hiểu theo giờ trình duyệt, cột Timestamp hiển thị nguyên chuỗi UTC HubSpot trả — người dùng (VN, +7) có nhầm? Cố ý hay cần đổi? (inventory Q-08, R-16) | BA | — | Open | US-H03 |
| OQ-H-09 | Nhãn "value at target" hiện theo ô Target time hiện tại trên form, không theo lần tra đã gửi; kết quả không xoá khi đổi / xoá ô — cố ý hay bug? (inventory Q-09, R-17) | BA | — | Open | US-H03 |
| OQ-H-10 | Gọi API duplicate với label rỗng trả về chính pipeline nguồn như thành công — cố ý hay bug? (inventory Q-10, R-24, DR-05) | BA / BE | — | Open | US-H06 (chỉ qua API) |
| OQ-H-11 | UI chỉ có Prod / Dev; API get property có thêm staging (= prod). Có cần Staging trên 4 tool? (inventory Q-11) | BA | — | Open | US-H01 |
| OQ-H-12 | Route "Suggested trace properties" và "Property history timeline (trace)" không màn nào gọi — thuộc tool nào, có trong phạm vi tài liệu? (inventory Q-12) | BA | — | Open | — |
| OQ-H-13 | So khớp pipeline theo label phân biệt hoa / thường, chỉ cắt khoảng trắng ở label mới — "Sales Pipeline" (dev) và "Sales pipeline" (prod) sẽ sinh thêm một pipeline. Chấp nhận? (inventory Q-13) | BA | — | Open | US-H05, US-H06 |
| OQ-H-14 | Clone / duplicate pipeline khi đích đã có cùng label: BE trả pipeline cũ, nhưng popup vẫn "Clone completed … is now available in the dev portal" / "Duplicate completed … was created in the <env> portal" — cố ý hay bug? (mở rộng inventory Q-05 sang pipeline; bằng chứng fe/src/ui/components/works/sapp/pipeline-tool.tsx:137-143,170-176 + be/libs/modules/src/lib/hubspot/common.service.ts:1081-1084; phát hiện khi viết R3) | BA | — | Open | US-H05, US-H06 |
| OQ-H-15 | Danh sách pipeline không làm mới khi đổi Environment / Object type. Các nút View stages / Clone to dev / Duplicate dùng id của danh sách cũ nhưng môi trường / object đang chọn. Vd: tải danh sách Dev, đổi sang Prod, bấm Duplicate → gọi duplicate trong prod với id lấy từ dev (nếu id trùng một pipeline prod thì tạo pipeline trong prod). Cố ý hay bug? (phát hiện khi viết R3 từ đọc code, chưa có trong inventory, chưa chạy thử; bằng chứng fe/src/ui/components/works/sapp/pipeline-tool.tsx:54-56,239-254,269,306-308,317,339-346,431-433) | BA / FE | Trước Gate R2 | Open | US-H04, US-H05, US-H06 |
6b. Drift: tài liệu ↔ code ​
Nguồn: inventory §7. Không tự chọn bên đúng — shared/api-docs/ chỉ lane be/ sửa.
| ID | Tài liệu nói | Code đang làm (bằng chứng file:dòng) | Ảnh hưởng | Owner quyết |
|---|---|---|---|---|
| DR-H-01 | shared/api-docs/sapp.md:14 §Overview: "the three routes below are currently marked @Public()" (inventory DR-01) | Toàn bộ route HubSpot của 4 tool (≥ 29 route, gồm route ghi prod) đều @Public() — be/apps/api/src/sapp/sapp.controller.ts các dòng ở inventory R-01 | Người đọc doc đánh giá thấp bề mặt công khai | BE |
| DR-H-02 | shared/api-docs/sapp.md:12: làm việc với "two portals (prod / dev)" (inventory DR-02) | Có thêm env staging (dùng credential prod) cho get property deals / contacts — be/libs/constants/src/lib/hubspot/hubspot.enum.ts:1-5; be/apps/api/src/sapp/sapp.controller.ts:592,1054. Doc nhắc staging ở :74-80, :119 nhưng tổng quan chưa cập nhật | Người đọc không biết "staging" = prod | BE |
| DR-H-03 | shared/api-docs/sapp.md:150: "There are 5 routes per object type" (inventory DR-03) | Bảng ngay dưới có 6 dòng; thực tế mỗi object có 7 route — be/apps/api/src/sapp/sapp.controller.ts:848-1010 (deals), 1194-1356 (tickets) | Thiếu route trong contract | BE |
| DR-H-04 | shared/api-docs/sapp.md:148: "Clones a pipeline definition … from prod to dev" (inventory DR-04) | Nhóm route còn tạo pipeline trong portal prod (duplicate prod), doc chỉ nhắc ở :176, không cảnh báo ghi prod — be/apps/api/src/sapp/sapp.controller.ts:956-977,1302-1323 | Che mất thao tác ghi prod (liên quan OQ-H-03) | BE |
| DR-H-05 | shared/api-docs/sapp.md:177-181: body label "required" (inventory DR-05) | DTO chỉ kiểm tra là chuỗi; rỗng / khoảng trắng qua được, BE trả lại pipeline nguồn — be/libs/interface/src/lib/dto/hubspot/hubspot-pipeline.dto.ts:52-55; be/libs/modules/src/lib/hubspot/common.service.ts:1068,1081-1084 | Liên quan OQ-H-10 | BE |
| DR-H-06 | shared/api-docs/sapp.md:60: lỗi 12003 / 12001 cho get property (inventory DR-06) | 12003 trả cho mọi lỗi HubSpot, không chỉ "không tồn tại" — be/libs/modules/src/lib/hubspot/common.service.ts:500-505 | Chẩn đoán sai khi token hết hạn (OQ-H-06) | BE |
| DR-H-07 | shared/api-docs/sapp.md:16-25: SAPP_*_HUBSPOT_API_URL "(reserved)" (inventory DR-07) | Khớp — code không dùng, host cố định (be/libs/services/src/lib/hubspot/hubspot.service.ts:35). Ghi lại để không mô tả sai là có cấu hình host (NFR-H-03) | Không (chỉ ghi nhận) | — |
| DR-H-08 | shared/api-docs/sapp.md:121-126 §Contacts, §Overview: không có route thêm option (inventory DR-08) | Có POST dev/hubspot/{deals|contacts}/properties/:property/options chưa được mô tả — be/apps/api/src/sapp/sapp.controller.ts:821,1101 (ngoài 4 tool, thuộc US-P07) | Contract thiếu route | BE |
| DR-H-09 | Swagger DTO be/libs/interface/src/lib/dto/hubspot/hubspot-property-history.dto.ts:33-45,62-65: response có sourceId, sourceLabel, updatedByUserId, valueLabel, targetValueLabel (inventory DR-09) | Service property-history chỉ dựng history / targetEntry / targetValue, không gắn nhãn giá trị — be/libs/modules/src/lib/hubspot/common.service.ts:140-170; shared/api-docs/sapp.md:222-241 khớp code, Swagger thì không | Người đọc Swagger kỳ vọng field không có | BE |
| DR-H-10 | be/.agents/maps/modules/hubspot.md: module HubSpot nằm ở apps/hubspot-service, … ; client @hubspot/api-client (inventory DR-10) | Repo chỉ có be/apps/api, hook, schedule; 4 tool đi qua controller SAPP + service HubSpot + client REST tự viết — be/libs/services/src/lib/hubspot/hubspot.service.ts:21-35 | Map module dẫn sai chỗ | BE |
7. References ​
- BRD: ../../brd/brd-as-built-v0.1-20260930.md
- Impact Matrix: N/A — Mode B
- Solution Decision: ../../../project-decisions.md
- Figma: N/A — as-built, không có Figma
- API Spec:
shared/api-docs/sapp.md(có drift — §6b) - Feature Inventory (nguồn Fact): feature-inventory-hubspot-20260930.md
- Danh sách US (R2): us-backlog-r2-20260930.md mục "FS 2"
- Câu hỏi gộp Gate R1: gate-r1-summary-20260930.md
- FS nền tảng: ../sapp-platform-as-built-v0.1-20260930/00-overview.md
- Code đã đọc (Mode B):
fe/src/ui/components/works/sapp/{property,clone,snapshot,pipeline}-tool.tsx;fe/src/data/services/sapp/{get-property,clone-property,property-history,pipeline}.service.ts;be/apps/api/src/sapp/sapp.controller.ts;be/libs/modules/src/lib/hubspot/common.service.ts;be/libs/services/src/lib/hubspot/hubspot.service.ts;be/libs/constants/src/lib/hubspot/hubspot.constants.ts;be/libs/constants/src/lib/error-codes/error-codes.constants.ts; DTObe/libs/interface/src/lib/dto/hubspot/*— chi tiết ở inventory §9 - Meeting Notes / Q&A: N/A — G-01…G-10 chưa có trả lời
8. Template Conformance Check ​
So khớp mục lục từng file US với ba/_workflow/templates/fs/User-Story.md (Metadata · 1. US Statement · 2. Dependencies & DoR · 3. Business Rules [cột "Đã cover bởi (AC)" + "Nguồn code"] · 4. Design [a. flow · b. mỗi màn: UI States · Fields · Filter/Search/Sort · Actions · AC G/W/T · Negative AC / Edge Cases] · 5. Cross-feature AC).
| US file | Section thiếu | Trạng thái |
|---|---|---|
| US-H01-get-property.md | (đủ — Filter/Search/Sort ghi N/A: màn tra cứu đơn, không phải List) | ✅ |
| US-H02-clone-property.md | (đủ — Filter/Search/Sort ghi N/A) | ✅ |
| US-H03-snapshot-property.md | (đủ — Filter/Search/Sort ghi N/A) | ✅ |
| US-H04-xem-pipeline.md | (đủ — M1 là màn List: Filter/Search/Sort có bảng; M2 ghi N/A) | ✅ |
| US-H05-clone-pipeline.md | (đủ — Filter/Search/Sort của M1 tham chiếu US-H04, M2 ghi N/A) | ✅ |
| US-H06-nhan-ban-pipeline.md | (đủ — Filter/Search/Sort của M1 tham chiếu US-H04, M2 ghi N/A) | ✅ |
Kiểm thêm: mọi BR có cột Nguồn code và ≥ 1 AC/EC cover; mọi ⚠️ Observed có OQ tương ứng ở §6; action ghi prod (US-H06 A2) có dòng ⚠️ Ghi PROD; mọi A-01…A-11 của inventory đã map (§4).