docs: update API.md, FRONTEND.md, MODULES.md, CLAUDE.md for Phase 1 and 2 completion
- API.md: add GET /config/schema endpoint docs; add GET|PUT /missions/rotation endpoints; fix mission response shape (name/filename/size_bytes/terrain); mark Phase 1+2 as done - FRONTEND.md: add TagListEditor, useServerConfigSchema, useServerMissionRotation, useUpdateMissionRotation; update Mission/Mod type notes; remove planned hooks now live - MODULES.md: update config_generator and missions_router descriptions - CLAUDE.md: mark Phase 1 and 2 as Done
This commit is contained in:
108
API.md
108
API.md
@@ -790,6 +790,39 @@ Get all config sections combined. Sensitive fields (passwords) are masked with `
|
||||
|
||||
---
|
||||
|
||||
### GET /servers/{server_id}/config/schema
|
||||
|
||||
Returns per-field widget hints for the frontend config editor. Used by `ConfigEditor` to render the correct UI widget (text box, toggle, select, tag list, etc.) for each field.
|
||||
|
||||
**Auth:** Required (any role)
|
||||
|
||||
**Response 200:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"server": {
|
||||
"hostname": { "widget": "text", "label": "Server Hostname" },
|
||||
"max_players": { "widget": "number", "label": "Max Players", "min": 1, "max": 1000 },
|
||||
"password": { "widget": "password", "label": "Player Password" },
|
||||
"forced_difficulty": { "widget": "select", "label": "Difficulty Preset", "options": ["Recruit", "Regular", "Veteran", "Custom"] },
|
||||
"battleye": { "widget": "toggle", "label": "BattleEye Anti-Cheat" },
|
||||
"motd_lines": { "widget": "textarea", "label": "Message of the Day (one line per row)" },
|
||||
"admin_uids": { "widget": "tag-list", "label": "Admin Steam UIDs", "placeholder": "76561198000000000" }
|
||||
},
|
||||
"rcon": {
|
||||
"rcon_password": { "widget": "password", "label": "RCon Password" }
|
||||
}
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
Returns `{}` if the adapter does not implement `get_ui_schema()`.
|
||||
|
||||
---
|
||||
|
||||
### GET /servers/{server_id}/config/preview
|
||||
|
||||
Rendered config for preview. Admin only because it may contain plaintext credentials.
|
||||
@@ -1182,10 +1215,10 @@ List all available mission/scenario files on disk.
|
||||
"total": 2,
|
||||
"missions": [
|
||||
{
|
||||
"name": "MyMission.Altis",
|
||||
"filename": "MyMission.Altis.pbo",
|
||||
"mission_name": "MyMission.Altis",
|
||||
"terrain": "Altis",
|
||||
"file_size": 102400
|
||||
"size_bytes": 102400,
|
||||
"terrain": "Altis"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1226,6 +1259,63 @@ Upload a mission file. **Multipart form-data**. Maximum file size: **500 MB**. F
|
||||
|
||||
---
|
||||
|
||||
### GET /servers/{server_id}/missions/rotation
|
||||
|
||||
Get the current mission rotation from the server config.
|
||||
|
||||
**Auth:** Required (any role)
|
||||
|
||||
**Response 200:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"missions": [
|
||||
{ "name": "MyMission.Altis", "difficulty": "Regular" },
|
||||
{ "name": "TvT.Stratis", "difficulty": "Veteran" }
|
||||
]
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### PUT /servers/{server_id}/missions/rotation
|
||||
|
||||
Replace the mission rotation. Uses **optimistic locking** — must include `config_version` from the last server config read.
|
||||
|
||||
**Auth:** Admin required
|
||||
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{
|
||||
"missions": [
|
||||
{ "name": "MyMission.Altis", "difficulty": "Regular" },
|
||||
{ "name": "TvT.Stratis", "difficulty": "" }
|
||||
],
|
||||
"config_version": 3
|
||||
}
|
||||
```
|
||||
|
||||
`difficulty` can be `""` for default, or one of `"Recruit"`, `"Regular"`, `"Veteran"`, `"Custom"`.
|
||||
|
||||
**Response 200:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": { "missions": [ ... ] },
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
**Error 409:** Config version conflict — re-fetch and retry.
|
||||
|
||||
---
|
||||
|
||||
### DELETE /servers/{server_id}/missions/{filename}
|
||||
|
||||
Delete a mission file by filename. Removes the file from disk.
|
||||
@@ -1491,20 +1581,20 @@ Implemented via `slowapi` middleware.
|
||||
|
||||
## Upcoming Endpoints (UX Enhancement Plan)
|
||||
|
||||
These endpoints are planned and will be added during the Arma 3 UX Enhancement implementation. They do not exist yet.
|
||||
Endpoints planned during the Arma 3 UX Enhancement. ✅ = implemented.
|
||||
|
||||
### Phase 1 — Config UI Schema
|
||||
### Phase 1 — Config UI Schema ✅
|
||||
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
| GET | `/servers/{server_id}/config/ui-schema` | Bearer | Returns widget hints per field (`widget`, `label`, `placeholder`) for the frontend config editor |
|
||||
| GET ✅ | `/servers/{server_id}/config/schema` | Bearer | Returns widget hints per field for the frontend config editor |
|
||||
|
||||
### Phase 2 — Mission Rotation
|
||||
### Phase 2 — Mission Rotation ✅
|
||||
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
| GET | `/servers/{server_id}/missions/rotation` | Bearer | Get current mission rotation list |
|
||||
| PUT | `/servers/{server_id}/missions/rotation` | Admin | Replace mission rotation (requires `config_version` for optimistic locking) |
|
||||
| GET ✅ | `/servers/{server_id}/missions/rotation` | Bearer | Get current mission rotation list |
|
||||
| PUT ✅ | `/servers/{server_id}/missions/rotation` | Admin | Replace mission rotation (requires `config_version` for optimistic locking) |
|
||||
|
||||
### Phase 4 — Player Kick / Ban
|
||||
|
||||
|
||||
@@ -58,15 +58,15 @@ Types below reflect the **current** API shape. Fields marked `(planned)` will be
|
||||
|
||||
| Phase | Feature | Status |
|
||||
|-------|---------|--------|
|
||||
| 1 | Config field UI widgets (textarea/toggle/select/tag-list per field) | Pending |
|
||||
| 2 | Mission rotation table + multi-file upload | Pending |
|
||||
| 1 | Config field UI widgets (textarea/toggle/select/tag-list per field) | Done |
|
||||
| 2 | Mission rotation table + multi-file upload | Done |
|
||||
| 3 | Mod display names (mod.cpp) + split-pane selector | Pending |
|
||||
| 4 | Player Kick/Ban from Players tab via RCon | Pending |
|
||||
| 5 | Historical log file browser + live log level filter | Pending |
|
||||
|
||||
**New endpoints added by the plan:**
|
||||
- `GET /api/servers/{id}/config/schema` — per-field widget hints
|
||||
- `GET|PUT /api/servers/{id}/missions/rotation` — mission rotation
|
||||
- `GET /api/servers/{id}/config/schema` — per-field widget hints (**implemented**)
|
||||
- `GET|PUT /api/servers/{id}/missions/rotation` — mission rotation (**implemented**)
|
||||
- `POST /api/servers/{id}/players/{slot_id}/kick`
|
||||
- `POST /api/servers/{id}/players/{slot_id}/ban`
|
||||
- `GET /api/servers/{id}/logfiles`
|
||||
|
||||
25
FRONTEND.md
25
FRONTEND.md
@@ -65,17 +65,18 @@ frontend/src/
|
||||
│ ├── servers/
|
||||
│ │ ├── ServerCard.tsx # Server card with actions
|
||||
│ │ ├── ServerHeader.tsx # Server name, status, stats grid, lifecycle buttons
|
||||
│ │ ├── ConfigEditor.tsx # Tabbed config section editor with optimistic locking
|
||||
│ │ ├── ConfigEditor.tsx # Tabbed config section editor; per-field widgets via useServerConfigSchema
|
||||
│ │ ├── PlayerTable.tsx # Current players + history with search
|
||||
│ │ ├── BanTable.tsx # Ban list + create/revoke form
|
||||
│ │ ├── MissionList.tsx # Mission list + upload/delete .pbo
|
||||
│ │ ├── MissionList.tsx # Available missions + Mission Rotation sections; multi-file upload
|
||||
│ │ ├── ModList.tsx # Mod list with enable/disable checkboxes
|
||||
│ │ └── LogViewer.tsx # Log display with level filter (receives logs as props)
|
||||
│ ├── settings/
|
||||
│ │ ├── PasswordChange.tsx # Password change form
|
||||
│ │ └── UserManager.tsx # User CRUD table (admin only)
|
||||
│ └── ui/
|
||||
│ └── StatusLed.tsx # Colored status indicator dot
|
||||
│ ├── StatusLed.tsx # Colored status indicator dot
|
||||
│ └── TagListEditor.tsx # Dynamic string-list editor (add/remove items)
|
||||
│
|
||||
└── __tests__/
|
||||
├── api.test.ts # Axios interceptor tests
|
||||
@@ -129,10 +130,10 @@ App
|
||||
│ │ │ ├── ServerHeader (status, stats, lifecycle buttons)
|
||||
│ │ │ ├── Tab bar (Overview, Config, Players, Bans, Missions, Mods, Logs)
|
||||
│ │ │ ├── OverviewTab (stats grid, executable path)
|
||||
│ │ │ ├── ConfigEditor (section tabs, edit form, optimistic locking)
|
||||
│ │ │ ├── ConfigEditor (section tabs, per-field widgets from schema, optimistic locking)
|
||||
│ │ │ ├── PlayerTable (current + history with search)
|
||||
│ │ │ ├── BanTable (ban list + create/revoke)
|
||||
│ │ │ ├── MissionList (upload .pbo, delete)
|
||||
│ │ │ ├── MissionList (Available + Rotation sections, multi-file upload)
|
||||
│ │ │ ├── ModList (enable/disable checkboxes)
|
||||
│ │ │ └── LogViewer (level filter, real-time via WebSocket onEvent)
|
||||
│ │ ├── /servers/new → CreateServerPage
|
||||
@@ -169,16 +170,19 @@ All server data flows through TanStack Query hooks:
|
||||
|---|---|---|---|
|
||||
| `useServerConfig(id)` | Query | `GET /api/servers/:id/config` | `["servers", id, "config"]` |
|
||||
| `useServerConfigSection(id, section)` | Query | `GET /api/servers/:id/config/:section` | `["servers", id, "config", section]` |
|
||||
| `useServerConfigSchema(id)` | Query | `GET /api/servers/:id/config/schema` | `["servers", id, "config", "schema"]` |
|
||||
| `useServerConfigPreview(id)` | Query | `GET /api/servers/:id/config/preview` | `["servers", id, "config", "preview"]` |
|
||||
| `useServerPlayers(id)` | Query | `GET /api/servers/:id/players` | `["players", id]` |
|
||||
| `useServerPlayerHistory(id, opts?)` | Query | `GET /api/servers/:id/players/history` | `["players", id, "history", opts]` |
|
||||
| `useServerBans(id)` | Query | `GET /api/servers/:id/bans` | `["bans", id]` |
|
||||
| `useServerMissions(id)` | Query | `GET /api/servers/:id/missions` | `["missions", id]` |
|
||||
| `useServerMissionRotation(id)` | Query | `GET /api/servers/:id/missions/rotation` | `["missions", id, "rotation"]` |
|
||||
| `useServerMods(id)` | Query | `GET /api/servers/:id/mods` | `["mods", id]` |
|
||||
| `useUpdateConfigSection(id, section)` | Mutation | `PUT /api/servers/:id/config/:section` | Invalidates config keys |
|
||||
| `useCreateBan(id)` | Mutation | `POST /api/servers/:id/bans` | Invalidates `["bans", id]` |
|
||||
| `useRevokeBan(id)` | Mutation | `DELETE /api/servers/:id/bans/:banId` | Invalidates `["bans", id]` |
|
||||
| `useUploadMission(id)` | Mutation | `POST /api/servers/:id/missions` (multipart) | Invalidates `["missions", id]` |
|
||||
| `useUploadMission(id)` | Mutation | `POST /api/servers/:id/missions` (multipart, `File[]`) | Invalidates `["missions", id]` |
|
||||
| `useUpdateMissionRotation(id)` | Mutation | `PUT /api/servers/:id/missions/rotation` | Invalidates rotation + server config |
|
||||
| `useDeleteMission(id)` | Mutation | `DELETE /api/servers/:id/missions/:filename` | Invalidates `["missions", id]` |
|
||||
| `useSetEnabledMods(id)` | Mutation | `PUT /api/servers/:id/mods/enabled` | Invalidates `["mods", id]` |
|
||||
| `useSendCommand(id)` | Mutation | `POST /api/servers/:id/rcon/command` | No invalidation |
|
||||
@@ -205,18 +209,15 @@ All server data flows through TanStack Query hooks:
|
||||
|
||||
**Key type notes**:
|
||||
- `Server` type in `useServers.ts` uses `game_port`, `current_players`, `max_players` (matches enriched API response)
|
||||
- `Mission` type: `{ name, filename, size_bytes }` — `terrain` field planned (Phase 2 UX enhancement)
|
||||
- `Mod` type: `{ name, path, size_bytes, enabled }` — `display_name`, `workshop_id` fields planned (Phase 3 UX enhancement)
|
||||
- `Mission` type: `{ name, filename, size_bytes, terrain }` — terrain parsed from filename
|
||||
- `Mod` type: `{ name, path, size_bytes, enabled, display_name, workshop_id }` — `display_name`/`workshop_id` from mod.cpp/meta.cpp (planned Phase 3)
|
||||
- `Ban` type: `{ id, server_id, guid, name, reason, banned_by, banned_at, expires_at, is_active, game_data }` (matches API)
|
||||
- There is no REST endpoint for logs — logs are only pushed via WebSocket events
|
||||
|
||||
**Planned hooks (UX Enhancement Plan):**
|
||||
**Planned hooks (UX Enhancement Plan — remaining):**
|
||||
|
||||
| Hook | Phase | Endpoint |
|
||||
|---|---|---|
|
||||
| `useConfigUISchema(serverId)` | Phase 1 | `GET /api/servers/:id/config/ui-schema` |
|
||||
| `useMissionRotation(id)` | Phase 2 | `GET /api/servers/:id/missions/rotation` |
|
||||
| `useUpdateMissionRotation(id)` | Phase 2 | `PUT /api/servers/:id/missions/rotation` |
|
||||
| `useKickPlayer(id)` | Phase 4 | `POST /api/servers/:id/players/:slot_id/kick` |
|
||||
| `useBanPlayer(id)` | Phase 4 | `POST /api/servers/:id/players/:slot_id/ban` |
|
||||
| `useLogFiles(id)` | Phase 5 | `GET /api/servers/:id/logfiles` |
|
||||
|
||||
@@ -49,7 +49,7 @@ All 7 capabilities implemented:
|
||||
| Module | Class | Purpose |
|
||||
|---|---|---|
|
||||
| `adapter.py` | `Arma3Adapter` | Composite adapter declaring all capabilities |
|
||||
| `config_generator.py` | `Arma3ConfigGenerator` | 5 Pydantic config models, writes server.cfg/basic.cfg/Arma3Profile/beserver.cfg, builds launch args |
|
||||
| `config_generator.py` | `Arma3ConfigGenerator` | 5 Pydantic config models, writes server.cfg/basic.cfg/Arma3Profile/beserver.cfg, builds launch args, `get_ui_schema()` for per-field widget hints |
|
||||
| `process_config.py` | `Arma3ProcessConfig` | Allowed executables, port conventions (game+1/+2/+3), directory layout |
|
||||
| `log_parser.py` | `RPTParser` | Regex-based .rpt log parser, log file resolver |
|
||||
| `rcon_client.py` | `BERConClient` | BattlEye RCon v2 UDP protocol implementation |
|
||||
@@ -74,7 +74,7 @@ All 7 capabilities implemented:
|
||||
| `router.py` | Server CRUD, lifecycle (start/stop/restart/kill), config read/write/preview, RCon command |
|
||||
| `players_router.py` | Player list, player history |
|
||||
| `bans_router.py` | Ban CRUD with bans.txt file sync |
|
||||
| `missions_router.py` | Mission list, .pbo upload (500MB), delete |
|
||||
| `missions_router.py` | Mission list, .pbo upload (500MB), delete, GET/PUT rotation |
|
||||
| `mods_router.py` | List mods, set enabled mods |
|
||||
| `service.py` | `ServerService` — orchestrates all lifecycle operations, config writes, thread management |
|
||||
| `schemas.py` | Pydantic models: CreateServerRequest, UpdateServerRequest, StopServerRequest |
|
||||
|
||||
Reference in New Issue
Block a user