# 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
