Skip to content

Encounter stats: store map_point_history on Mongo + backfill script#337

Merged
ptrlrd merged 1 commit into
mainfrom
fix/encounter-stats-mongo-backfill
May 22, 2026
Merged

Encounter stats: store map_point_history on Mongo + backfill script#337
ptrlrd merged 1 commit into
mainfrom
fix/encounter-stats-mongo-backfill

Conversation

@ptrlrd
Copy link
Copy Markdown
Owner

@ptrlrd ptrlrd commented May 22, 2026

Fixes the empty /api/runs/encounter-stats response that shipped in #336. Submitted runs now carry map_point_history on their Mongo doc, and a single-pass backfill populates it for the existing ~9.9K docs by reading their on-disk JSON.

Why

The aggregation walks $map_point_history to compute per-encounter sample counts, fatal counts, average damage, and average turns. The field was never stored on the run doc; only denormalized fields (killed_by, deck, relics, card_choices) were. Disk JSONs are the source of truth (the share-run page already reads from there).

Changes

  • submit_run includes map_point_history in the inserted doc going forward. All new submissions populate the field automatically.
  • tools/backfill_run_encounters_mongo.py finds every Mongo doc missing the field and $sets it from the corresponding disk JSON. Idempotent. Supports --dry-run and --limit N for spot-checks.

After-merge ops

ssh prod 'cd /var/www/spire-codex && \
  docker compose -f docker-compose.prod.yml exec backend \
    python3 -m tools.backfill_run_encounters_mongo'

Same against docker-compose.beta.yml for the beta site.

The hourly autodeploy cron will pull the new backend image but won't run the backfill itself. Operator runs the command above once after the first deploy carrying this change.

… script

The /api/runs/encounter-stats endpoint shipped in #336 returned zero rows
because the aggregation walks $map_point_history but that field was
never stored on the run doc — only denormalized fields (killed_by, deck,
relics, card_choices) were. The raw history lives on disk at
data/runs/<hash>.json (which the share-run page already reads).

Two changes:

1. submit_run now includes map_point_history in the inserted doc. Going
   forward, every new submission populates the field so the aggregation
   has data to walk.

2. tools/backfill_run_encounters_mongo.py reads every disk JSON whose
   corresponding Mongo doc is missing the field and $sets it. Idempotent
   — safe to re-run, processes ~5K docs/sec.

Operator run after deploy:

  ssh prod 'cd /var/www/spire-codex && docker compose -f docker-compose.prod.yml exec backend python3 -m tools.backfill_run_encounters_mongo'

(Beta box runs the same script against the beta compose file.)
@ptrlrd ptrlrd merged commit 7ee1c68 into main May 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant