From a4c0d0603d20ec0fa63bab8fb2df6f2acd9311a7 Mon Sep 17 00:00:00 2001 From: Asger Geel Weirsoee Date: Sun, 1 Mar 2026 20:52:04 +0000 Subject: [PATCH] feat(cutover): harden SPA asset cache busting and rollback playbook (#188) --- ...SSUE-188-SPA-CUTOVER-HARDENING-ARTIFACT.md | 47 +++++++++++++++++++ docs/STAGING_GAMEPLAY_SMOKE_ARTIFACT.md | 3 ++ docs/UI_SMOKE.md | 12 +++++ docs/spa-cutover-flag.md | 30 ++++++++++-- lobby/templates/lobby/spa_shell.html | 4 +- lobby/tests.py | 15 +++++- lobby/ui_views.py | 1 + partyhub/settings.py | 3 ++ 8 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 docs/ISSUE-188-SPA-CUTOVER-HARDENING-ARTIFACT.md diff --git a/docs/ISSUE-188-SPA-CUTOVER-HARDENING-ARTIFACT.md b/docs/ISSUE-188-SPA-CUTOVER-HARDENING-ARTIFACT.md new file mode 100644 index 0000000..38932ae --- /dev/null +++ b/docs/ISSUE-188-SPA-CUTOVER-HARDENING-ARTIFACT.md @@ -0,0 +1,47 @@ +# Issue #188 Artifact — SPA cutover hardening (asset versioning + rollback) + +## Scope +Acceptance for `[READY][SPA][P11] Cutover hardening`: +1. Dokumenteret strategi for cache-busting/versionering af SPA assets i Django staticfiles/reverse proxy setup. +2. Konfigurerbar rollback-procedure for `USE_SPA_UI` (trin-for-trin, target <10 min). +3. Smoke-artefakt for både SPA on/off i samme release-vindue. +4. Ingen gameplay-ændringer. + +## 1) Asset versioning/cache-busting strategi +Implementeret i SPA shell render-path: + +- Konfiguration i `partyhub/settings.py`: + - `WPP_SPA_ASSET_BASE` (eksisterende) + - `WPP_SPA_ASSET_VERSION` (ny) +- `lobby/ui_views.py` injicerer `spa_asset_version` til template-context. +- `lobby/templates/lobby/spa_shell.html` appender `?v={{ spa_asset_version }}` på: + - `styles.css` + - `main.js` + +Effekt: +- Ny release-version (fx SHA/tag) kan tvinge cache-miss i browser/proxy uden ændring af route. +- Rollback kan pege på tidligere stabil version-token med samme mekanisme. + +## 2) Rollback playbook (`USE_SPA_UI`) — target <10 min +Dokumenteret i `docs/spa-cutover-flag.md`: + +1. Sæt `USE_SPA_UI=false`. +2. Sæt `WPP_SPA_ASSET_VERSION` til sidste stabile release-token. +3. Deploy/reload app-processer. +4. Verificér legacy routes (`/lobby/ui/host` + `/lobby/ui/player`). +5. Kør hurtig smoke sanity. +6. Log trigger/timestamp/resultat i smoke artifact. + +## 3) Smoke artifact for SPA OFF/ON i samme release-vindue +Dokumenteret i: +- `docs/UI_SMOKE.md` (sektion: "Samme release-vindue: SPA OFF + ON verifikation") +- `docs/STAGING_GAMEPLAY_SMOKE_ARTIFACT.md` (template udvidet med release-window check + `WPP_SPA_ASSET_VERSION`) + +Krav: +- OFF-pass (legacy) og ON-pass (SPA) køres i samme deploy/release-vindue. +- Begge passes logges i samme artifact med UTC timestamps og version-token. + +## Non-goals bekræftet +- Ingen gameplay-regler ændret. +- Ingen API-kontrakter ændret. +- Ingen UX-redesign; kun drift/cutover-hardening. diff --git a/docs/STAGING_GAMEPLAY_SMOKE_ARTIFACT.md b/docs/STAGING_GAMEPLAY_SMOKE_ARTIFACT.md index 082177b..5be9b5e 100644 --- a/docs/STAGING_GAMEPLAY_SMOKE_ARTIFACT.md +++ b/docs/STAGING_GAMEPLAY_SMOKE_ARTIFACT.md @@ -23,11 +23,14 @@ Formål: levere et lille, ensartet evidensformat for release-nær gameplay-smoke - Active category/questions present: - Participants: host + players - `USE_SPA_UI`: +- `WPP_SPA_ASSET_VERSION`: - UI route used: - OFF (legacy): `/lobby/ui/host` + `/lobby/ui/player` - ON (SPA shell): `/lobby/ui/host/` + `/lobby/ui/player` #### Checks (PASS/FAIL) +0. Same release-window verification + - OFF + ON smoke kørt i samme release-vindue: 1. Cutover route sanity - Flag OFF serves legacy UI templates: - Flag ON serves SPA shell on expected path(s): diff --git a/docs/UI_SMOKE.md b/docs/UI_SMOKE.md index 48446be..d95a135 100644 --- a/docs/UI_SMOKE.md +++ b/docs/UI_SMOKE.md @@ -27,6 +27,18 @@ - Next-round/final leaderboard sanity er PASS. - Ingen nye blocker-regressioner i host/player kerneflow. +## Samme release-vindue: SPA OFF + ON verifikation +Kør begge checks i samme release-vindue (samme deploy/artifact version): + +1. **OFF-pass (legacy)** + - `USE_SPA_UI=false` + - Verificér legacy routes + fuld runde. +2. **ON-pass (SPA)** + - `USE_SPA_UI=true` + - Behold samme release artifact og kun toggl flag/version-token ved behov. + - Verificér SPA shell routes + fuld runde. +3. Dokumentér begge pass i samme smoke-artifact med UTC timestamps og `WPP_SPA_ASSET_VERSION`. + ## Rollback check points Skift straks tilbage til `USE_SPA_UI=false` hvis en gate fejler: 1. Verificér legacy routes (`/lobby/ui/host` + `/lobby/ui/player`) fungerer igen. diff --git a/docs/spa-cutover-flag.md b/docs/spa-cutover-flag.md index 6bf8420..3f9a79c 100644 --- a/docs/spa-cutover-flag.md +++ b/docs/spa-cutover-flag.md @@ -12,6 +12,22 @@ Sæt env var pr. miljø: Backward compatibility under cutover: - Hvis `USE_SPA_UI` ikke er sat, bruges `WPP_SPA_ENABLED` som fallback. +## Static asset versioning/cache-busting (hardening) +Formål: sikre at browser/proxy/CDN hurtigt henter ny SPA bundle i release-vinduet uden at kræve hard refresh. + +- `WPP_SPA_ASSET_BASE` peger fortsat på build-output (`/static/frontend/angular/browser`). +- `WPP_SPA_ASSET_VERSION` injiceres i SPA shell URLs som query-param (`?v=`). +- Anbefalet værdi for `WPP_SPA_ASSET_VERSION`: release-tag eller kort commit SHA. +- Ved rollback sættes `WPP_SPA_ASSET_VERSION` til den tidligere kendte stabile release-værdi. + +Eksempel (staging/prod env): + +```env +USE_SPA_UI=true +WPP_SPA_ASSET_BASE=/static/frontend/angular/browser +WPP_SPA_ASSET_VERSION=rel-2026-03-01-bb82357 +``` + ## Staging rollout-checkliste (`USE_SPA_UI`) 1. **Baseline (flag OFF)** - Bekræft at staging kører med `USE_SPA_UI=false`. @@ -27,15 +43,21 @@ Backward compatibility under cutover: 4. **Post-cutover dokumentation** - Log evidens med commit/head SHA, UTC timestamp og gate-status. -## Rollback-checkpoints (staging) +## Rollback playbook (`USE_SPA_UI`) — mål: <10 min Rollback til legacy (`USE_SPA_UI=false`) udføres straks hvis et checkpoint fejler: - Forkert route/shell for valgt flag i cutover route sanity. - Gameplay smoke kan ikke gennemføres til scoreboard/final leaderboard. - Kritisk regression i host/player flow under smoke. -Efter rollback: -- Bekræft legacy routes virker igen (`/lobby/ui/host` + `/lobby/ui/player`). -- Log rollback-trigger + repro + blocker-link i smoke artifact. +Trin-for-trin: +1. Sæt `USE_SPA_UI=false` i deploy-env. +2. Sæt `WPP_SPA_ASSET_VERSION` til sidste stabile release-token. +3. Deploy/reload app-processer. +4. Verificér legacy routes: `/lobby/ui/host` + `/lobby/ui/player`. +5. Kør hurtig smoke sanity (join/start/scoreboard path). +6. Log UTC tid, trigger, release-token og resultat i smoke artifact. + +Target: rollback + sanity-verifikation inden for 10 minutter. ## Verifikation - Flag OFF: `UiScreenTests.test_legacy_templates_are_used_when_spa_flag_is_off` diff --git a/lobby/templates/lobby/spa_shell.html b/lobby/templates/lobby/spa_shell.html index ec23d90..7846c7a 100644 --- a/lobby/templates/lobby/spa_shell.html +++ b/lobby/templates/lobby/spa_shell.html @@ -4,10 +4,10 @@ WPP SPA Shell - + Indlæser Angular app-shell… - + diff --git a/lobby/tests.py b/lobby/tests.py index 8d047db..9320996 100644 --- a/lobby/tests.py +++ b/lobby/tests.py @@ -1022,7 +1022,8 @@ class UiScreenTests(TestCase): self.assertContains(response, "