# CTO Report — Missing Shop Delete/Deactivate UI

> Date: 2026-03-14
> Reporter: QA Team (Automated Chrome Testing)
> Priority: P1 (Functional Gap)
> Status: RESOLVED
> Resolution: Implemented in commit 6263eeb (feat: add shop lifecycle management UI — deactivate & close shop)

---

## 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**: `Draft` → `Active` → `Inactive` (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

---

## Recommended Implementation

### Option A: Thêm "Danger Zone" vào ShopSettings.razor (Recommended)

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
