feat: add current match page and live kill feed

This commit is contained in:
devRaGonSa
2026-05-21 15:18:03 +02:00
parent 4544cb3c0a
commit da3f1643a2
12 changed files with 703 additions and 50 deletions

View File

@@ -0,0 +1,190 @@
---
id: TASK-150
title: Server card history and current match entrypoints
status: done
type: frontend
team: Frontend Senior
supporting_teams: []
roadmap_item: rcon-full-data
priority: high
---
# TASK-150 - Server card history and current match entrypoints
## Goal
Add server-specific navigation buttons to the home page and make the internal
historical page accept an initial server filter through the URL.
## Background
The home page currently renders live server cards in
`frontend/assets/js/main.js`. Each server card currently has a single
"Historico" action built through `renderServerAction(server)`.
We need clearer per-server actions for the active Comunidad Hispana servers:
- Open the public current scoreboard.
- Open our internal historical page already filtered by that server.
- Open our future internal live/current match page already filtered by that
server.
Important URL correction:
The current public scoreboard URLs are the base scoreboard URLs, without
`/games`:
- `comunidad-hispana-01` -> `https://scoreboard.comunidadhll.es`
- `comunidad-hispana-02` -> `https://scoreboard.comunidadhll.es:5443`
The `/games` URLs are only for the external public historical scoreboard, if
needed later:
- `comunidad-hispana-01` -> `https://scoreboard.comunidadhll.es/games`
- `comunidad-hispana-02` -> `https://scoreboard.comunidadhll.es:5443/games`
## Constraints / DO NOT BREAK
- Do not change backend storage.
- Do not change RCON ingestion.
- Do not change scoreboard correlation logic.
- Do not depend on server #03.
- Do not expose arbitrary URLs received from API payloads.
- Do not remove existing server card live status rendering.
- Do not implement the full live match page in this task.
- Keep the change frontend-focused and minimal.
- Preserve existing responsive layout.
## Allowed Changes
- `frontend/assets/js/main.js`
- `frontend/assets/css/main.css` or equivalent home CSS file
- historical page JS/CSS/HTML files needed to support `?server=`
- optionally add a minimal placeholder `partida-actual.html` if needed to
avoid a broken link
- docs only if needed
## Implementation Requirements
1. Replace the current single "Historico" server-card action with a small
action group.
2. For each active supported server, render these actions:
- "Scoreboard público"
- "Nuestro histórico"
- "Partida actual"
3. "Scoreboard público" must open the current public scoreboard base URL:
- `comunidad-hispana-01` -> `https://scoreboard.comunidadhll.es`
- `comunidad-hispana-02` -> `https://scoreboard.comunidadhll.es:5443`
It must NOT append `/games`.
4. "Nuestro histórico" must open the internal historical page with a server
query parameter:
- `historico.html?server=comunidad-hispana-01`
- `historico.html?server=comunidad-hispana-02`
5. "Partida actual" must open:
- `partida-actual.html?server=comunidad-hispana-01`
- `partida-actual.html?server=comunidad-hispana-02`
6. Add trusted frontend mappings for supported active servers only:
- `comunidad-hispana-01`
- `comunidad-hispana-02`
Do not add server #03.
7. The server identifier should be resolved from the server payload using
`external_server_id` or another already existing stable server slug. If the
server cannot be resolved to a trusted known server, do not render
public/current-match actions for it.
8. Update the historical page initialization so that:
- `?server=comunidad-hispana-01` selects Comunidad Hispana #01 instead of
defaulting to all servers.
- `?server=comunidad-hispana-02` selects Comunidad Hispana #02 instead of
defaulting to all servers.
- unknown or missing server query values fall back to the current default
behavior.
9. If `partida-actual.html` does not exist yet, create a minimal placeholder
page that:
- reads `?server=`
- displays "Partida actual"
- displays the selected server slug/name
- explains that the live detail view will be implemented in the next task
- includes a safe link back to the home page and historical page
Do not implement live data polling yet.
10. Ensure all generated URLs are built from trusted constants, not directly
from API-provided arbitrary values.
## Files to Read First
- `AGENTS.md`
- `ai/architecture-index.md`
- `ai/repo-context.md`
- `ai/orchestrator/frontend-senior.md`
- `frontend/assets/js/main.js`
- historical page files used for the existing server filter flow
## Expected Files to Modify
- `frontend/assets/js/main.js`
- home CSS only if the new action group needs layout styling
- historical page files needed for `?server=` initialization
- `partida-actual.html` only if a placeholder is needed
## Validation
- Run `node --check` on every modified frontend JS file.
- Review `git diff --name-only` and confirm the changed files match this task.
## Manual Verification
1. Open the home page.
2. Verify Comunidad Hispana #01 card shows:
- Scoreboard público
- Nuestro histórico
- Partida actual
3. Verify Comunidad Hispana #02 card shows:
- Scoreboard público
- Nuestro histórico
- Partida actual
4. Click "Scoreboard público" for Comunidad Hispana #01 and verify it opens:
`https://scoreboard.comunidadhll.es`
5. Click "Scoreboard público" for Comunidad Hispana #02 and verify it opens:
`https://scoreboard.comunidadhll.es:5443`
6. Click "Nuestro histórico" for Comunidad Hispana #01 and verify the
historical page loads with Comunidad Hispana #01 selected.
7. Click "Nuestro histórico" for Comunidad Hispana #02 and verify the
historical page loads with Comunidad Hispana #02 selected.
8. Click "Partida actual" for both servers and verify the page opens with the
correct server query parameter.
9. Verify no server #03 action is introduced.
## Commit Message
`feat: add current match server entrypoints`
## Expected Outcome
The home page exposes clear per-server navigation actions, and the internal
historical page can open directly filtered by server.
## Outcome
- Replaced the home server-card history URL path with a trusted frontend action
catalog for active servers `comunidad-hispana-01` and
`comunidad-hispana-02` only. Payload-provided `community_history_url`
values and the previous server #03 fallback are no longer used for those
card actions.
- Added the three per-server entrypoints from trusted constants: public
scoreboard base URL, internal historical filter URL and internal current
match URL.
- Confirmed `frontend/assets/js/historico.js` already normalizes the supported
`?server=` values into the active selector and falls back to `all-servers`
for unknown or missing values, so no historical page code change was needed.
- Added a minimal `partida-actual.html` placeholder with a trusted server label
map and safe internal links for TASK-151 to upgrade.
- Validation: `node --check frontend/assets/js/main.js`.
- Scope review: `git diff --name-only` and `git status --short` were reviewed
for the task move plus frontend files. Browser click verification was not
completed because the in-app browser JavaScript control tool was not
available after tool discovery in this session.
## Change Budget
- Prefer fewer than 5 modified files.
- Prefer changes under 200 lines when feasible.
- Split the work into follow-up tasks if the scope grows.

