# Aurora API Reference

REST API server for Aurora bot management. Base URL: `http://localhost:3000`

## Common Response Formats

**Success Responses:**
- Single resource: `{ ...resource }` or `{ success: true, resource: {...} }`
- List operations: `{ items: [...], total: number }`
- Mutations: `{ success: true, resource: {...} }`

**Error Responses:**
```json
{
  "error": "Brief error message",
  "details": "Optional detailed error information"
}
```

**HTTP Status Codes:**
| Code | Description |
|------|-------------|
| 200 | Success |
| 201 | Created |
| 204 | No Content (successful DELETE) |
| 400 | Bad Request (validation error) |
| 404 | Not Found |
| 409 | Conflict (e.g., duplicate name) |
| 429 | Too Many Requests |
| 500 | Internal Server Error |

---

## Health

### `GET /api/health`
Returns server health status.

**Response:** `{ "status": "ok", "timestamp": 1234567890 }`

---

## Items

### `GET /api/items`
List all items with optional filtering.

| Query Param | Type | Description |
|-------------|------|-------------|
| `search` | string | Filter by name/description |
| `type` | string | Filter by item type |
| `rarity` | string | Filter by rarity (C, R, SR, SSR) |
| `limit` | number | Max results (default: 100) |
| `offset` | number | Pagination offset |

**Response:** `{ "items": [...], "total": number }`

### `GET /api/items/:id`
Get single item by ID.

**Response:**
```json
{
  "id": 1,
  "name": "Health Potion",
  "description": "Restores HP",
  "type": "CONSUMABLE",
  "rarity": "C",
  "price": "100",
  "iconUrl": "/assets/items/1.png",
  "imageUrl": "/assets/items/1.png",
  "usageData": { "consume": true, "effects": [] }
}
```

### `POST /api/items`
Create new item. Supports JSON or multipart/form-data with image.

**Body (JSON):**
```json
{
  "name": "Health Potion",
  "description": "Restores HP",
  "type": "CONSUMABLE",
  "rarity": "C",
  "price": "100",
  "iconUrl": "/assets/items/placeholder.png",
  "imageUrl": "/assets/items/placeholder.png",
  "usageData": { "consume": true, "effects": [] }
}
```

**Body (Multipart):**
- `data`: JSON string with item fields
- `image`: Image file (PNG, JPEG, WebP, GIF, max 15MB)

### `PUT /api/items/:id`
Update existing item.

### `DELETE /api/items/:id`
Delete item and associated asset.

### `POST /api/items/:id/icon`
Upload/replace item image. Accepts multipart/form-data with `image` field.

---

## Users

### `GET /api/users`
List all users with optional filtering and sorting.

| Query Param | Type | Description |
|-------------|------|-------------|
| `search` | string | Filter by username (partial match) |
| `sortBy` | string | Sort field: `balance`, `level`, `xp`, `username` (default: `balance`) |
| `sortOrder` | string | Sort order: `asc`, `desc` (default: `desc`) |
| `limit` | number | Max results (default: 50) |
| `offset` | number | Pagination offset |

**Response:** `{ "users": [...], "total": number }`

### `GET /api/users/:id`
Get single user by Discord ID.

**Response:**
```json
{
  "id": "123456789012345678",
  "username": "Player1",
  "balance": "1000",
  "xp": "500",
  "level": 5,
  "dailyStreak": 3,
  "isActive": true,
  "classId": "1",
  "class": { "id": "1", "name": "Warrior", "balance": "5000" },
  "settings": {},
  "createdAt": "2024-01-01T00:00:00Z",
  "updatedAt": "2024-01-15T12:00:00Z"
}
```

### `PUT /api/users/:id`
Update user fields.

**Body:**
```json
{
  "username": "NewName",
  "balance": "2000",
  "xp": "750",
  "level": 10,
  "dailyStreak": 5,
  "classId": "1",
  "isActive": true,
  "settings": {}
}
```

### `GET /api/users/:id/inventory`
Get user's inventory with item details.

**Response:**
```json
{
  "inventory": [
    {
      "userId": "123456789012345678",
      "itemId": 1,
      "quantity": "5",
      "item": { "id": 1, "name": "Health Potion", ... }
    }
  ]
}
```

### `POST /api/users/:id/inventory`
Add item to user inventory.

**Body:**
```json
{
  "itemId": 1,
  "quantity": "5"
}
```

### `DELETE /api/users/:id/inventory/:itemId`
Remove item from user inventory. Use query param `amount` to specify quantity (default: 1).

