Giao diện
US-H05: Clone pipeline từ prod sang dev ​
Thuộc FS: 00-overview.md — SAPP HubSpot tools (sapp.001–004) Phần chung (tổng quan, roles, flow tổng, related features, NFR, Open Questions, References) xem ở Overview. File này chỉ chứa nội dung riêng của US. As-built tại commit
e77c47a. Nguồn: inventory A-07 (và A-11 cho popup lỗi). Danh sách pipeline (M1) mô tả đầy đủ ở US-H04.
| Field | Value |
|---|---|
| US ID | US-H05 |
| Role thực hiện | R1 - Người dùng tool (Assumption — OQ-H-01 về G-01) |
| Phase | As-built (đã triển khai) |
| Priority | N/A — as-built |
| Status | Draft |
| NFR liên quan | NFR-H-01, NFR-H-02, NFR-H-04, NFR-H-05, NFR-H-07 — xem Overview §5 |
| OQ liên quan | OQ-H-01, OQ-H-02, OQ-H-04, OQ-H-13, OQ-H-14, OQ-H-15 — xem Overview §6 |
1. US Statement ​
text
As a Người dùng tool [Assumption — OQ-H-01 về G-01]
I want chọn một pipeline Deal / Ticket của portal prod và clone nó (kèm toàn bộ stage) sang portal dev, tuỳ chọn đặt label mới
So that [Assumption — OQ-H-04] portal dev có cùng pipeline như prod để chạy dữ liệu test2. Dependencies & Definition Of Ready ​
N/A — đã triển khai (Mode B). Dependency runtime:
| # | Cần sẵn sàng | Ai cung cấp | Trạng thái |
|---|---|---|---|
| D1 | Tool sapp.004 đang bật / hiển thị / đã mở khoá — US-P02 | Admin CMS | Runtime |
| D2 | env_systems: cả SAPP_PROD_HUBSPOT_ACCESS_TOKEN (đọc nguồn) và SAPP_DEV_HUBSPOT_ACCESS_TOKEN (ghi đích) — US-P04 | Admin CMS | Runtime |
| D3 | Danh sách pipeline prod đã tải ở US-H04 | — | Runtime |
3. Business Rules ​
| ID | Rule | Áp dụng ở | Đã cover bởi (AC) | Nguồn code (Mode B/C) |
|---|---|---|---|---|
| BR-01 | Nút "Clone to dev" chỉ hiện trên thẻ pipeline khi môi trường đang chọn là Prod; chiều clone cố định prod → dev | M1 - action A1 | AC-M1.1, AC-M1.2 | fe/src/ui/components/works/sapp/pipeline-tool.tsx:317-335; be/apps/api/src/sapp/sapp.controller.ts:937-948 |
| BR-02 | Modal "Clone pipeline to dev", phụ đề "Source: <label nguồn> · into dev portal"; ô "New label (optional)" điền sẵn label nguồn | M2 - field New label | AC-M2.1 | fe/src/ui/components/works/sapp/pipeline-tool.tsx:322-327,426-433,471-489 |
| BR-03 | Label mới để trống → giữ label nguồn | M2 - action A2 | AC-M2.2 | fe/src/ui/components/works/sapp/pipeline-tool.tsx:191-197; be/libs/modules/src/lib/hubspot/common.service.ts:1068 |
| BR-04 | Không ghi đè: pipeline đích ở dev được so khớp theo label (chính xác, sau khi cắt khoảng trắng label mới); đã có → trả nguyên pipeline dev đó, không tạo (NFR-H-07) | M2 - action A2 | AC-M2.3 | be/libs/modules/src/lib/hubspot/common.service.ts:1068,1081-1084 |
| BR-05 | Pipeline mới ở dev giữ label đích, thứ tự hiển thị và toàn bộ stage của nguồn (label, thứ tự, metadata); id pipeline / stage do HubSpot cấp mới | M2 - action A2 | AC-M2.1 | be/libs/modules/src/lib/hubspot/common.service.ts:1034-1046,1086-1087 |
| BR-06 | Lỗi: pipeline nguồn không có ở prod → 12007; đọc danh sách dev lỗi → 12002; tạo ở dev lỗi → 12008 "Failed to clone HubSpot pipeline". Popup "Failed to clone pipeline" (NFR-H-04) | M2 - action A2 | EC-M2.1, EC-M2.2 | be/libs/modules/src/lib/hubspot/common.service.ts:1018-1023,1075-1079,1093-1098; fe/src/ui/components/works/sapp/pipeline-tool.tsx:132 |
| BR-07 | Khi đang clone: nút "Cancel", "Clone to dev" và ô nhập bị khoá, modal không đóng được | M2 | AC-M2.4 | fe/src/ui/components/works/sapp/pipeline-tool.tsx:185,434-439,448,456,486 |
| BR-08 | Clone thành công → đóng modal, popup "Clone completed"; danh sách đang xem (prod) không tải lại | M2 - action A2 | AC-M2.1 | fe/src/ui/components/works/sapp/pipeline-tool.tsx:133-145 |
⚠️ Observed (không phải BR): popup "Clone completed … is now available in the dev portal" kể cả khi không tạo gì — AC-M2.3, OQ-H-14. Danh sách không làm mới khi đổi môi trường — EC-M1.1, OQ-H-15.
4. Design ​
a. Mối liên hệ giữa các màn & User Flow ​
text
[M1: Pipeline manager, Environment = Prod, danh sách đã tải] (US-H04)
↓ bấm "Clone to dev" trên một pipeline
[M2: Modal "Clone pipeline to dev"]
├─ Cancel ───────────────────────────→ đóng modal
├─ dev chưa có label đích → tạo ─────→ popup "Clone completed", đóng modal
├─ dev đã có label đích → không tạo ─→ popup "Clone completed" (⚠️ Observed), đóng modal
└─ lỗi (12001/12002/12007/12008) ────→ popup "Failed to clone pipeline", modal vẫn mởLink flow chi tiết: N/A — as-built, không có Figma.
b. Chi tiết từng màn ​
Màn M1 - Pipeline manager (nút "Clone to dev") ​
| Field | Value |
|---|---|
| Figma frame | N/A |
| Trigger vào màn | Như US-H04 M1, với Environment = Prod và đã bấm "Load pipelines" |
| Mô tả ngắn | Mỗi thẻ pipeline prod có nút "Clone to dev" mở modal M2. Hiển thị danh sách: xem US-H04 M1 |
UI States ​
| State | Khi nào | Hiển thị | Figma frame |
|---|---|---|---|
| Default | Environment = Prod, danh sách đã tải | Nút "Clone to dev" trên mỗi thẻ có id | N/A |
| Loading | Đang clone | Nút "Clone to dev" trên mọi thẻ đổi thành "Cloning…"; mọi nút / ô chọn bị khoá | N/A |
| Has data | — | Như US-H04 M1 | N/A |
| Empty | Không có pipeline | "No pipelines found." — không có nút clone | N/A |
| Error | — | Xem M2 | N/A |
| Disabled | Environment = Dev | Không có nút "Clone to dev" (BR-01) | N/A |
Fields ​
N/A — M1 không có field nhập riêng cho US này; Environment / Object type mô tả ở US-H04 M1.
Filter / Search / Sort ​
Xem US-H04 M1 — không đổi.
Actions ​
A1 - Mở modal Clone to dev ​
| Item | Description |
|---|---|
| Trigger | Bấm "Clone to dev" trên một thẻ pipeline (chỉ có khi Prod) |
| Behavior | Mở M2 với pipeline nguồn = thẻ đó, ô label điền sẵn label nguồn (BR-02). Không gọi API, không ghi |
| Success Result | M2 mở |
Error cases:
| Case | Expected Handling |
|---|---|
| Pipeline không có id | Nút bị khoá (US-H04 BR-06) |
Acceptance Criteria của màn M1 ​
AC-M1.1 - Nút chỉ có ở Prod ​
gherkin
Given danh sách pipeline đã tải với Environment = Prod
Then mỗi thẻ pipeline có nút "Clone to dev"Maps to:
- Business Rule: BR-01
AC-M1.2 - Không có ở Dev ​
gherkin
Given Environment = Dev và danh sách đã tải
Then không thẻ nào có nút "Clone to dev"Maps to:
- Business Rule: BR-01
Negative AC / Edge Cases của màn M1 ​
| ID | Tình huống | Hành vi mong đợi |
|---|---|---|
| EC-M1.1 | Tải danh sách ở Dev, đổi Environment sang Prod mà không tải lại | ⚠️ Observed — nút "Clone to dev" hiện trên danh sách dev; clone sẽ đọc nguồn ở prod theo id của pipeline dev (thường ra 12007; nếu id trùng một pipeline prod thì clone pipeline prod đó) (fe/src/ui/components/works/sapp/pipeline-tool.tsx:269,317-328). Chưa chạy thử — OQ-H-15 |
Màn M2 - Modal "Clone pipeline to dev" ​
| Field | Value |
|---|---|
| Figma frame | N/A |
| Trigger vào màn | A1 ở M1 |
| Mô tả ngắn | Nhập label đích (tuỳ chọn) rồi xác nhận clone. Chú thích trong modal: "A pipeline with this label is created in the dev portal, reusing the source stages. Leave it empty to keep the prod label. If dev already has a pipeline with the same label it is returned unchanged." (fe/src/ui/components/works/sapp/pipeline-tool.tsx:490-497) |
UI States ​
| State | Khi nào | Hiển thị | Figma frame |
|---|---|---|---|
| Default | Vừa mở | Tiêu đề "Clone pipeline to dev", phụ đề "Source: <label nguồn> · into dev portal", ô "New label (optional)" = label nguồn (placeholder = label nguồn), nút "Cancel", "Clone to dev" | N/A |
| Loading | Đang clone | Nút "Cloning…"; Cancel, ô nhập, nút đóng modal không tác dụng (BR-07) | N/A |
| Has data | N/A — thành công thì modal đóng | — | N/A |
| Empty | Ô label trống | Hợp lệ — dùng label nguồn (BR-03) | N/A |
| Error | API lỗi | Popup "Failed to clone pipeline"; modal vẫn mở với label đã nhập | N/A |
| Disabled | Đang clone | Như Loading | N/A |
Fields ​
| Field | Required | Type | Default | Format | Validation | Error Message | Visibility | Depends On |
|---|---|---|---|---|---|---|---|---|
| New label (optional) | No | Text | Label pipeline nguồn | Cắt khoảng trắng hai đầu; trống → không gửi label | BR-03, BR-04 | — | Always | Là khoá so khớp tồn tại ở dev (BR-04) |
Filter / Search / Sort ​
N/A — modal xác nhận.
Actions ​
A2 - Clone to dev (xác nhận) ​
| Item | Description |
|---|---|
| Trigger | Bấm "Clone to dev" trong modal hoặc nhấn Enter trong ô label |
| Behavior | Gọi POST /api/v1/sapp/dev/hubspot/{deals|tickets}/pipelines/clone-prod/:pipelineId (label nếu có). BE: (1) đọc pipeline nguồn ở HubSpot portal prod; (2) đọc danh sách pipeline ở portal dev; (3) có pipeline cùng label đích → trả nguyên (BR-04); chưa có → ghi: tạo pipeline mới kèm stage ở HubSpot portal dev (BR-05). Không ghi prod |
| Success Result | Đóng modal; popup "Clone completed — Pipeline "<label>" is now available in the dev portal."; danh sách không tải lại (BR-08) |
Error cases:
| Case | Expected Handling |
|---|---|
| Pipeline nguồn không có ở prod | Popup "Failed to clone pipeline" — "HubSpot pipeline not found (12007)" |
| Đọc danh sách dev lỗi | Popup … "HubSpot API request failed (12002)" |
| HubSpot dev từ chối tạo | Popup … "Failed to clone HubSpot pipeline (12008)" |
| Thiếu token prod / dev | Popup … "(12001)" (NFR-H-02) |
A3 - Cancel ​
| Item | Description |
|---|---|
| Trigger | Bấm "Cancel" hoặc đóng modal khi không đang clone |
| Behavior | Đóng modal, xoá label đã nhập; không gọi API |
| Success Result | Về M1 |
Error cases:
| Case | Expected Handling |
|---|---|
| Đang clone | Không đóng được (BR-07) |
Acceptance Criteria của màn M2 ​
AC-M2.1 - Clone tạo pipeline mới ở dev ​
gherkin
Given portal prod có pipeline Deal "Sales Pipeline" với 5 stage, dev chưa có pipeline label "Sales Pipeline"
When người dùng bấm "Clone to dev" trên thẻ đó, giữ nguyên label điền sẵn và bấm "Clone to dev" trong modal
Then portal dev có pipeline mới "Sales Pipeline" với 5 stage cùng label, thứ tự và metadata (id mới)
And portal prod không bị thay đổi
And modal đóng, hiện popup "Clone completed — Pipeline "Sales Pipeline" is now available in the dev portal."
And danh sách prod đang xem không tải lạiMaps to:
- Business Rule: BR-02, BR-05, BR-08
- Field/Action: New label / A2
AC-M2.2 - Để trống label ​
gherkin
Given modal clone của pipeline "Sales Pipeline"
When người dùng xoá hết ô label (hoặc chỉ để khoảng trắng) và xác nhận
Then pipeline đích dùng label "Sales Pipeline"Maps to:
- Business Rule: BR-03
AC-M2.3 - Dev đã có label đích (hành vi hiện tại) ​
gherkin
Given dev đã có pipeline Deal label "Sales Pipeline" (3 stage), prod có 5 stage
When người dùng clone "Sales Pipeline" với label mặc định
Then không có pipeline nào được tạo hay sửa ở dev (vẫn 3 stage)
And ⚠️ Observed: popup vẫn "Clone completed — Pipeline "Sales Pipeline" is now available in the dev portal." (OQ-H-14)Maps to:
- Business Rule: BR-04
- NFR: NFR-H-07
- OQ: OQ-H-14
AC-M2.4 - Khoá khi đang clone ​
gherkin
Given người dùng đã bấm xác nhận clone
When yêu cầu chưa có kết quả
Then nút hiện "Cloning…", ô label và "Cancel" bị khoá, modal không đóng đượcMaps to:
- Business Rule: BR-07
Negative AC / Edge Cases của màn M2 ​
| ID | Tình huống | Hành vi mong đợi |
|---|---|---|
| EC-M2.1 | Pipeline nguồn bị xoá ở prod sau khi tải danh sách | Popup "Failed to clone pipeline" — "(12007)"; modal vẫn mở (BR-06) |
| EC-M2.2 | HubSpot dev từ chối tạo (vd vượt giới hạn số pipeline của portal) | Popup … "(12008)"; không có gì được tạo — nguyên nhân cụ thể suy đoán, chưa chạy thử |
| EC-M2.3 | Dev có "Sales pipeline", label đích là "Sales Pipeline" (khác hoa / thường) | So khớp phân biệt hoa / thường → tạo thêm pipeline mới ở dev (be/libs/modules/src/lib/hubspot/common.service.ts:1081-1083) — OQ-H-13 |
| EC-M2.4 | Dev có pipeline label có khoảng trắng thừa ở cuối | Chỉ label mới được cắt khoảng trắng, label ở dev thì không → không khớp, tạo thêm — OQ-H-13 |
| EC-M2.5 | Bấm clone hai lần cùng label | Lần hai rơi vào AC-M2.3 — không tạo trùng (NFR-H-07) |
5. Cross-feature AC ​
AC-X.1 - Tool bị gate chặn ​
gherkin
Given tool sapp.004 đang bị ẩn / tắt / khoá mã bí mật
When người dùng mở /works/sapp/tools/hs-pipeline
Then hành vi theo gate của nền tảng (US-P02)
And route clone pipeline vẫn gọi trực tiếp được, ghi vào portal dev (NFR-P-01, Overview §2.2)Maps to:
- REL-H-01 (Affects - Hub + gate tool)
AC-X.2 - Cần cả hai token ​
gherkin
Given SAPP_DEV_HUBSPOT_ACCESS_TOKEN chưa cấu hình
When người dùng xác nhận clone một pipeline prod
Then nhận lỗi 12001 và không có gì được tạo ở devMaps to:
- REL-H-02 (Affects - Cấu hình env_systems)