chore: add api contract
Build and Push Docker Image / build-and-push (push) Has been skipped Details

This commit is contained in:
itqop 2025-11-09 02:08:57 +03:00
parent 9c940cedfd
commit c67c4f749c
1 changed files with 262 additions and 0 deletions

262
WHITELIST_API.md Normal file
View File

@ -0,0 +1,262 @@
# Whitelist API Contract
API endpoints for managing player whitelist in HubMC gateway.
**Base Path:** `/api/v1/whitelist`
**Authentication:** All endpoints require `X-API-Key` header.
---
## Endpoints
### 1. Add Player to Whitelist
**Endpoint:** `POST /api/v1/whitelist/add`
**Description:** Add a player to the whitelist. If player exists but is inactive, reactivates them with new data.
**Request Body:**
```json
{
"player_name": "string", // 3-16 chars, alphanumeric + underscore only
"added_by": "string", // 1-100 chars, who added the player
"added_at": "datetime", // ISO 8601 format, within 1 hour past to 5 min future
"expires_at": "datetime|null", // Optional, must be after added_at, max 2 years future
"is_active": "boolean", // Default: true
"reason": "string|null" // Optional, max 500 chars, whitespace trimmed
}
```
**Validation Rules:**
- `player_name`: Must match regex `^[a-zA-Z0-9_]{3,16}$`
- `added_by`: Cannot be empty or whitespace
- `added_at`: Must be between (now - 1 hour) and (now + 5 minutes)
- `expires_at`: Must be after `added_at` and before (now + 2 years)
- `reason`: Trimmed, null if empty after trim
**Response:** `201 Created`
```json
{
"id": "uuid",
"player_name": "string",
"added_by": "string",
"added_at": "datetime",
"expires_at": "datetime|null",
"is_active": true,
"reason": "string|null"
}
```
**Errors:**
- `401 Unauthorized`: Invalid API key
- `400 Bad Request`: Validation error (invalid username format, date constraints, etc.)
- `409 Conflict`: Player already exists and is active (`AlreadyExistsError`)
**Behavior:**
- Creates LuckPerms player entry (logs error if fails, continues anyway)
- If player exists and is inactive: reactivates with new data
- If player exists and is active: returns 409 error
- Handles race conditions with IntegrityError retry logic
---
### 2. Remove Player from Whitelist
**Endpoint:** `POST /api/v1/whitelist/remove`
**Description:** Permanently delete a player from the whitelist.
**Request Body:**
```json
{
"player_name": "string" // 3-16 chars, alphanumeric + underscore only
}
```
**Validation Rules:**
- `player_name`: Must match regex `^[a-zA-Z0-9_]{3,16}$`
**Response:** `204 No Content`
**Errors:**
- `401 Unauthorized`: Invalid API key
- `400 Bad Request`: Invalid username format
- `404 Not Found`: Player not found in whitelist (`NotFoundError`)
**Behavior:**
- Hard deletes the entry from database
- Does NOT check if player is active/inactive
---
### 3. Check Player Whitelist Status
**Endpoint:** `POST /api/v1/whitelist/check`
**Description:** Check if a player is currently whitelisted and active.
**Request Body:**
```json
{
"player_name": "string" // 3-16 chars, alphanumeric + underscore only
}
```
**Validation Rules:**
- `player_name`: Must match regex `^[a-zA-Z0-9_]{3,16}$`
**Response:** `200 OK`
```json
{
"is_whitelisted": true // true if exists AND is_active=true
}
```
**Errors:**
- `401 Unauthorized`: Invalid API key
- `400 Bad Request`: Invalid username format
**Behavior:**
- Returns `true` only if entry exists AND `is_active = true`
- Returns `false` if player not found OR `is_active = false`
---
### 4. List All Whitelisted Players
**Endpoint:** `GET /api/v1/whitelist/`
**Description:** Get all whitelist entries (both active and inactive).
**Query Parameters:** None
**Response:** `200 OK`
```json
{
"entries": [
{
"id": "uuid",
"player_name": "string",
"added_by": "string",
"added_at": "datetime",
"expires_at": "datetime|null",
"is_active": true,
"reason": "string|null"
}
],
"total": 42 // Count of entries array
}
```
**Errors:**
- `401 Unauthorized`: Invalid API key
**Behavior:**
- Returns ALL entries (active and inactive)
- Sorted by `added_at` descending (newest first)
- No pagination implemented
---
### 5. Get Whitelist Count
**Endpoint:** `GET /api/v1/whitelist/count`
**Description:** Get total count of all whitelist entries.
**Query Parameters:** None
**Response:** `200 OK`
```json
{
"total": 42 // Total count of all entries (active + inactive)
}
```
**Errors:**
- `401 Unauthorized`: Invalid API key
**Behavior:**
- Counts ALL entries regardless of `is_active` status
---
## Data Types
**datetime:** ISO 8601 format with timezone
```
2024-01-15T10:30:00+00:00
2024-01-15T10:30:00Z
```
**uuid:** UUID v4 format
```
550e8400-e29b-41d4-a716-446655440000
```
---
## Common Headers
**Request:**
```
X-API-Key: your-api-key-here
Content-Type: application/json
```
**Response:**
```
Content-Type: application/json
```
---
## Error Response Format
All errors follow FastAPI standard format:
```json
{
"detail": "Error message description"
}
```
**Status Codes:**
- `200 OK`: Success (GET)
- `201 Created`: Resource created (POST add)
- `204 No Content`: Success with no body (POST remove)
- `400 Bad Request`: Validation error
- `401 Unauthorized`: Invalid/missing API key
- `404 Not Found`: Resource not found
- `409 Conflict`: Resource already exists
- `500 Internal Server Error`: Unexpected server error
---
## Implementation Notes
### Database Model
- Table: `hub_whitelist`
- Primary Key: `id` (UUID, auto-generated)
- Unique Constraint: `player_name`
- Indexes: `player_name`, `is_active`, `expires_at`
- Auto-timestamps: `created_at`, `updated_at`
### Race Condition Handling
The `add` endpoint handles concurrent requests for the same `player_name`:
1. Checks if player exists
2. Attempts to create/update
3. On `IntegrityError` (race condition), retries check
4. Returns appropriate error if now active
### LuckPerms Integration
The `add` endpoint creates a LuckPerms player entry with:
- `username`: from `player_name`
- `primary_group`: "default"
Failures are logged but do NOT block whitelist creation.
### Soft Delete
Currently NOT implemented. The `remove` endpoint performs hard delete.
Inactive entries are kept until explicitly removed.