| Query Param | Type | Description |
|-------------|------|-------------|
| `amount` | number | Amount to remove (default: 1) |
```

---

## Classes

### `GET /api/classes`
List all classes.

**Response:**
```json
{
  "classes": [
    { "id": "1", "name": "Warrior", "balance": "5000", "roleId": "123456789" }
  ]
}
```

### `POST /api/classes`
Create new class.

**Body:**
```json
{
  "id": "2",
  "name": "Mage",
  "balance": "0",
  "roleId": "987654321"
}
```

### `PUT /api/classes/:id`
Update class.

**Body:**
```json
{
  "name": "Updated Name",
  "balance": "10000",
  "roleId": "111222333"
}
```

### `DELETE /api/classes/:id`
Delete class.

---

## Moderation

### `GET /api/moderation`
List moderation cases with optional filtering.

| Query Param | Type | Description |
|-------------|------|-------------|
| `userId` | string | Filter by target user ID |
| `moderatorId` | string | Filter by moderator ID |
| `type` | string | Filter by case type: `warn`, `timeout`, `kick`, `ban`, `note`, `prune` |
| `active` | boolean | Filter by active status |
| `limit` | number | Max results (default: 50) |
| `offset` | number | Pagination offset |

**Response:**
```json
{
  "cases": [
    {
      "id": "1",
      "caseId": "CASE-0001",
      "type": "warn",
      "userId": "123456789",
      "username": "User1",
      "moderatorId": "987654321",
      "moderatorName": "Mod1",
      "reason": "Spam",
      "metadata": {},
      "active": true,
      "createdAt": "2024-01-15T12:00:00Z",
      "resolvedAt": null,
      "resolvedBy": null,
      "resolvedReason": null
    }
  ]
}
```

### `GET /api/moderation/:caseId`
Get single case by case ID (e.g., `CASE-0001`).

### `POST /api/moderation`
Create new moderation case.

**Body:**
```json
{
  "type": "warn",
  "userId": "123456789",
  "username": "User1",
  "moderatorId": "987654321",
  "moderatorName": "Mod1",
  "reason": "Rule violation",
  "metadata": { "duration": "24h" }
}
```

### `PUT /api/moderation/:caseId/clear`
Clear/resolve a moderation case.

**Body:**
```json
{
  "clearedBy": "987654321",
  "clearedByName": "Mod1",
  "reason": "Appeal accepted"
}
```

---

## Transactions

### `GET /api/transactions`
List economy transactions.

| Query Param | Type | Description |
|-------------|------|-------------|
| `userId` | string | Filter by user ID |
| `type` | string | Filter by transaction type |
| `limit` | number | Max results (default: 50) |
| `offset` | number | Pagination offset |

**Response:**
```json
{
  "transactions": [
    {
      "id": "1",
      "userId": "123456789",
      "relatedUserId": null,
      "amount": "100",
      "type": "DAILY_REWARD",
      "description": "Daily reward (Streak: 3)",
      "createdAt": "2024-01-15T12:00:00Z"
    }
  ]
}
```

**Transaction Types:**
- `DAILY_REWARD` - Daily claim reward
- `TRANSFER_IN` - Received from another user
- `TRANSFER_OUT` - Sent to another user
- `LOOTDROP_CLAIM` - Claimed lootdrop
- `SHOP_BUY` - Item purchase
- `QUEST_REWARD` - Quest completion reward

---

---

## Lootdrops

### `GET /api/lootdrops`
List lootdrops (default limit 50, sorted by newest).

| Query Param | Type | Description |
|-------------|------|-------------|
| `limit` | number | Max results (default: 50) |

**Response:** `{ "lootdrops": [...] }`

### `POST /api/lootdrops`
Spawn a lootdrop in a channel.

**Body:**
```json
{
  "channelId": "1234567890",
  "amount": 100,
  "currency": "Gold"
}
```

### `DELETE /api/lootdrops/:messageId`
Cancel and delete a lootdrop.

---

## Quests

### `GET /api/quests`
List all quests.

**Response:**
```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "Daily Login",
      "description": "Login once",
      "triggerEvent": "login",
      "requirements": { "target": 1 },
      "rewards": { "xp": 50, "balance": 100 }
    }
  ]
}
```

### `POST /api/quests`
Create new quest.

**Body:**
```json
{
  "name": "Daily Login",
  "description": "Login once",
  "triggerEvent": "login",
  "target": 1,
  "xpReward": 50,
  "balanceReward": 100
}
```

### `PUT /api/quests/:id`
Update quest.

### `DELETE /api/quests/:id`
Delete quest.

---

## Settings

### `GET /api/settings`
Get current bot configuration.

### `POST /api/settings`
Update configuration (partial merge supported).

### `GET /api/settings/meta`
Get Discord metadata (roles, channels, commands).

**Response:**
```json
{
  "roles": [{ "id": "123", "name": "Admin", "color": "#FF0000" }],
  "channels": [{ "id": "456", "name": "general", "type": 0 }],
  "commands": [{ "name": "daily", "category": "economy" }]
}
```

---

## Admin Actions

### `POST /api/actions/reload-commands`
Reload bot slash commands.

### `POST /api/actions/clear-cache`
Clear internal caches.

### `POST /api/actions/maintenance-mode`
Toggle maintenance mode.

**Body:** `{ "enabled": true, "reason": "Updating..." }`

---

## Stats

### `GET /api/stats`
Get full dashboard statistics.

### `GET /api/stats/activity`
Get activity aggregation (cached 5 min).

---

## Assets

### `GET /assets/items/:filename`
Serve item images. Cached 24 hours.

---

## WebSocket

### `ws://localhost:3000/ws`
Real-time dashboard updates.

**Messages:**
- `STATS_UPDATE` - Periodic stats broadcast (every 5s when clients connected)
- `NEW_EVENT` - Real-time system events
- `PING/PONG` - Heartbeat

**Limits:** Max 10 concurrent connections, 16KB max payload, 60s idle timeout.
