List Custom Contracts
Overview Description
The List Custom Contracts feature provides administrators with the ability to view, search, and filter custom contracts with pagination. This endpoint supports multiple filter criteria and returns paginated results with related data.
Pre-conditions
- User must be authenticated as admin (SuperAdmin or AdminStaff role)
Dependencies
- None (read-only operation)
Swagger Link
Case Documentation
Case 1: Successful Contract List Retrieval
Description
Administrator successfully retrieves a paginated list of custom contracts with optional filters applied. Results include related subscription, group, user, and package plan data.
Sequence Diagram
sequenceDiagram
participant Admin
participant Controller as CustomContractController
participant Request as ListCustomContractRequest
participant Service as CustomContractService
participant Repository as CustomContractRepository
participant Database
Note over Admin,Database: GET /api/v1/admin/custom-contracts
rect rgb(200, 255, 200)
Note right of Admin: Happy Case Flow
Admin->>Controller: GET request with filters
rect rgb(200, 230, 255)
Note right of Controller: Request Validation
Controller->>Request: validate(params)
Request->>Request: Validate filter parameters
Request->>Request: Validate pagination params
Request-->>Controller: Validation passed
end
rect rgb(200, 255, 255)
Note right of Controller: Query Processing
Controller->>Service: list(validatedParams)
Service->>Repository: getQuery() with filters
Repository->>Repository: Build query with joins
Repository->>Repository: Apply status filter
Repository->>Repository: Apply group_name filter
Repository->>Repository: Apply other filters
Repository->>Database: Execute paginated query
Database-->>Repository: Return contract records
Repository-->>Service: Return paginated collection
Service-->>Controller: Return paginated results
end
Controller-->>Admin: 200 OK (contracts, meta, links)
end
Steps
Step 1: Request Validation
- Description: Validate filter and pagination parameters
- Request:
GET /api/v1/admin/custom-contracts?status=offered&group_name=test&page=1&per_page=10 - Authorization: User must have SuperAdmin or AdminStaff role
- Available Filters:
status: Filter by contract status (offered, active, draft, expired, cancelled, or 'all')group_id: Filter by specific group IDgroup_name: Filter by group name (partial match, case-insensitive)subscription_id: Filter by subscription IDuser_id: Filter by user IDcode: Filter by contract code (partial match)per_page: Items per page (default: 10)page: Page number (default: 1)
Step 2: Query Building
- Description: Build database query with filters and eager loading
- Action:
- Load relationships: subscription, group, user, packagePlan
- Apply status filter (if provided and not 'all')
- Apply group_id filter (if provided)
- Apply group_name filter with LIKE query (if provided)
- Apply subscription_id filter (if provided)
- Apply user_id filter (if provided)
- Apply code filter with LIKE query (if provided)
- Order by id DESC (latest first)
- Database Operations:
- SELECT from custom_contracts with LEFT JOINs
- WHERE clauses for filters
- ORDER BY id DESC
- LIMIT and OFFSET for pagination
Step 3: Execute Paginated Query
- Description: Execute query and return paginated results
- Action:
- Execute query with pagination
- Calculate total count
- Build pagination meta data
- Build pagination links (first, last, prev, next)
- Response Structure:
data: Array of contract resourcesmeta: Pagination metadata (total, per_page, current_page, last_page)links: Pagination links (first, last, prev, next)
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
timestamp created_at
timestamp updated_at
}
subscriptions {
bigint id PK
string slug
bigint package_plan_id FK
bigint group_id FK
string status
timestamp created_at
}
groups {
bigint id PK
string name
integer status
timestamp created_at
}
users {
bigint id PK
string name
string email
timestamp created_at
}
package_plans {
bigint id PK
string name
string billing_interval
timestamp created_at
}
custom_contracts ||--o| subscriptions : has
custom_contracts ||--|| groups : belongs_to
custom_contracts ||--o| users : managed_by
custom_contracts ||--o| package_plans : based_on
Error Handling
- Log: Errors are logged via
logThrow()method - Error Detail:
| Status Code | Error Message | Description |
|---|---|---|
| 422 | Validation error messages | When filter parameters are invalid |
| 400 | Generic error with exception message | For unexpected database errors |
Additional Notes
Filter Behavior
- Status Filter:
- Accepts single status or comma-separated list
- 'all' shows contracts in any status
- Default: shows all statuses
- Group Name Filter:
- Case-insensitive partial match
- Uses SQL LIKE with wildcards:
%search%
- Code Filter:
- Partial match for contract codes
- Useful for searching by contract identifier patterns
Pagination
- Default per_page: 10
- Minimum per_page: 1
- Maximum per_page: 100
- Results always ordered by ID DESC (newest first)
Performance Considerations
- Indexed fields: status, subscription_id
- Eager loading prevents N+1 queries
- Group name filter uses LIKE (consider full-text search for large datasets)
- Consider caching for frequently accessed pages
Response Format
{
"status": true,
"message": "カスタムプラン一覧の取得に成功しました",
"data": [
{
"id": 1,
"code": "CUSTOM-2026-001",
"status": "offered",
"amount": 150000,
"billing_interval": "month",
"currency": "jpy",
"group": {
"id": 5,
"name": "Test Corporation"
},
"subscription": {
"id": 10,
"slug": "sub_abc123"
},
"created_at": "2026-02-01T10:30:00Z"
}
],
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 10,
"total": 45
},
"links": {
"first": "http://api.example.com/api/v1/admin/custom-contracts?page=1",
"last": "http://api.example.com/api/v1/admin/custom-contracts?page=5",
"prev": null,
"next": "http://api.example.com/api/v1/admin/custom-contracts?page=2"
}
}