Xem Chi Tiết Hợp Đồng Tùy Chỉnh

Mô Tả Tổng Quan

Tính năng Xem Chi Tiết Hợp Đồng Tùy Chỉnh cho phép quản trị viên lấy thông tin đầy đủ về một hợp đồng tùy chỉnh cụ thể, bao gồm tất cả dữ liệu và lịch sử liên quan.

Điều Kiện Tiên Quyết

  • Người dùng phải được xác thực với vai trò quản trị viên (SuperAdmin hoặc AdminStaff)
  • Hợp đồng tùy chỉnh phải tồn tại

Phụ Thuộc

  • Không có (thao tác chỉ đọc)

Liên Kết Swagger

API: Xem Chi Tiết Hợp Đồng Tùy Chỉnh

Tài Liệu Trường Hợp

Trường Hợp 1: Lấy Chi Tiết Hợp Đồng Thành Công

Mô Tả

Quản trị viên lấy thành công thông tin chi tiết về một hợp đồng tùy chỉnh cụ thể, bao gồm tất cả các mối quan hệ và siêu dữ liệu.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant Controller as CustomContractController
    participant Repository as CustomContractRepository
    participant Database
    
    Note over Admin,Database: GET /api/v1/admin/custom-contracts/{id}
    
    rect rgb(200, 255, 200)
    Note right of Admin: Happy Case Flow
    
    Admin->>Controller: GET request with contract ID
    
    rect rgb(200, 255, 255)
    Note right of Controller: Data Retrieval
    Controller->>Repository: findById(contractId)
    Repository->>Database: SELECT * FROM custom_contracts WHERE id = ?
    Database-->>Repository: Return contract record
    Repository->>Repository: Load relationships (eager loading)
    Repository->>Database: SELECT related records
    Database-->>Repository: Return related data
    Repository-->>Controller: Return contract with all relations
    end
    
    Controller-->>Admin: 200 OK (contract_data)
    end
    
    rect rgb(255, 200, 200)
    Note right of Admin: Error Scenarios
    rect rgb(255, 230, 230)
    alt Contract Not Found
        Repository-->>Controller: Null returned
        Controller-->>Admin: 404 Not Found
    else Database Error
        Database-->>Repository: Database error
        Repository-->>Controller: Error result
        Controller-->>Admin: 400 Bad Request
    end
    end
    end

Các Bước

Bước 1: Lấy Hợp Đồng

  • Mô Tả: Lấy bản ghi hợp đồng với tất cả các mối quan hệ
  • Yêu Cầu: GET /api/v1/admin/custom-contracts/{id}
  • Ủy Quyền: Người dùng phải có vai trò SuperAdmin hoặc AdminStaff
  • Tham Số Đường Dẫn:
    • id: ID hợp đồng tùy chỉnh (bắt buộc, số nguyên)

Bước 2: Tải Các Mối Quan Hệ

  • Mô Tả: Tải tích cực tất cả dữ liệu liên quan
  • Các Mối Quan Hệ Được Tải:
    • group: Thông tin nhóm với các thành viên
    • group.groupMembers: Tất cả thành viên nhóm
    • packagePlan: Chi tiết gói cơ bản
    • subscription: Dữ liệu đăng ký liên quan
  • Thao Tác Cơ Sở Dữ Liệu:
    • SELECT từ custom_contracts
    • LEFT JOIN với groups, package_plans, subscriptions
    • Truy vấn bổ sung cho thành viên nhóm

Bước 3: Trả Về Phản Hồi

  • Mô Tả: Trả về dữ liệu hợp đồng đầy đủ
  • Dữ Liệu Phản Hồi:
    • Tất cả các trường hợp đồng
    • Chi tiết nhóm (name, status, created_by)
    • Danh sách thành viên nhóm
    • Chi tiết gói (nếu có)
    • Chi tiết đăng ký (slug, status, email)
    • Siêu dữ liệu Stripe (session_id, price_id, subscription_item_id)
    • Giới hạn sử dụng (tất cả các trường max_*)
    • Thông tin ngày (starts_at, ends_at, created_at, updated_at)
  • Thông Báo Thành Công: "カスタムプランの詳細取得に成功しました" (Đã lấy thành công chi tiết hợp đồng)

Database Related Tables & Fields

