- Fix logfiles_router and thread_registry to resolve .rpt log files from Path(server["exe_path"]).parent/server/ instead of the languard data dir, which never contained log files — log list and live tail both now work correctly - Rewrite get_ui_schema() in config_generator to cover all ~80 fields across all 5 sections (server/basic/profile/launch/rcon) with proper toggle/select/number/password/tag-list/hidden widgets and labels; missions field is hidden (managed by Missions tab) - Add formatSelectDisplay() to ConfigEditor so select fields show descriptive text (e.g. "0 - Never") instead of raw numbers in view mode - Add ToggleDisplay for boolean fields (Enabled/Disabled with indicator dot) - Add section tab labels and descriptions to ConfigEditor - Add MissionList UX hints and dynamic Add/In Rotation button labels - Add "hidden" to FieldSchema widget union type - Update API.md, ARCHITECTURE.md, CLAUDE.md, FRONTEND.md, MODULES.md, THREADING.md to document log path fix and schema coverage
4.5 KiB
4.5 KiB
Languard Server Manager
Quick Start
# Backend (from backend/)
python -m uvicorn main:app --host 0.0.0.0 --port 8000 --reload
# Frontend (from frontend/)
npx vite --host
- Backend API: http://localhost:8000 (docs: http://localhost:8000/docs)
- Frontend: http://localhost:5173
- Default admin:
admin/ (random, printed at first startup; reset viapython -c "from core.auth.utils import hash_password; print(hash_password('admin123'))"then update SQLite)
Architecture
FastAPI + SQLite backend, React 19 + TypeScript + Vite frontend. See ARCHITECTURE.md for full details.
Key Rules
- Frontend types must match API response shapes, NOT database schema columns
- There is no REST endpoint for logs — logs are only pushed via WebSocket events
- WebSocket
onEventcallback is the mechanism for receiving real-time log entries - Config updates use optimistic locking (config_version) — 409 on conflict
- Sensitive config fields are encrypted at rest with Fernet
Current Implementation Status
Backend: Fully implemented (42+ endpoints)
All routers, services, repositories, game adapter system, WebSocket, background threads, and scheduled cleanup are complete.
Frontend: Fully implemented (baseline)
| Route | Status | Notes |
|---|---|---|
/login |
Complete | Zod + react-hook-form validation |
/ |
Complete | Dashboard with server grid + Start/Stop/Restart quick actions |
/servers/:id |
Complete | 7-tab detail page (overview, config, players, bans, missions, mods, logs) |
/servers/new |
Complete | 4-step wizard with per-step validation via trigger() |
/settings |
Complete | Password change + admin user management |
Frontend Type Mapping (API → Frontend)
| API Resource | Frontend Type | Key Fields |
|---|---|---|
| Server (enriched) | Server in useServers.ts |
game_port, current_players, max_players, cpu_percent, ram_mb |
| Mission | Mission in useServerDetail.ts |
name, filename, size_bytes, terrain |
| Mod | Mod in useServerDetail.ts |
name, path, size_bytes, enabled, display_name, workshop_id |
| Ban | Ban in useServerDetail.ts |
id, server_id, guid, name, reason, banned_by, banned_at, expires_at, is_active, game_data |
| Player | Player in useServerDetail.ts |
id, slot_id, name, guid, ip, ping |
| LogFile | LogFile in useServerDetail.ts |
filename, size_bytes, modified_at |
UX Enhancement Plan — ALL PHASES COMPLETE
Plan file: .claude/plan/arma3-ux-enhancement.md
| Phase | Feature | Status |
|---|---|---|
| 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 | Done |
| 4 | Player Kick/Ban from Players tab via RCon | Done |
| 5 | Historical log file browser + live log level filter | Done |
Endpoints added:
GET /api/servers/{id}/config/schema— per-field widget hintsGET|PUT /api/servers/{id}/missions/rotation— mission rotation with optimistic lockingPOST /api/servers/{id}/players/{slot_id}/kick— kick via RConPOST /api/servers/{id}/players/{slot_id}/ban— ban via RCon + DB recordGET /api/servers/{id}/logfiles— list.rptlog filesGET /api/servers/{id}/logfiles/{filename}/download— download log fileDELETE /api/servers/{id}/logfiles/{filename}— delete log file
Test Commands
# Frontend unit tests
cd frontend && npx vitest run
# Frontend type check
cd frontend && npx tsc --noEmit
# Backend (no test suite yet)
Key Implementation Notes
BanRepository.create()takesexpires_at(ISO string), notduration_minutes— convert in serviceslot_idis stored as a string in theplayerstable — cast withstr(slot_id)in queries- Config field names in
ServerConfigPydantic model:password_admin(notadmin_password),battleye(notbattle_eye),disable_von(notvon) - Arma 3 log files are located at
{exe_path_parent}/server/*.rpt(next to the .exe), NOT in languard'sservers/{id}/data directory. Code that finds log files must usePath(server["exe_path"]).parentto resolve the log directory. - Config UI schema now covers all ~80 Arma 3 fields across 5 sections (server, basic, profile, launch, rcon) with per-field widget hints (text, toggle, select, number, password, tag-list, hidden, textarea). The
missionsfield in the server section is markedhiddenbecause mission rotation is managed via the dedicated Missions tab.