feat: implement user data schema and API endpoints
- Add Alembic migration setup with async configuration - Create 16 user data models (users, decks, cards, replays, etc.) - Implement comprehensive API endpoints with JWT auth - Add replay, card collection, group, network, preferences, and activity log routers - Include API documentation and migration test plan - Update Dockerfile to run migrations on startup
This commit is contained in:
@@ -0,0 +1,852 @@
|
||||
# User Data API Endpoints - Complete Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The User Data API provides comprehensive CRUD operations for:
|
||||
- **Session Management** - User authentication sessions
|
||||
- **Deck Versions** - Deck version history and rollback
|
||||
- **Game Replays** - Game recording and playback
|
||||
- **Game Outcomes** - Win/loss tracking with ratings
|
||||
- **User Statistics** - Denormalized stats (games, wins, streaks)
|
||||
- **Card Collection** - User-owned cards with condition/language
|
||||
- **Wishlist** - Cards users want to acquire
|
||||
- **Groups** - User groups with roles and chat
|
||||
- **Networks** - Extended social connections
|
||||
- **Preferences** - User settings and preferences
|
||||
- **Activity Log** - Audit trail with JSONB metadata
|
||||
|
||||
## Base URL
|
||||
|
||||
```
|
||||
/api/v1/user-data
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
All endpoints require a valid JWT token in the `Authorization` header:
|
||||
|
||||
```
|
||||
Authorization: Bearer <your-jwt-token>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. Session Management
|
||||
|
||||
### Get Active Sessions
|
||||
```http
|
||||
GET /sessions/me
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"cleaned_count": 2,
|
||||
"message": "Found 2 active sessions"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Cleanup Expired Sessions
|
||||
```http
|
||||
DELETE /sessions/cleanup
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Cleaned 5 expired sessions"
|
||||
}
|
||||
```
|
||||
|
||||
### Logout Current Session
|
||||
```http
|
||||
POST /sessions/logout
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Logged out successfully"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Deck Versions
|
||||
|
||||
### Create Deck Version
|
||||
```http
|
||||
POST /decks/{deck_id}/versions
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"content": "4x Thoughtseize, 4x Lightning Bolt, ...",
|
||||
"status": "DRAFT",
|
||||
"comment": "Updated for meta change"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"deck_id": 42,
|
||||
"version_number": 3,
|
||||
"content": "4x Thoughtseize, ...",
|
||||
"status": "DRAFT",
|
||||
"comment": "Updated for meta change",
|
||||
"created_at": "2026-01-01T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Get Deck Versions
|
||||
```http
|
||||
GET /decks/{deck_id}/versions?page=1&page_size=50
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"versions": [...],
|
||||
"total": 10,
|
||||
"page": 1,
|
||||
"page_size": 50,
|
||||
"total_pages": 1
|
||||
}
|
||||
```
|
||||
|
||||
### Update Deck Version
|
||||
```http
|
||||
PATCH /decks/{deck_id}/versions/{version_id}
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"status": "FINAL",
|
||||
"comment": "Ready for tournament"
|
||||
}
|
||||
```
|
||||
|
||||
### Delete Deck Version
|
||||
```http
|
||||
DELETE /decks/{deck_id}/versions/{version_id}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Game Replays
|
||||
|
||||
### Create Game Replay
|
||||
```http
|
||||
POST /replays
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"game_uuid": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"room_id": 1,
|
||||
"game_type": "Draft",
|
||||
"format": "Standard",
|
||||
"duration_seconds": 1800,
|
||||
"start_time": "2026-01-01T12:00:00Z",
|
||||
"end_time": "2026-01-01T12:30:00Z",
|
||||
"status": "COMPLETED",
|
||||
"replay_data": {
|
||||
"turns": [...],
|
||||
"deck": {...}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"game_uuid": "550e8400-...",
|
||||
"room_id": 1,
|
||||
"game_type": "Draft",
|
||||
"format": "Standard",
|
||||
"duration_seconds": 1800,
|
||||
"start_time": "2026-01-01T12:00:00Z",
|
||||
"end_time": "2026-01-01T12:30:00Z",
|
||||
"status": "COMPLETED",
|
||||
"replay_data": {...},
|
||||
"created_at": "2026-01-01T12:30:00Z",
|
||||
"updated_at": "2026-01-01T12:30:00Z",
|
||||
"players": [...]
|
||||
}
|
||||
```
|
||||
|
||||
### Get Game Replays
|
||||
```http
|
||||
GET /replays?page=1&page_size=50&user_id=42&status_filter=COMPLETED
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"replays": [...],
|
||||
"total": 100,
|
||||
"page": 1,
|
||||
"page_size": 50,
|
||||
"total_pages": 2
|
||||
}
|
||||
```
|
||||
|
||||
### Get Replay Players
|
||||
```http
|
||||
GET /replays/{replay_id}/players
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"user_id": 42,
|
||||
"deck_id": 10,
|
||||
"position": 1,
|
||||
"won": true,
|
||||
"lost": false,
|
||||
"concession": false,
|
||||
"turn_one": false
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Game Outcomes
|
||||
|
||||
### Create Game Outcome
|
||||
```http
|
||||
POST /outcomes
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"game_uuid": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"outcome": "WIN",
|
||||
"opponent_id": 99,
|
||||
"format": "Standard",
|
||||
"rating_before": 1500,
|
||||
"rating_after": 1525,
|
||||
"rating_change": 25
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"user_id": 42,
|
||||
"game_uuid": "550e8400-...",
|
||||
"outcome": "WIN",
|
||||
"opponent_id": 99,
|
||||
"format": "Standard",
|
||||
"rating_before": 1500,
|
||||
"rating_after": 1525,
|
||||
"rating_change": 25,
|
||||
"created_at": "2026-01-01T12:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Get Game Outcomes
|
||||
```http
|
||||
GET /outcomes?page=1&page_size=50&user_id=42
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. User Statistics
|
||||
|
||||
### Get User Statistics
|
||||
```http
|
||||
GET /statistics/{user_id}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"user_id": 42,
|
||||
"total_games": 150,
|
||||
"total_wins": 90,
|
||||
"total_losses": 55,
|
||||
"total_concessions": 5,
|
||||
"win_rate": 60.0,
|
||||
"current_streak": 3,
|
||||
"best_streak": 8,
|
||||
"average_rating": 1450.5,
|
||||
"last_game_date": "2026-01-01T12:00:00Z",
|
||||
"updated_at": "2026-01-01T12:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Update User Statistics
|
||||
```http
|
||||
POST /statistics/update
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"user_id": 42,
|
||||
"outcome": "WIN"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"user_id": 42,
|
||||
"total_games": 151,
|
||||
"total_wins": 91,
|
||||
"total_losses": 55,
|
||||
"win_rate": 60.26,
|
||||
"current_streak": 4,
|
||||
"updated_at": "2026-01-01T12:35:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Card Collection
|
||||
|
||||
### Add Card to Collection
|
||||
```http
|
||||
POST /collection
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"card_id": 12345,
|
||||
"quantity": 4,
|
||||
"condition": "NEAR_MINT",
|
||||
"language": "EN",
|
||||
"is_foil": true,
|
||||
"is_alt_art": false,
|
||||
"acquired_date": "2026-01-01T00:00:00Z",
|
||||
"acquisition_method": "Bought",
|
||||
"notes": "From card shop"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"user_id": 42,
|
||||
"card_id": 12345,
|
||||
"quantity": 4,
|
||||
"condition": "NEAR_MINT",
|
||||
"language": "EN",
|
||||
"is_foil": true,
|
||||
"is_alt_art": false,
|
||||
"acquired_date": "2026-01-01T00:00:00Z",
|
||||
"acquisition_method": "Bought",
|
||||
"notes": "From card shop",
|
||||
"created_at": "2026-01-01T12:00:00Z",
|
||||
"updated_at": "2026-01-01T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Get Card Collection
|
||||
```http
|
||||
GET /collection?page=1&page_size=50&is_foil=true&is_alt_art=false
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"cards": [...],
|
||||
"total": 500,
|
||||
"page": 1,
|
||||
"page_size": 50,
|
||||
"total_pages": 10
|
||||
}
|
||||
```
|
||||
|
||||
### Update Card in Collection
|
||||
```http
|
||||
PATCH /collection/{card_id}
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"quantity": 3,
|
||||
"condition": "EX",
|
||||
"notes": "Slightly worn"
|
||||
}
|
||||
```
|
||||
|
||||
### Remove Card from Collection
|
||||
```http
|
||||
DELETE /collection/{card_id}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Wishlist
|
||||
|
||||
### Add to Wishlist
|
||||
```http
|
||||
POST /wishlist
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"card_id": 12345,
|
||||
"max_price": 50.00,
|
||||
"notes": "Looking for foil version"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"user_id": 42,
|
||||
"card_id": 12345,
|
||||
"max_price": 50.00,
|
||||
"notes": "Looking for foil version",
|
||||
"created_at": "2026-01-01T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Get Wishlist
|
||||
```http
|
||||
GET /wishlist?page=1&page_size=50
|
||||
```
|
||||
|
||||
### Update Wishlist Item
|
||||
```http
|
||||
PATCH /wishlist/{item_id}
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"max_price": 75.00,
|
||||
"notes": "Willing to pay more"
|
||||
}
|
||||
```
|
||||
|
||||
### Remove from Wishlist
|
||||
```http
|
||||
DELETE /wishlist/{item_id}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Groups
|
||||
|
||||
### Create Group
|
||||
```http
|
||||
POST /groups
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "Standard Players",
|
||||
"description": "Casual Standard players",
|
||||
"is_public": true,
|
||||
"max_members": 50
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Standard Players",
|
||||
"description": "Casual Standard players",
|
||||
"owner_id": 42,
|
||||
"is_public": true,
|
||||
"max_members": 50,
|
||||
"created_at": "2026-01-01T12:00:00Z",
|
||||
"updated_at": "2026-01-01T12:00:00Z",
|
||||
"member_count": 1,
|
||||
"is_member": true
|
||||
}
|
||||
```
|
||||
|
||||
### Get User Groups
|
||||
```http
|
||||
GET /groups?page=1&page_size=50&is_public=true
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"groups": [...],
|
||||
"total": 5,
|
||||
"page": 1,
|
||||
"page_size": 50,
|
||||
"total_pages": 1
|
||||
}
|
||||
```
|
||||
|
||||
### Update Group
|
||||
```http
|
||||
PATCH /groups/{group_id}
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"description": "Updated description",
|
||||
"max_members": 100
|
||||
}
|
||||
```
|
||||
|
||||
### Delete Group
|
||||
```http
|
||||
DELETE /groups/{group_id}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Group Members
|
||||
|
||||
### Add Group Member
|
||||
```http
|
||||
POST /groups/{group_id}/members
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"user_id": 99,
|
||||
"role": "MEMBER"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Member added",
|
||||
"member_id": 5
|
||||
}
|
||||
```
|
||||
|
||||
### Update Group Member Role
|
||||
```http
|
||||
PATCH /groups/{group_id}/members/{member_id}
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"role": "ADMIN"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Member role updated"
|
||||
}
|
||||
```
|
||||
|
||||
### Remove Group Member
|
||||
```http
|
||||
DELETE /groups/{group_id}/members/{member_id}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Group Chat Messages
|
||||
|
||||
### Send Group Message
|
||||
```http
|
||||
POST /groups/{group_id}/messages
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"message": "Hey everyone! Ready for a game?"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"group_id": 1,
|
||||
"sender_id": 42,
|
||||
"sender_username": "player42",
|
||||
"message": "Hey everyone! Ready for a game?",
|
||||
"created_at": "2026-01-01T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Get Group Messages
|
||||
```http
|
||||
GET /groups/{group_id}/messages?page=1&page_size=50
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"messages": [...],
|
||||
"total": 25,
|
||||
"page": 1,
|
||||
"page_size": 50,
|
||||
"total_pages": 1
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Networks
|
||||
|
||||
### Create Network
|
||||
```http
|
||||
POST /networks
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "MTG Enthusiasts",
|
||||
"description": "Friends who play Magic",
|
||||
"is_public": true
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"name": "MTG Enthusiasts",
|
||||
"description": "Friends who play Magic",
|
||||
"creator_id": 42,
|
||||
"is_public": true,
|
||||
"created_at": "2026-01-01T12:00:00Z",
|
||||
"member_count": 1,
|
||||
"is_member": true
|
||||
}
|
||||
```
|
||||
|
||||
### Get User Networks
|
||||
```http
|
||||
GET /networks?page=1&page_size=50
|
||||
```
|
||||
|
||||
### Update Network
|
||||
```http
|
||||
PATCH /networks/{network_id}
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"description": "Updated network description"
|
||||
}
|
||||
```
|
||||
|
||||
### Delete Network
|
||||
```http
|
||||
DELETE /networks/{network_id}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. Network Members
|
||||
|
||||
### Add Network Member
|
||||
```http
|
||||
POST /networks/{network_id}/members
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"user_id": 99,
|
||||
"role": "MEMBER"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"message": "Member added",
|
||||
"member_id": 3
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 13. User Preferences
|
||||
|
||||
### Get User Preferences
|
||||
```http
|
||||
GET /preferences
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"user_id": 42,
|
||||
"theme": "light",
|
||||
"notifications_enabled": true,
|
||||
"email_notifications": true,
|
||||
"auto_save_decks": true,
|
||||
"default_format": "standard",
|
||||
"language": "EN",
|
||||
"updated_at": "2026-01-01T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Update User Preferences
|
||||
```http
|
||||
PATCH /preferences
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"theme": "dark",
|
||||
"notifications_enabled": false,
|
||||
"default_format": "modern"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"user_id": 42,
|
||||
"theme": "dark",
|
||||
"notifications_enabled": false,
|
||||
"email_notifications": true,
|
||||
"auto_save_decks": true,
|
||||
"default_format": "modern",
|
||||
"language": "EN",
|
||||
"updated_at": "2026-01-01T12:05:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 14. Activity Log
|
||||
|
||||
### Get Activity Log
|
||||
```http
|
||||
GET /activity?page=1&page_size=50&activity_type=LOGIN
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"entries": [
|
||||
{
|
||||
"id": 1,
|
||||
"user_id": 42,
|
||||
"activity_type": "LOGIN",
|
||||
"activity_data": {"ip": "192.168.1.1"},
|
||||
"ip_address": "192.168.1.1",
|
||||
"created_at": "2026-01-01T12:00:00Z"
|
||||
}
|
||||
],
|
||||
"total": 100,
|
||||
"page": 1,
|
||||
"page_size": 50,
|
||||
"total_pages": 2
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Responses
|
||||
|
||||
All endpoints return consistent error responses:
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "Error message"
|
||||
}
|
||||
```
|
||||
|
||||
### Common Error Codes
|
||||
|
||||
| Status Code | Description |
|
||||
|------------|-------------|
|
||||
| 400 | Bad Request - Invalid input |
|
||||
| 401 | Unauthorized - Missing or invalid token |
|
||||
| 403 | Forbidden - Insufficient permissions |
|
||||
| 404 | Not Found - Resource doesn't exist |
|
||||
| 409 | Conflict - Resource already exists |
|
||||
| 500 | Internal Server Error |
|
||||
|
||||
---
|
||||
|
||||
## Testing with cURL
|
||||
|
||||
### Example: Create a Deck Version
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/user-data/decks/42/versions" \
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"content": "4x Thoughtseize, 4x Lightning Bolt, ...",
|
||||
"status": "DRAFT",
|
||||
"comment": "Updated for meta"
|
||||
}'
|
||||
```
|
||||
|
||||
### Example: Get Card Collection
|
||||
```bash
|
||||
curl "http://localhost:8000/api/v1/user-data/collection?page=1&page_size=10" \
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN"
|
||||
```
|
||||
|
||||
### Example: Add to Wishlist
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/user-data/wishlist" \
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"card_id": 12345,
|
||||
"max_price": 50.00,
|
||||
"notes": "Looking for foil"
|
||||
}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Available Endpoints Summary
|
||||
|
||||
| Method | Endpoint | Description |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/sessions/me` | Get active sessions |
|
||||
| DELETE | `/sessions/cleanup` | Cleanup expired sessions |
|
||||
| POST | `/sessions/logout` | Logout current session |
|
||||
| POST | `/decks/{id}/versions` | Create deck version |
|
||||
| GET | `/decks/{id}/versions` | Get deck versions |
|
||||
| PATCH | `/decks/{id}/versions/{vid}` | Update deck version |
|
||||
| DELETE | `/decks/{id}/versions/{vid}` | Delete deck version |
|
||||
| POST | `/replays` | Create game replay |
|
||||
| GET | `/replays` | Get game replays |
|
||||
| GET | `/replays/{id}` | Get specific replay |
|
||||
| PATCH | `/replays/{id}` | Update replay |
|
||||
| DELETE | `/replays/{id}` | Delete replay |
|
||||
| POST | `/replays/{id}/players` | Add player to replay |
|
||||
| GET | `/replays/{id}/players` | Get replay players |
|
||||
| POST | `/outcomes` | Create game outcome |
|
||||
| GET | `/outcomes` | Get game outcomes |
|
||||
| GET | `/statistics/{id}` | Get user statistics |
|
||||
| POST | `/statistics/update` | Update user statistics |
|
||||
| POST | `/collection` | Add card to collection |
|
||||
| GET | `/collection` | Get card collection |
|
||||
| PATCH | `/collection/{id}` | Update card |
|
||||
| DELETE | `/collection/{id}` | Remove card |
|
||||
| POST | `/wishlist` | Add to wishlist |
|
||||
| GET | `/wishlist` | Get wishlist |
|
||||
| PATCH | `/wishlist/{id}` | Update wishlist item |
|
||||
| DELETE | `/wishlist/{id}` | Remove from wishlist |
|
||||
| POST | `/groups` | Create group |
|
||||
| GET | `/groups` | Get user groups |
|
||||
| GET | `/groups/{id}` | Get specific group |
|
||||
| PATCH | `/groups/{id}` | Update group |
|
||||
| DELETE | `/groups/{id}` | Delete group |
|
||||
| POST | `/groups/{id}/members` | Add group member |
|
||||
| PATCH | `/groups/{id}/members/{mid}` | Update member role |
|
||||
| DELETE | `/groups/{id}/members/{mid}` | Remove member |
|
||||
| POST | `/groups/{id}/messages` | Send group message |
|
||||
| GET | `/groups/{id}/messages` | Get group messages |
|
||||
| POST | `/networks` | Create network |
|
||||
| GET | `/networks` | Get user networks |
|
||||
| GET | `/networks/{id}` | Get specific network |
|
||||
| PATCH | `/networks/{id}` | Update network |
|
||||
| DELETE | `/networks/{id}` | Delete network |
|
||||
| POST | `/networks/{id}/members` | Add network member |
|
||||
| GET | `/preferences` | Get user preferences |
|
||||
| PATCH | `/preferences` | Update preferences |
|
||||
| GET | `/activity` | Get activity log |
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Test endpoints** with curl or Postman
|
||||
2. **Create integration tests** for each endpoint
|
||||
3. **Add rate limiting** for production
|
||||
4. **Implement pagination optimization** for large datasets
|
||||
5. **Add search functionality** for cards and decks
|
||||
6. **Create webhook endpoints** for real-time notifications
|
||||
Reference in New Issue
Block a user