View File

@@ -0,0 +1,190 @@
---
id: TASK-151
title: Current match page base
status: done
type: frontend
team: Frontend Senior
supporting_teams:
- Backend Senior
roadmap_item: rcon-full-data
priority: high
---
# TASK-151 - Current match page base
## Goal
Create the first functional internal "Partida actual" page for active
Comunidad Hispana servers.
## Background
The home page will link to
`partida-actual.html?server=<server_slug>`. We need the first real version of
our internal current-match page.
This page should be visually aligned with the existing historical match detail
page, but it represents a live match instead of a closed historical match.
Important public scoreboard URLs:
- `comunidad-hispana-01` -> `https://scoreboard.comunidadhll.es`
- `comunidad-hispana-02` -> `https://scoreboard.comunidadhll.es:5443`
These are base URLs for the current public scoreboard and must not include
`/games`.
## Constraints / DO NOT BREAK
- Do not break the existing historical page.
- Do not break the existing match detail page.
- Do not change scoreboard correlation logic.
- Do not implement the live kill feed in this task unless there is already a
safe endpoint that can be reused trivially.
- Do not fabricate closed-match data.
- Do not show final winner/duration/closed_at for a live match.
- Do not depend on server #03.
- Do not expose untrusted public scoreboard URLs.
- Keep polling moderate and safe.
## Allowed Changes
- `partida-actual.html`
- new frontend JS/CSS for current match page
- backend API endpoint only if needed
- backend read-model code only if needed for current live state
- tests where practical
## Implementation Requirements
1. Create or upgrade `partida-actual.html` as a real live-current-match page.
2. The page must read `?server=` from the URL.
3. Supported server values:
- `comunidad-hispana-01`
- `comunidad-hispana-02`
4. Unknown server values must show a safe error/empty state and must not build
external URLs from the unknown value.
5. Add trusted current public scoreboard links:
- `comunidad-hispana-01` -> `https://scoreboard.comunidadhll.es`
- `comunidad-hispana-02` -> `https://scoreboard.comunidadhll.es:5443`
6. Add a "Ver scoreboard público" button using the trusted base URL for that
server.
7. The page should display a live-match header with:
- server name
- live/online status
- current map
- game mode if available
- `started_at` if available
- current players / max players if available
- last updated/captured timestamp
8. The page should display a scoreboard panel:
- allied score if available
- axis score if available
- neutral state if scores are unavailable
9. Do not display:
- final duration
- final winner
- `closed_at`
- any copy implying that the match has finished
10. Add a placeholder section for future live kill feed:
- title: "Feed de combate"
- text explaining that live kill events will appear here when enabled
- no fake kill rows
11. Add a player table section if current player stats are already available
from existing APIs. If they are not available, show a clean placeholder:
- "Las estadísticas en vivo aparecerán cuando haya datos suficientes."
12. Add frontend polling with safe in-flight protection:
- default interval: 30 seconds
- avoid overlapping requests
- show stale/error states clearly
13. If no backend endpoint exists for current match state, add a minimal
endpoint that derives the current server state from existing live/RCON
snapshot data. Keep it read-only.
14. The endpoint response should be stable and minimal:
- server slug/name
- status
- map
- `game_mode`
- `started_at`
- `allied_score`
- `axis_score`
- players
- `max_players`
- `captured_at`/`updated_at`
- `public_scoreboard_url` from trusted mapping
## Files to Read First
- `AGENTS.md`
- `ai/architecture-index.md`
- `ai/repo-context.md`
- `ai/orchestrator/frontend-senior.md`
- current historical match detail frontend files
- live server backend/read-model files used by the existing server cards
## Expected Files to Modify
- `partida-actual.html`
- new current-match frontend JS/CSS files as needed
- minimal live-state backend endpoint/read-model files only if existing APIs
cannot supply the page state
- focused tests where practical
## Validation
- `python -m compileall backend/app`
- Run backend tests relevant to live server/read model if available.
- Run `node --check` on modified/new frontend JS files.
- Review `git diff --name-only` and confirm the changed files match this task.
## Manual Verification
1. Open `partida-actual.html?server=comunidad-hispana-01`.
2. Open `partida-actual.html?server=comunidad-hispana-02`.
3. Verify the public scoreboard button opens:
- `https://scoreboard.comunidadhll.es`
- `https://scoreboard.comunidadhll.es:5443`
4. Verify `/games` is not used for the current public scoreboard button.
5. Verify no final/closed-match fields are shown.
6. Verify unknown server query values do not create unsafe links.
## Commit Message
`feat: add current match page base`
## Expected Outcome
A safe first version of the internal current-match page exists and can display
live server/match state without pretending the match is closed.
## Outcome
- Upgraded `partida-actual.html` into the first internal live match page and
kept it aligned with the existing historical shell/styles.
- Added frontend polling every 30 seconds with an in-flight guard. The page
rejects unknown `?server=` values before building any external link, and the
public scoreboard button is populated only from the trusted backend
projection.
- Added read-only `GET /api/current-match?server=`. It supports only active
trusted scoreboard origins and projects the existing live server snapshot
fields into the current-match shape. The current live snapshot persistence
exposes status, map, population and capture time; score, game mode and match
start fields remain `null`/unavailable when the snapshot source does not
provide them.
- Kept the combat feed and live player statistics as honest empty placeholders
for the follow-up tasks rather than fabricating closed-match or kill data.
- Validation: `python -m compileall backend/app`;
`node --check frontend/assets/js/partida-actual.js`;
`powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`;
narrow inline route guard check for missing/unknown current-match server
values; narrow inline payload projection check using a controlled live
snapshot document.
- Scope review: `git diff --name-only` and `git status --short` were reviewed.
No focused product route test file exists in `backend/tests` for this API
bootstrap layer yet.
## Change Budget
- Prefer fewer than 5 modified files.
- Prefer changes under 200 lines when feasible.
- Split the work into follow-up tasks if the scope grows.

