Files
pos-system/CTO_REPORT_SHOP_DELETE.md
Ho Ngoc Hai 6263eeb05d feat: add shop lifecycle management UI — deactivate & close shop
- Add "Danger Zone" section to ShopSettings with deactivate/close actions
- CloseShopConfirmDialog: type shop name to confirm (GitHub-style)
- BFF: proxy endpoints POST /shops/{id}/deactivate and /close
- MerchantApiService: DeactivateShopAsync(), CloseShopAsync()
- CTO report documenting the gap and implementation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 07:35:30 +07:00

5.6 KiB

CTO Report — Missing Shop Delete/Deactivate UI

Date: 2026-03-14 Reporter: QA Team (Automated Chrome Testing) Priority: P1 (Functional Gap) Status: OPEN


Issue Summary

Trang Thiết lập cửa hàng (/admin/shop/{shopId}/settings) không có chức năng xóa, đóng, hoặc vô hiệu hóa cửa hàng. Admin tạo shop mới nhưng không thể xóa/đóng shop từ UI.

URL kiểm tra: http://localhost:3001/admin/shop/0d25b74e-f855-4fba-9ca4-baa2c89e4811/settings


Current State

UI (ShopSettings.razor) — Thiếu hoàn toàn

Trang Thiết lập chỉ có 3 section:

  1. Thông tin cửa hàng — Tên, Ngành hàng (read-only)
  2. Giờ & ngày hoạt động — Giờ mở/đóng, ngày kinh doanh
  3. Tính năng cửa hàng — 6 toggles (tồn kho, bàn, bếp, đặt lịch, vận chuyển, giao hàng)

Không có: Nút xóa, đóng, vô hiệu hóa, hoặc lưu trữ cửa hàng.

Backend (merchant-service-net) — Đã có đầy đủ

API endpoints đã implement và có handler + validation:

Action Endpoint Domain Method Status Transition
Vô hiệu hóa POST /api/v1/shops/{shopId}/deactivate Shop.SetInactive() Active → Inactive (reversible)
Đóng cửa hàng POST /api/v1/shops/{shopId}/close Shop.Close() Any → Closed (permanent)
Xóa mềm — (no controller endpoint) Shop.Delete() Sets _isDeleted = true

Authorization: Handlers validate merchant ownership via JWT claims trước khi thực hiện.

Domain Events: ShopClosedDomainEvent được raise khi đóng shop.

Shop Status Enum: DraftActiveInactive (reversible) → Closed (permanent)

Files liên quan

Layer File Notes
UI Pages/Admin/Shop/ShopSettings.razor Thiếu delete/deactivate UI
UI Pages/Admin/Shop/ShopPage.razor Chỉ có edit, không có delete
API ShopsController.cs (line 211-229) Endpoints /deactivate, /close đã có
Handler ShopStatusCommandHandlers.cs SetShopInactiveCommandHandler, CloseShopCommandHandler
Domain Shop.cs (line 298-319, 407-414) SetInactive(), Close(), Delete() methods
Domain ShopStatus.cs Status enum: Draft, Active, Inactive, Closed

Impact

  • User Experience: Admin không thể quản lý lifecycle cửa hàng (tạo → vô hiệu hóa → đóng/xóa)
  • Data Hygiene: Shop test/demo không thể xóa, gây lộn xộn trong danh sách shop
  • Business Logic: Merchant tạo shop mới cho mùa kinh doanh (ví dụ pop-up store) nhưng không thể đóng khi hết mùa

Thêm section cuối trang Thiết lập, tương tự GitHub repository settings:

┌─ Vùng nguy hiểm ──────────────────────────────────────┐
│                                                         │
│  Tạm ngưng cửa hàng                    [Tạm ngưng]     │
│  Shop sẽ không hiển thị trên POS.                       │
│  Có thể kích hoạt lại.                                  │
│                                                         │
│  ─────────────────────────────────────────────────────  │
│                                                         │
│  Đóng cửa hàng vĩnh viễn               [Đóng shop]     │
│  Không thể hoàn tác. Tất cả dữ liệu                    │
│  sẽ được lưu trữ nhưng shop sẽ bị khóa.                │
│                                                         │
│  ─────────────────────────────────────────────────────  │
│                                                         │
│  Xóa cửa hàng                          [Xóa shop]      │
│  Xóa mềm — shop sẽ không hiển thị                      │
│  nhưng dữ liệu vẫn được giữ trong DB.                  │
│                                                         │
└─────────────────────────────────────────────────────────┘

UX Requirements

  1. Confirmation dialog (MudDialog) với nhập tên shop để xác nhận
  2. Phân quyền: Chỉ Owner/Admin mới thấy Danger Zone
  3. Cascading effect notice: Thông báo impact lên staff, orders, inventory
  4. "Tạm ngưng" có nút "Kích hoạt lại" khi shop đang Inactive

API Calls (BFF)

  • Cần thêm BFF proxy endpoints trong WebClientTpos.Server:
    • POST /api/bff/shops/{shopId}/deactivate
    • POST /api/bff/shops/{shopId}/close
  • Forward đến MerchantService endpoints đã có

Effort Estimate

  • Frontend: ~2-3 hours (Danger Zone UI + confirmation dialogs)
  • BFF: ~30 minutes (proxy endpoints)
  • Backend: 0 (đã có đầy đủ)
  • Testing: ~1 hour (E2E verify)

Priority Justification

P1 (High) vì:

  • Backend đã implement đầy đủ → chỉ thiếu UI, effort thấp
  • Đây là chức năng quản lý cơ bản mà mọi merchant platform cần có
  • Ảnh hưởng trực tiếp đến trải nghiệm admin khi quản lý nhiều shop