Files
comunidadhll/ai/tasks/done/TASK-253-polish-player-profile-kpm-links-and-labels.md
2026-06-11 14:21:45 +02:00

3.8 KiB

TASK-253 - Polish player profile KPM, links and labels

Summary

This task improves the public player profile in stats.html without changing the validated historical match-detail KPM model.

Changes included:

  • real weekly/monthly profile KPM when safe
  • no visible raw player ID in the personal profile card or profile heading
  • translated current-week / current-month labels
  • external profile buttons aligned with historico-partida

Teamkills were not changed here. TASK-251 remains the reference audit for that problem.

Files Read First

  • frontend/stats.html
  • frontend/assets/js/stats.js
  • frontend/assets/js/historico-partida.js
  • backend/app/payloads.py
  • backend/app/rcon_historical_player_stats.py
  • docs/HISTORICAL_MATCH_KILLS_PER_MINUTE_ANALYSIS.md

Real KPM Decision

The player profile does not use match duration and does not reuse kills_per_match.

It now exposes real KPM only when the selected weekly or monthly window can aggregate player facts with:

  • active_time_source = connection_intervals
  • active_time_source = connection_intervals_carryover
  • player_active_seconds >= HLL_KPM_MIN_ACTIVE_SECONDS

Formula:

sum(eligible_kills) / (sum(eligible_player_active_seconds) / 60)

If the profile window has:

  • no active time -> kpm_status = missing_active_time
  • only fallback spans without reliable connection intervals -> kpm_status = missing_connection_intervals
  • real connection rows but below threshold -> kpm_status = insufficient_active_time

Only kpm_status = ready is rendered in the frontend.

Backend Notes

build_stats_player_profile_payload(...) now exposes:

  • platform
  • steam_id_64
  • epic_id
  • external_profile_links
  • player_active_seconds
  • player_active_minutes
  • kpm
  • kpm_status
  • active_time_source
  • active_time_coverage

If player_period_stats is unavailable for the requested weekly/monthly profile, the endpoint now falls back to runtime aggregation for that single player and window instead of returning an empty read-model-only payload.

This keeps the route useful without touching scheduler or snapshot policies.

Frontend Notes

Profile polish in stats.js:

  • removed visible ID: from the identity card
  • removed raw player ID from the visible profile heading/state
  • translated:
    • current-week -> Semana actual
    • current-month -> Mes actual
    • fallback labels for previous windows
  • added external profile buttons using the same destinations as historico-partida
  • keeps defensive image onerror
  • renders KPM only when kpm_status == ready

Profile buttons by platform:

  • Steam:
    • Steam
    • Hellor
    • HLL Records
    • Helo
  • Epic:
    • Hellor
    • HLL Records

Teamkills Note

No teamkills fix was implemented here.

Reference:

  • TASK-251-investigate-teamkills-ranking-zeroes.md

Observed state remains:

  • rcon_match_player_stats.teamkills stays at zero in the audited dataset
  • same-team kill events were not present in the audited AdminLog dataset
  • lifetime profile snapshots can show TK counters, but they are not a valid direct source for annual ranking without redesign/backfill

Validation

Executed:

  • node --check frontend/assets/js/stats.js
  • python -m compileall backend/app
  • cd backend; python -m unittest tests.test_current_match_payload
  • cd backend; python -m unittest tests.test_historical_snapshot_refresh
  • cd backend; python -m unittest tests.test_stats_player_profile_payload

Static checks:

  • no visible ID: remains in the personal profile card
  • current-week / current-month no longer remain as visible UI labels
  • external profile buttons do not print raw IDs on screen
  • KPM is rendered only for kpm_status == ready

Notes

  • No scheduler changes.
  • No RCON or server configuration changes.
  • No asset changes were required.