View File

@@ -0,0 +1,174 @@
---
id: TASK-152
title: Current match live kill feed
status: done
type: backend
team: Backend Senior
supporting_teams:
- Frontend Senior
roadmap_item: rcon-full-data
priority: high
---
# TASK-152 - Current match live kill feed
## Goal
Expose recent current-match kill events and render them as a live visual feed
on `partida-actual.html`.
## Background
The current-match page will exist at
`partida-actual.html?server=<server_slug>`. The backend already stores/parses
RCON AdminLog data and materializes kill/player stats for historical matches.
Existing materialization logic uses AdminLog kill payload fields such as:
- `killer_id`
- `killer_name`
- `killer_team`
- `victim_id`
- `victim_name`
- `victim_team`
- `weapon`
We now want a live/current-match kill feed similar to a FPS kill feed: killer,
weapon, victim, teamkill distinction, timestamp.
## Constraints / DO NOT BREAK
- Do not query RCON directly from the frontend.
- Do not expose raw AdminLog lines.
- Do not expose admin-only/sensitive fields.
- Do not break existing historical materialization.
- Do not break existing match detail player stats.
- Do not depend on server #03.
- Do not fabricate kill events.
- Do not duplicate kill rows on repeated polling.
- Keep polling safe.
## Allowed Changes
- backend endpoint for current match kill feed
- backend read-model/helper for current/open match event window
- frontend current-match JS/CSS
- tests for event normalization/filtering where practical
## Implementation Requirements
1. Add a backend endpoint for recent current-match kill events by server.
2. Supported servers:
- `comunidad-hispana-01`
- `comunidad-hispana-02`
3. Unknown server values must return a safe 400/404 style response and must
not query arbitrary targets.
4. The endpoint should return normalized event rows:
- `event_id`
- `event_timestamp` or `server_time`
- `killer_name`
- `killer_team`
- `victim_name`
- `victim_team`
- `weapon`
- `is_teamkill`
- confidence/source if needed
5. The endpoint should only return events belonging to the current/open match
if that can be determined.
6. If the current/open match window cannot be determined reliably, return a
safe recent window and include a clear confidence marker, for example:
- scope: `"recent-admin-log-window"`
- confidence: `"partial"`
7. Do not return raw AdminLog text.
8. Add frontend rendering for a kill feed:
- newest events visible at top or bottom consistently
- killer name
- weapon label/icon placeholder
- victim name
- timestamp
- teamkill visual distinction
9. Prevent duplicate rendering:
- track `event_id` values already rendered
- update existing rows only if needed
10. Poll every 15-30 seconds.
11. Add an empty state:
- "Todavía no se han detectado bajas en esta partida."
12. Add an error/stale state:
- "No se pudo actualizar el feed de combate."
13. Do not show fake/sample kill events in production UI.
## Files to Read First
- `AGENTS.md`
- `ai/architecture-index.md`
- `ai/repo-context.md`
- `ai/orchestrator/backend-senior.md`
- current-match page files created by TASK-151
- AdminLog materialization/read-model files that already normalize kill data
## Expected Files to Modify
- backend current-match kill feed endpoint/read-model files
- current-match frontend JS/CSS files
- focused tests for event normalization/filtering where practical
## Validation
- `python -m compileall backend/app`
- Run backend tests related to AdminLog/materialization/current-match feed.
- Run `node --check` on current-match frontend JS.
- Review `git diff --name-only` and confirm the changed files match this task.
## Manual Verification
1. Open `partida-actual.html?server=comunidad-hispana-01`.
2. Open `partida-actual.html?server=comunidad-hispana-02`.
3. Verify kill feed renders only normalized events.
4. Verify repeated polling does not duplicate rows.
5. Verify teamkills are visually distinguishable.
6. Verify raw AdminLog lines are never displayed.
## Commit Message
`feat: add current match live kill feed`
## Expected Outcome
The current-match page can show a safe, normalized, non-duplicated live kill
feed based on RCON/AdminLog data.
## Outcome
- Added read-only `GET /api/current-match/kills?server=&limit=` for the active
trusted Comunidad Hispana servers. Unsupported servers fail before any
AdminLog query is built.
- Added a safe AdminLog kill feed read that emits normalized fields only:
generated `event_id`, event time/server time, killer/victim names and teams,
weapon, and computed `is_teamkill`. It does not return raw AdminLog text,
player ids or admin-only payload fields.
- Feed scope prefers `open-admin-log-match-window` with
`confidence: "admin-log-boundary"` when the latest AdminLog boundary for the
server is an unmatched `match_start`. Otherwise it returns
`recent-admin-log-window` with `confidence: "partial"` as the explicit
fallback.
- Extended `partida-actual.js` to poll the feed with the existing 30-second
in-flight-protected current-match refresh cycle, dedupe rows by `event_id`,
keep newest events ordered by server/event time, render a TK badge for
teamkills, and show empty/error states without fake rows.
- Added a focused AdminLog storage test for open-window filtering and teamkill
normalization. The environment does not have `pytest` installed (`pytest`
and `python -m pytest` both failed), so the same storage normalization path
was verified with a narrow inline Python scenario.
- Validation: `python -m compileall backend/app`;
`node --check frontend/assets/js/partida-actual.js`;
`powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`;
narrow inline route guard check for missing, unknown and invalid-limit feed
requests; inline storage normalization check excluding pre-window kills and
confirming no raw message field leaks.
- Scope review: `git diff --name-only` and `git status --short` were reviewed.
## Change Budget
- Prefer fewer than 5 modified files.
- Prefer changes under 200 lines when feasible.
- Split the work into follow-up tasks if the scope grows.