Files
languard-servers-manager/backend/core/servers/players_router.py
Tran G. (Revernomad) Khoa 6511353b55 feat: implement full backend + frontend server detail, settings, and create server pages
Backend:
- Complete FastAPI backend with 42+ REST endpoints (auth, servers, config,
  players, bans, missions, mods, games, system)
- Game adapter architecture with Arma 3 as first-class adapter
- WebSocket real-time events for status, metrics, logs, players
- Background thread system (process monitor, metrics, log tail, RCon poller)
- Fernet encryption for sensitive config fields at rest
- JWT auth with admin/viewer roles, bcrypt password hashing
- SQLite with WAL mode, parameterized queries, migration system
- APScheduler cleanup jobs for logs, metrics, events

Frontend:
- Server Detail page with 7 tabs (overview, config, players, bans,
  missions, mods, logs)
- Settings page with password change and admin user management
- Create Server wizard (4-step; known bug: silent validation failure)
- New hooks: useServerDetail, useAuth, useGames
- New components: ServerHeader, ConfigEditor, PlayerTable, BanTable,
  MissionList, ModList, LogViewer, PasswordChange, UserManager
- WebSocket onEvent callback for real-time log accumulation
- 120 unit tests passing (Vitest + React Testing Library)

Docs:
- Added .gitignore, CLAUDE.md, README.md
- Updated FRONTEND.md, ARCHITECTURE.md with current implementation state
- Added .env.example for backend configuration

Known issues:
- Create Server form: "Next" buttons don't validate before advancing,
  causing silent submit failure when fields are invalid
- Config sub-tabs need UX redesign for non-technical users
2026-04-17 11:58:34 +07:00

57 lines
1.7 KiB
Python

"""Player endpoints — list current players for a running server."""
from __future__ import annotations
import logging
from typing import Annotated
from fastapi import APIRouter, Depends
from sqlalchemy.engine import Connection
from core.dal.player_repository import PlayerRepository
from core.servers.service import ServerService
from database import get_db
from dependencies import get_current_user
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/servers/{server_id}/players", tags=["players"])
def _ok(data):
return {"success": True, "data": data, "error": None}
@router.get("")
def list_players(
server_id: int,
db: Annotated[Connection, Depends(get_db)],
_user: Annotated[dict, Depends(get_current_user)],
) -> dict:
"""List current players (cached from RemoteAdminPollerThread)."""
ServerService(db).get_server(server_id) # raises 404 if not found
player_repo = PlayerRepository(db)
players = player_repo.get_all(server_id=server_id)
count = player_repo.count(server_id=server_id)
return _ok({
"server_id": server_id,
"player_count": count,
"players": players,
})
@router.get("/history")
def player_history(
server_id: int,
db: Annotated[Connection, Depends(get_db)],
_user: Annotated[dict, Depends(get_current_user)],
limit: int = 100,
offset: int = 0,
search: str | None = None,
) -> dict:
"""Get historical player sessions."""
ServerService(db).get_server(server_id) # raises 404 if not found
player_repo = PlayerRepository(db)
total, rows = player_repo.get_history(
server_id=server_id, limit=limit, offset=offset, search=search,
)
return _ok({"total": total, "items": rows})