Skip to content

Seed a staging test user with games in every state - #1405

Merged
johnpooch merged 2 commits into
mainfrom
claude/intelligent-fermi-1d23md
Sep 27, 2026
Merged

johnpooch merged 2 commits into
mainfrom
claude/intelligent-fermi-1d23md

Conversation

@johnpooch

@johnpooch johnpooch commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

What this PR does

Staging testing relied on a real production account, and its state drifted. Its commitment rating fell to low, which blocks game creation, and there was no reliable way to reach specific game states. This PR adds a seed_staging management command, and staging deploys now run it, so you can log in as test-user@example.com / password as soon as the backend is up.

The command creates the tester, eight opponents and a DumbBot. It then builds 24 games through the real managers and adjudicator. Phases are resolved with Phase.objects.resolve, and civil disorder, eliminations, victories and draw acceptance all come from the production code paths. The games cover these states:

  • Finished: you won solo, another player won solo, five-way draw (with players in civil disorder excluded), abandoned
  • Active:
    • you are in civil disorder
    • you missed the last deadline (NMR)
    • other players in civil disorder, plus a replaced seat
    • a seat you can take over as a spectator
    • you were eliminated
    • retreat phase
    • adjustment (build) phase
    • mid-game with public and private messages you haven't read, and NMR extensions
    • draw proposed and waiting on your vote, plus a rejected one
    • orders required (with a bot)
    • orders not confirmed (anonymous game)
    • orders confirmed (no-press game)
    • paused
  • Pending: you created it, you are the game master, you joined someone else's game
  • Find Games: one seat left (joining starts the game), committed players only, gunboat Italy vs Germany with fixed daily deadlines
  • a sandbox game

A few details:

  • Games involving the tester use two-week deadlines, so they stay put while you test.
  • Scenarios where the tester misses orders are in private games, which don't count toward commitment. The tester therefore ends up with high commitment. The test checks this through the API.
  • Safety: the command refuses to run unless DEBUG=True or ENVIRONMENT=staging. Each run deletes the games it seeded last time (found by the seeded users) and seeds them again. You can also run it locally.

How it runs on staging: the workflow sets SEED_STAGING_DATA=True on the staging Django service. When that is set, entrypoint.sh runs seed_staging --skip-if-seeded after migrations and before Gunicorn starts. A container restart keeps your test state, and a redeploy re-clones the database and seeds fresh. The PR comment now lists the login.

I didn't run the command from the Actions runner. A seed is about 6.7k queries, and at internet latency to Railway's public DB proxy that would take minutes. Inside the container it takes about 15s.

Also noted, but not changed here: deleting a game that has a replaced member fails the member_unique_nation_per_game constraint. The cascade nulls replaced_by before it deletes the rows. The seed works around this in its cleanup.

Checklist

  • This PR does one thing — no unrelated fixes, refactors, or drive-by cleanups bundled in
  • For PRs of any significant complexity: I ran /review-pr against this PR in Claude Code and addressed (or responded to) its findings
  • Tests cover the change: TestSeedStagingCommand in service/game/tests.py checks every state through the games list, draw-proposal, profile and login endpoints. It also covers the guard, re-seeding and --skip-if-seeded.
  • Screenshots embedded in the PR description for any visual changes: this PR changes no web code. I checked the seeded data locally in the web app (My Games tabs and Find Games) and it renders as expected.

Verified on a real staging deploy of this PR: the seed ran at startup, the tester login worked, and every game was in its expected state with high commitment. The account was then still staging-tester@example.com; it was renamed to test-user@example.com afterwards, and production has no user with that email or the test-user username. If the staging service has a short healthcheck timeout, the extra ~15–30s at startup is worth watching. harness/tests.py::TestQualityMetricAggregation::test_accuracy_covers_ranked_samples_and_skips_the_rest also fails on main without this change.

🤖 Generated with Claude Code

https://claude.ai/code/session_017MmHa6RT4ZtHZueLJEZnkD

Adds a seed_staging management command that creates a login user
(staging-tester@example.com), opponents and a bot, then builds games
through the real managers and adjudicator: pending, joinable, active at
each order status, retreat and adjustment phases, civil disorder,
eliminated, paused, draw proposed, solo win and loss, draw and abandoned.
It refuses to run unless DEBUG or ENVIRONMENT=staging, and each run
replaces the games it seeded before.

The PR staging workflow sets SEED_STAGING_DATA=True on the Django
service, and the entrypoint seeds (once per database clone) before
Gunicorn starts, so the data is next to the database rather than
thousands of round trips away on the Actions runner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017MmHa6RT4ZtHZueLJEZnkD
@github-actions

Copy link
Copy Markdown
Contributor

Warning

WIP limit exceeded. There are now 6 open pull requests — the project target is 5 or fewer.

Please close or merge an existing PR before continuing with this one.

@johnpooch johnpooch added the deploy-to-staging Trigger staging environment deployment label Sep 27, 2026
@github-actions github-actions Bot removed the deploy-to-staging Trigger staging environment deployment label Sep 27, 2026
@railway-app
railway-app Bot temporarily deployed to devoted-rejoicing / staging-pr-1405 September 27, 2026 11:29 Inactive
@github-actions

Copy link
Copy Markdown
Contributor

Staging Environment Deployed

Frontend preview: https://deploy-preview-1405--diplicity-react.netlify.app
Staging backend: https://diplicity-react-staging-pr-1405.up.railway.app

The staging backend has a copy of the production database from the daily snapshot taken at Sun, 27 Sep 2026 07:31:24 GMT, with migrations from this PR applied.
Use email/password login to test (Google OAuth is not configured for staging).

Log in as staging-tester@example.com / password to find seeded games in every state (pending, active, finished, civil disorder, draws, solo wins and more). The seed runs on the backend at startup, so the games appear once the backend is ready.

The frontend preview derives its backend URL from the PR number at build time.
Refresh the preview page once the staging backend is ready.
To redeploy, add the deploy-to-staging label again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017MmHa6RT4ZtHZueLJEZnkD
@johnpooch
johnpooch merged commit 7233270 into main Sep 27, 2026
22 checks passed
@johnpooch
johnpooch deleted the claude/intelligent-fermi-1d23md branch September 27, 2026 11:49
@github-actions

Copy link
Copy Markdown
Contributor

Staging Environment Torn Down

The staging environment for this PR has been removed.

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.

2 participants