diff --git a/README.md b/README.md index 89d2390..a6dda29 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ After login, character creation and play use one dialogue history and one text i During play the UI has no persistent location, task, inventory, economy, status, or purchase panels. The player asks for information or writes an action in the same input. Rust validates state changes; the AI can only propose a typed intent. A direct request to travel may establish a new place and an encounter when Rust commits that movement. +The separate `/admin` route provides an authenticated, read-only operations view for player search/profile/trace, YAML prompt assets, generated Luau rules with validation results, and the append-only audit log. All privileged data comes from the Rust `/api/admin/...` API; the browser never connects directly to PostgreSQL. Backend endpoints require `accounts.is_admin=true`. + The game is text- and dialogue-based and uses no images. Place descriptions include sound, smell, air/temperature, touch/surface, and spatial-orientation cues. Visible details may also be described in words, but are never required to understand the scene or play. The transcript is screen-reader announced, and Enter submits the input while Shift+Enter inserts a newline; no separate send button is required. The browser and API stay on the same public origin, `https://ai-spel.k3s.k0.nu`. The ingress routes `/` to this frontend service and routes `/api`, `/version`, and `/health` to the Rust service. That keeps the current server-side session cookie same-origin and avoids browser CORS configuration. diff --git a/index.html b/index.html index eb0e79b..37663a9 100644 --- a/index.html +++ b/index.html @@ -18,6 +18,11 @@ #dialogue li[data-role="user"] { font-weight: 650; } #dialogue li[data-role="assistant"] { padding-inline-start: .75rem; border-inline-start: .2rem solid currentColor; } #message { width: 100%; min-height: 3.5rem; box-sizing: border-box; } + #admin-content { display: grid; gap: 1rem; } + #admin-content section, #admin-content article { border: 1px solid currentColor; border-radius: .35rem; padding: .75rem; } + #admin-content pre { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 32rem; overflow: auto; } + #admin-toolbar { display: flex; flex-wrap: wrap; gap: .5rem; margin-block: 1rem; } + #player-search { display: flex; flex-wrap: wrap; align-items: end; gap: .5rem; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; } [hidden] { display: none !important; } footer { margin-top: 2rem; border-top: 1px solid; padding-top: .5rem; color: GrayText; font-size: .875rem; } @@ -43,11 +48,25 @@ Tryck Enter för att skicka. Tryck Skift och Enter för ny rad. + diff --git a/scripts/check-frontend.sh b/scripts/check-frontend.sh index dd4f2e1..d324e4b 100755 --- a/scripts/check-frontend.sh +++ b/scripts/check-frontend.sh @@ -12,6 +12,11 @@ grep -q "event.key === 'Enter' && !event.shiftKey" index.html grep -q "request('/api/character/draft'" index.html grep -q "request('/api/world/draft'" index.html grep -q "request('/api/dialogue'" index.html +grep -q 'id="admin-view"' index.html +grep -q '/api/admin/players?' index.html +grep -q "request('/api/admin/prompts'" index.html +grep -q "request('/api/admin/rules'" index.html +grep -q '/api/admin/audit?limit=200' index.html grep -q "request('/api/world/start'" index.html grep -q "request('/api/character'" index.html grep -q 'location = /healthz' nginx/default.conf