# API Documentation - Call Path Management

## Mục lục
1. [Quản lý đường dẫn (Call Path)](#1-quản-lý-đường-dẫn-call-path)
2. [Quản lý phiên bản (Call Path Version)](#2-quản-lý-phiên-bản-call-path-version)
3. [Models & Enums](#3-models--enums)
4. [Thay đổi so với phiên bản cũ (Breaking Changes)](#4-thay-đổi-so-với-phiên-bản-cũ-breaking-changes)

---

## 1. Quản lý đường dẫn (Call Path)

> [!IMPORTANT]
> **Cấu trúc dữ liệu mới**
> Từ phiên bản này, `CallPath` đã được tái cấu trúc:
> - Thuộc tính `Path` (fullPath) cũ đã được **thay thế** bằng `RelativePath` + `Domain` (từ `CallPathVersion`).
> - Mỗi `CallPath` bắt buộc thuộc về một `CallPathVersion` (chứa Version, Build, Domain).
> - Đường dẫn đầy đủ = `Domain` + `RelativePath` (ví dụ: `https://api.ladaexpress.vn` + `/api/Order/Search`).

### 1.1. Lấy tất cả đường dẫn

**Endpoint:** `GET /api/CallPath/GetAll`

**Authorization:** Yêu cầu đăng nhập (không yêu cầu quyền đặc biệt)

**Response:**
```json
[
  {
    "Id": 1,
    "Name": "Search Orders",
    "RelativePath": "/api/Order/Search",
    "CallPathVersionId": 1,
    "Version": "1.0.0",
    "Build": "101",
    "Domain": "https://api.ladaexpress.vn",
    "Description": "Tìm kiếm đơn hàng"
  },
  {
    "Id": 2,
    "Name": "Get Order By ID",
    "RelativePath": "/api/Order/GetById",
    "CallPathVersionId": 1,
    "Version": "1.0.0",
    "Build": "101",
    "Domain": "https://api.ladaexpress.vn",
    "Description": "Lấy chi tiết đơn hàng"
  }
]
```

---

### 1.2. Tìm kiếm đường dẫn

**Endpoint:** `POST /api/CallPath/Search`

**Authorization:** `Founder`

**Request Body:**
```json
{
  "Pagination": {
    "PageIndex": 1,
    "PageSize": 15
  },
  "Search": {
    "PredicateObject": {
      "Keyword": "Order",
      "Version": "1.0.0",
      "Build": "101",
      "CreatedStart": "2026-01-01T00:00:00+07:00",
      "CreatedEnd": "2026-03-31T23:59:59+07:00"
    }
  },
  "Sort": {
    "Predicate": "Id",
    "Reverse": true
  }
}
```

**Search Parameters:**
- `Keyword` (string, optional): Tìm kiếm theo `Name`, `RelativePath`, `Description`, `Version`, `Build`, `Domain`
- `Version` (string, optional): Lọc chính xác theo số phiên bản (ví dụ: `"1.0.0"`)
- `Build` (string, optional): Lọc chính xác theo số build (ví dụ: `"101"`)
- `CreatedStart` (DateTimeOffset, optional): Lọc từ ngày tạo
- `CreatedEnd` (DateTimeOffset, optional): Lọc đến ngày tạo

> [!NOTE]
> **Bộ lọc Version & Build**
> - `Keyword` tìm kiếm mờ (contains) trên nhiều trường, bao gồm cả Version/Build/Domain.
> - `Version` và `Build` lọc khớp chính xác (exact match) riêng biệt.
> - `CreatedStart` và `CreatedEnd` phải truyền cùng nhau. Hệ thống tự động áp dụng `StartOfDay()` / `EndOfDay()`.

**Response:**
```json
{
  "Items": [
    {
      "Id": 1,
      "Name": "Search Orders",
      "RelativePath": "/api/Order/Search",
      "CallPathVersionId": 1,
      "Version": "1.0.0",
      "Build": "101",
      "Domain": "https://api.ladaexpress.vn",
      "Description": "Tìm kiếm đơn hàng"
    }
  ],
  "TotalRecord": 1,
  "NumberOfPages": 1
}
```

---

### 1.3. Lấy chi tiết đường dẫn theo ID

**Endpoint:** `GET /api/CallPath/GetById?id={id}`

**Authorization:** `Founder`

**Query Parameters:**
- `id` (int, required): ID của CallPath

**Response:**
```json
{
  "Id": 1,
  "Name": "Search Orders",
  "RelativePath": "/api/Order/Search",
  "CallPathVersionId": 1,
  "Version": "1.0.0",
  "Build": "101",
  "Domain": "https://api.ladaexpress.vn",
  "Description": "Tìm kiếm đơn hàng",
  "UpdatedBy": 1,
  "UpdatedByUserName": "admin",
  "CreatedTime": "2026-01-15T10:30:00+07:00",
  "UpdatedTime": "2026-02-20T14:20:00+07:00"
}
```

> [!NOTE]
> **Response khi không tìm thấy**
> Nếu `id <= 0` hoặc không tìm thấy bản ghi, API trả về một object rỗng với `Id = 0`.

---

### 1.4. Tạo hoặc cập nhật đường dẫn

**Endpoint:** `POST /api/CallPath/CreateOrUpdate`

**Authorization:** `Founder`

**Request Body (Tạo mới):**
```json
{
  "Id": 0,
  "Name": "Search Orders",
  "RelativePath": "/api/Order/Search",
  "CallPathVersionId": 1,
  "Description": "Tìm kiếm đơn hàng"
}
```

**Request Body (Cập nhật):**
```json
{
  "Id": 1,
  "Name": "Search Orders V2",
  "RelativePath": "/api/v2/Order/Search",
  "CallPathVersionId": 2,
  "Description": "Tìm kiếm đơn hàng phiên bản mới"
}
```

**Request Parameters:**
- `Id` (int, required): ID bản ghi (0 = tạo mới, >0 = cập nhật)
- `Name` (string, required): Tên đường dẫn
- `RelativePath` (string, required): Đường dẫn tương đối (ví dụ: `/api/Order/Search`)
- `CallPathVersionId` (int, required): ID phiên bản (tham chiếu tới bảng `CallPathVersion`)
- `Description` (string, optional): Mô tả

> [!IMPORTANT]
> **CallPathVersionId là bắt buộc**
> Mỗi `CallPath` phải thuộc về một `CallPathVersion`. Frontend cần hiển thị dropdown để chọn phiên bản khi tạo/cập nhật.
> Các trường `Version`, `Build`, `Domain` là **read-only** — chúng được tự động lấy từ `CallPathVersion` khi đọc dữ liệu, không cần gửi khi tạo/cập nhật.

**Response (Thành công):**
```json
{
  "Result": 1,
  "Message": ""
}
```

**Response (Thất bại):**
```json
{
  "Result": 2,
  "Message": "Không xác định được người dùng 0 - "
}
```

---

### 1.5. Xóa đường dẫn

**Endpoint:** `DELETE /api/CallPath/Delete?id={id}`

**Authorization:** `Founder`

**Query Parameters:**
- `id` (int, required): ID của CallPath cần xóa

**Response (Thành công):**
```json
{
  "Result": 1,
  "Message": ""
}
```

**Response (Không tìm thấy):**
```json
{
  "Result": 2,
  "Message": "Không tìm thấy danh mục yêu cầu"
}
```

**Response (Lỗi hệ thống):**
```json
{
  "Result": 3,
  "Message": "Hệ thống không thể thực hiện yêu cầu lúc này, vui lòng thử lại sau!"
}
```

---

## 2. Quản lý phiên bản (Call Path Version)

> [!NOTE]
> **Controller mới: `CallPathVersionController`**
> Các API dưới đây được phục vụ bởi controller riêng tại route `/api/CallPathVersion`.
> Frontend dùng API GetAll của CallPathVersion để hiển thị dropdown khi tạo/cập nhật CallPath.

### 2.1. Lấy tất cả phiên bản (dùng cho dropdown)

**Endpoint:** `GET /api/CallPathVersion/GetAll`

**Authorization:** Yêu cầu đăng nhập (không yêu cầu quyền đặc biệt)

**Response:**
```json
[
  {
    "Id": 1,
    "Version": "1.0.0",
    "Build": "101",
    "Domain": "https://api.ladaexpress.vn",
    "Description": "Phiên bản chính thức",
    "CallPathCount": 15
  },
  {
    "Id": 2,
    "Version": "2.0.0",
    "Build": "200",
    "Domain": "https://api-v2.ladaexpress.vn",
    "Description": "Phiên bản mới",
    "CallPathCount": 3
  }
]
```

**Response Fields:**
- `CallPathCount` (int): Số lượng đường dẫn (CallPath) đang thuộc phiên bản này

---

### 2.2. Tìm kiếm phiên bản

**Endpoint:** `POST /api/CallPathVersion/Search`

**Authorization:** `Founder`

**Request Body:**
```json
{
  "Pagination": {
    "PageIndex": 1,
    "PageSize": 15
  },
  "Search": {
    "PredicateObject": {
      "Keyword": "1.0.0"
    }
  },
  "Sort": {
    "Predicate": "Id",
    "Reverse": true
  }
}
```

**Search Parameters:**
- `Keyword` (string, optional): Tìm kiếm theo `Version`, `Build`, `Domain`, `Description`

**Response:**
```json
{
  "Items": [
    {
      "Id": 1,
      "Version": "1.0.0",
      "Build": "101",
      "Domain": "https://api.ladaexpress.vn",
      "Description": "Phiên bản chính thức",
      "CallPathCount": 15
    }
  ],
  "TotalRecord": 1,
  "NumberOfPages": 1
}
```

---

### 2.3. Lấy chi tiết phiên bản theo ID

**Endpoint:** `GET /api/CallPathVersion/GetById?id={id}`

**Authorization:** `Founder`

**Query Parameters:**
- `id` (int, required): ID của CallPathVersion

**Response:**
```json
{
  "Id": 1,
  "Version": "1.0.0",
  "Build": "101",
  "Domain": "https://api.ladaexpress.vn",
  "Description": "Phiên bản chính thức",
  "UpdatedBy": 1,
  "UpdatedByUserName": "admin",
  "CreatedTime": "2026-01-15T10:30:00+07:00",
  "UpdatedTime": "2026-02-20T14:20:00+07:00"
}
```

---

### 2.4. Tạo hoặc cập nhật phiên bản

**Endpoint:** `POST /api/CallPathVersion/CreateOrUpdate`

**Authorization:** `Founder`

**Request Body (Tạo mới):**
```json
{
  "Id": 0,
  "Version": "2.0.0",
  "Build": "200",
  "Domain": "https://api-v2.ladaexpress.vn",
  "Description": "Phiên bản API mới"
}
```

**Request Body (Cập nhật):**
```json
{
  "Id": 1,
  "Version": "1.0.1",
  "Build": "102",
  "Domain": "https://api.ladaexpress.vn",
  "Description": "Cập nhật domain mới"
}
```

**Request Parameters:**
- `Id` (int, required): ID bản ghi (0 = tạo mới, >0 = cập nhật)
- `Version` (string, required): Số phiên bản (ví dụ: `1.0.0`)
- `Build` (string, required): Số build (ví dụ: `101`)
- `Domain` (string, required): Domain cơ sở (ví dụ: `https://api.ladaexpress.vn`)
- `Description` (string, optional): Mô tả phiên bản

> [!IMPORTANT]
> **Validation: Version + Build phải unique**
> Không thể tạo 2 bản ghi có cùng `Version` và `Build`. API sẽ trả về lỗi nếu trùng.

**Response (Thành công):**
```json
{
  "Result": 1,
  "Message": ""
}
```

**Response (Trùng Version + Build):**
```json
{
  "Result": 2,
  "Message": "Phiên bản 1.0.0 - Build 101 đã tồn tại"
}
```

---

### 2.5. Xóa phiên bản

**Endpoint:** `DELETE /api/CallPathVersion/Delete?id={id}`

**Authorization:** `Founder`

**Query Parameters:**
- `id` (int, required): ID của CallPathVersion cần xóa

> [!IMPORTANT]
> **Không thể xóa phiên bản đang có đường dẫn sử dụng**
> Nếu phiên bản đang có CallPath liên kết, API sẽ từ chối xóa và trả về thông báo lỗi.

**Response (Thành công):**
```json
{
  "Result": 1,
  "Message": ""
}
```

**Response (Đang có CallPath sử dụng):**
```json
{
  "Result": 2,
  "Message": "Không thể xóa phiên bản đang có 15 đường dẫn sử dụng"
}
```

---

## 3. Models & Enums

### CallPathItem (Danh sách - dùng cho Search & GetAll)

| Tên trường         | Kiểu dữ liệu | Mô tả                                      |
|--------------------|---------------|---------------------------------------------|
| `Id`               | int           | ID bản ghi                                  |
| `Name`             | string        | Tên đường dẫn                               |
| `RelativePath`     | string        | Đường dẫn tương đối (ví dụ: `/api/Order/Search`) |
| `CallPathVersionId`| int           | ID phiên bản                                |
| `Version`          | string        | Số phiên bản (ví dụ: `1.0.0`) — **read-only** |
| `Build`            | string        | Số build (ví dụ: `101`) — **read-only**     |
| `Domain`           | string        | Domain cơ sở (ví dụ: `https://api.ladaexpress.vn`) — **read-only** |
| `Description`      | string        | Mô tả                                       |

### CallPathModel (Chi tiết - dùng cho GetById & CreateOrUpdate)

Kế thừa từ `BaseModel<int>`, bao gồm các trường từ `CallPathItem` cộng thêm:

| Tên trường          | Kiểu dữ liệu    | Mô tả                        |
|---------------------|------------------|-------------------------------|
| `CreatedTime`       | DateTimeOffset?  | Ngày tạo                     |
| `CreatedTimeDisplay`| string           | Ngày tạo (dd/MM/yyyy HH:mm)  |
| `UpdatedTime`       | DateTimeOffset?  | Ngày cập nhật                 |
| `UpdatedTimeDisplay`| string           | Ngày cập nhật (dd/MM/yyyy HH:mm) |
| `UpdatedBy`         | int              | ID người cập nhật             |
| `UpdatedByUserName` | string           | Tên người cập nhật            |
| `CreatedBy`         | int              | ID người tạo                  |
| `CreatedByUserName` | string           | Tên người tạo                 |

### CallPathVersionItem (Danh sách - dùng cho Search & GetAll)

| Tên trường     | Kiểu dữ liệu | Mô tả                                      |
|----------------|---------------|---------------------------------------------|
| `Id`           | int           | ID phiên bản                                |
| `Version`      | string        | Số phiên bản (ví dụ: `1.0.0`)              |
| `Build`        | string        | Số build (ví dụ: `101`)                    |
| `Domain`       | string        | Domain cơ sở (ví dụ: `https://api.ladaexpress.vn`) |
| `Description`  | string        | Mô tả phiên bản                            |
| `CallPathCount`| int           | Số lượng đường dẫn thuộc phiên bản này      |

### CallPathVersionModel (Chi tiết - dùng cho GetById & CreateOrUpdate)

Kế thừa từ `BaseModel<int>`, bao gồm các trường từ `CallPathVersionItem` (trừ `CallPathCount`) cộng thêm:

| Tên trường          | Kiểu dữ liệu    | Mô tả                        |
|---------------------|------------------|-------------------------------|
| `CreatedTime`       | DateTimeOffset?  | Ngày tạo                     |
| `CreatedTimeDisplay`| string           | Ngày tạo (dd/MM/yyyy HH:mm)  |
| `UpdatedTime`       | DateTimeOffset?  | Ngày cập nhật                 |
| `UpdatedTimeDisplay`| string           | Ngày cập nhật (dd/MM/yyyy HH:mm) |
| `UpdatedBy`         | int              | ID người cập nhật             |
| `UpdatedByUserName` | string           | Tên người cập nhật            |
| `CreatedBy`         | int              | ID người tạo                  |
| `CreatedByUserName` | string           | Tên người tạo                 |

### BaseResult

| Tên trường | Kiểu dữ liệu | Mô tả                                    |
|------------|---------------|-------------------------------------------|
| `Result`   | int           | 1 = Thành công, 2 = Thất bại, 3 = Lỗi hệ thống |
| `Message`  | string        | Thông điệp kết quả                       |

---

## 4. Thay đổi so với phiên bản cũ (Breaking Changes)

> [!CAUTION]
> **Breaking Changes - Frontend cần cập nhật**
> Các thay đổi dưới đây **BẮT BUỘC** frontend phải cập nhật để tương thích.

### 4.1. Thuộc tính `Path` đã bị xóa

| Trước (Cũ)     | Sau (Mới)                           |
|-----------------|-------------------------------------|
| `Path` (fullPath) | `RelativePath` + `Domain` (từ Version) |

**Cách tính đường dẫn đầy đủ:**
```
FullPath = Domain + RelativePath
// Ví dụ: "https://api.ladaexpress.vn" + "/api/Order/Search"
```

### 4.2. Các trường mới cần hiển thị

Frontend cần hiển thị thêm các cột/trường sau trong danh sách và form chi tiết:

| Trường mới          | Loại           | Mô tả                                      |
|---------------------|----------------|---------------------------------------------|
| `RelativePath`      | Input/Display  | Đường dẫn tương đối (thay thế `Path` cũ)   |
| `CallPathVersionId` | Dropdown       | ID phiên bản (chọn từ danh sách phiên bản)  |
| `Version`           | Display (chỉ xem) | Số phiên bản — tự động lấy từ CallPathVersion |
| `Build`             | Display (chỉ xem) | Số build — tự động lấy từ CallPathVersion    |
| `Domain`            | Display (chỉ xem) | Domain — tự động lấy từ CallPathVersion      |

### 4.3. Bộ lọc mới trong Search

Frontend có thể thêm các bộ lọc mới vào giao diện tìm kiếm:

| Bộ lọc     | Kiểu      | Mô tả                                        |
|------------|-----------|-----------------------------------------------|
| `Version`  | Dropdown/Input | Lọc chính xác theo phiên bản              |
| `Build`    | Dropdown/Input | Lọc chính xác theo build                  |

> [!TIP]
> **Gợi ý triển khai Frontend**
> - Khi tạo/cập nhật `CallPath`, nên cung cấp dropdown để chọn `CallPathVersion`.
> - Khi hiển thị danh sách, ghép `Domain + RelativePath` để hiển thị đường dẫn đầy đủ cho người dùng dễ nhìn.
> - Các trường `Version`, `Build`, `Domain` là **read-only** trong form tạo/cập nhật — chúng tự động thay đổi khi chọn `CallPathVersionId` khác.