erDiagram
    custom_contracts {
        bigint id PK
        bigint subscription_id FK
        bigint package_plan_id FK
        bigint group_id FK
        bigint user_id FK
        string code
        string billing_interval
        string currency
        integer amount
        string status
        string provider_checkout_session_id
        string provider_price_id
        string provider_subscription_item_id
        timestamp starts_at
        timestamp ends_at
        integer max_member
        integer max_product_group
        integer max_product
        integer max_category
        integer max_search_query
        integer max_viewpoint
        string data_visible
        tinyint api_available
        timestamp created_at
        timestamp updated_at
    }
    groups {
        bigint id PK
        string name
        bigint created_by FK
        integer status
        timestamp created_at
        timestamp updated_at
    }
    group_members {
        bigint id PK
        bigint group_id FK
        bigint user_id FK
        string role
        timestamp created_at
    }
    subscriptions {
        bigint id PK
        string slug
        bigint package_plan_id FK
        bigint group_id FK
        string status
        string email
        string payment_provider_customer_id
        timestamp created_at
        timestamp updated_at
    }
    package_plans {
        bigint id PK
        bigint package_id FK
        string name
        string billing_interval
        integer amount
        timestamp created_at
        timestamp updated_at
    }
    users {
        bigint id PK
        string name
        string email
        timestamp created_at
    }
    
    custom_contracts ||--|| groups : belongs_to
    custom_contracts ||--o| package_plans : based_on
    custom_contracts ||--o| subscriptions : has
    custom_contracts ||--o| users : managed_by
    groups ||--o{ group_members : has
    group_members ||--|| users : belongs_to

Error Handling

  • Log: Errors are logged via logThrow() method
  • Error Detail:
Status Code Error Message Description
404 "カスタムプランが見つかりませんでした" When contract with specified ID doesn't exist
400 Generic error with exception message For unexpected database errors

Additional Notes

Response Structure

The response includes comprehensive contract information:

  • Contract Details: code, status, amounts, intervals, dates
  • Stripe Integration: session_id, price_id, subscription_item_id
  • Usage Limits: All max_* fields (null means unlimited)
  • Related Group: Full group details with member list
  • Related Subscription: Complete subscription information
  • Related Package Plan: Base plan used as template
Group Members Information
  • Includes all members of the contract's group
  • Shows member roles and permissions
  • Useful for admin to understand who has access
Usage Limits Display
  • null values indicate unlimited usage for that resource
  • 0 values indicate feature is disabled
  • Positive integers show the specific limit
Status Information

Contract status indicates lifecycle stage:

  • draft: Created but not yet offered
  • offered: Payment link sent, awaiting payment
  • active: Payment successful, contract in effect
  • expired: Contract end date has passed
  • cancelled: Contract terminated before expiration
Stripe Metadata
  • provider_checkout_session_id: Used to track payment session
  • provider_price_id: Stripe price ID for subscription
  • provider_subscription_item_id: Stripe subscription item for management
Performance Considerations
  • Single query with eager loading prevents N+1 problem
  • Indexed lookup on contract ID (primary key)
  • Fast response time (typically < 100ms)
  • Consider caching for frequently accessed contracts
Response Format Example
{
  "status": true,
  "message": "カスタムプランの詳細取得に成功しました",
  "data": {
    "id": 1,
    "subscription_id": 10,
    "package_plan_id": 3,
    "group_id": 5,
    "user_id": 15,
    "code": "CUSTOM-2026-001",
    "billing_interval": "month",
    "currency": "jpy",
    "amount": 150000,
    "status": "active",
    "provider_checkout_session_id": "cs_test_abc123",
    "provider_price_id": "price_abc123",
    "provider_subscription_item_id": "si_abc123",
    "starts_at": "2026-02-01T00:00:00Z",
    "ends_at": "2027-02-01T00:00:00Z",
    "max_member": 10,
    "max_product_group": 5,
    "max_product": 100,
    "max_category": 20,
    "max_search_query": 50,
    "max_viewpoint": 30,
    "data_visible": "private",
    "api_available": 1,
    "created_at": "2026-01-28T10:30:00Z",
    "updated_at": "2026-01-28T15:45:00Z",
    "group": {
      "id": 5,
      "name": "Test Corporation",
      "status": 1,
      "created_by": 12,
      "group_members": [
        {
          "id": 1,
          "user_id": 15,
          "role": "owner",
          "user": {
            "id": 15,
            "name": "John Doe",
            "email": "john@example.com"
          }
        }
      ]
    },
    "subscription": {
      "id": 10,
      "slug": "sub_abc123",
      "status": "active",
      "email": "billing@example.com",
      "payment_provider_customer_id": "cus_abc123"
    },
    "package_plan": {
      "id": 3,
      "name": "Enterprise Plan",
      "billing_interval": "month",
      "amount": 100000
    }
  }
}