Files
languard-servers-manager/CLAUDE.md
Tran G. (Revernomad) Khoa bf09a6ed1c fix: fix Arma 3 log discovery and improve config editor UX
- 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
2026-04-18 15:56:04 +07:00

93 lines
4.5 KiB
Markdown

# Languard Server Manager
## Quick Start
```bash
# 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 via `python -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 `onEvent` callback 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 hints
- `GET|PUT /api/servers/{id}/missions/rotation` — mission rotation with optimistic locking
- `POST /api/servers/{id}/players/{slot_id}/kick` — kick via RCon
- `POST /api/servers/{id}/players/{slot_id}/ban` — ban via RCon + DB record
- `GET /api/servers/{id}/logfiles` — list `.rpt` log files
- `GET /api/servers/{id}/logfiles/{filename}/download` — download log file
- `DELETE /api/servers/{id}/logfiles/{filename}` — delete log file
## Test Commands
```bash
# 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()` takes `expires_at` (ISO string), not `duration_minutes` — convert in service
- `slot_id` is stored as a string in the `players` table — cast with `str(slot_id)` in queries
- Config field names in `ServerConfig` Pydantic model: `password_admin` (not `admin_password`), `battleye` (not `battle_eye`), `disable_von` (not `von`)
- **Arma 3 log files** are located at `{exe_path_parent}/server/*.rpt` (next to the .exe), NOT in languard's `servers/{id}/` data directory. Code that finds log files must use `Path(server["exe_path"]).parent` to 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 `missions` field in the server section is marked `hidden` because mission rotation is managed via the dedicated Missions tab.