From e7c92eacef399b58d543f31f87edfcba45f7c3cd Mon Sep 17 00:00:00 2001 From: Lucas Kalil Date: Thu, 18 Jun 2026 18:25:50 -0300 Subject: [PATCH] docs: drop DATA_VERSION from workflow and project memory --- .agents/TODO.md | 8 ++++---- .agents/issues.md | 14 ++++++++------ .agents/project-memory.md | 36 ++++++++++++++++++++---------------- .agents/stats-screen-plan.md | 9 +++++---- how-refresh-data.md | 19 +++++++++---------- 5 files changed, 46 insertions(+), 40 deletions(-) diff --git a/.agents/TODO.md b/.agents/TODO.md index a44ce8b..341bd3f 100644 --- a/.agents/TODO.md +++ b/.agents/TODO.md @@ -68,7 +68,7 @@ Use checkboxes to track progress. Items marked **🔴 BLOCKER** prevent release; ### 🟢 OPTIONAL - [x] ~~PWA Tier 1 — instalável (manifest + ícones + meta tags; 2026-06-16). Atende todos os critérios de aceitação da issue.~~ -- [ ] PWA Tier 2 — service worker + offline (deferido; ver `.agents/issues.md` → "PWA Tier 2". DEVE excluir `data/*.json` do cache p/ não quebrar o live-refresh + `DATA_VERSION`). +- [ ] PWA Tier 2 — service worker + offline (deferido; ver `.agents/issues.md` → "PWA Tier 2". DEVE excluir `data/*.json` do cache p/ não quebrar o live-refresh). --- @@ -88,13 +88,13 @@ champion path, debuts champion) once the final lands. The **data-layer stages (G - [x] ~~Stage D — auto record-cards + "format-48 debuts" band~~ - [x] ~~Stage E — in-tab results archive~~ — **SKIPPED (Option B):** kept the "See all matches → Matches" link; the Matches tab already covers browsing. - [x] ~~Stage F — team comparator (diverging bars)~~ — teams only; the Teams/Players toggle is deferred to Stage H per graceful degradation. -- [x] ~~Stage J (round 1, release polish) — a11y/responsive/i18n/README audit on A–F~~ — passed clean (no code fixes). **Lighthouse + final `DATA_VERSION` bump still pending an actual deploy.** +- [x] ~~Stage J (round 1, release polish) — a11y/responsive/i18n/README audit on A–F~~ — passed clean (no code fixes). **Lighthouse still pending an actual deploy** (the once-planned final `DATA_VERSION` bump is moot — `DATA_VERSION` removed 2026-06-18). ### 🔭 Future (data layers + 2nd polish — near/after the Cup) -- [ ] **Stage G — Layer 2 cheap data.** Extend `results.json` (attendance, **`cards`→{y,r} migration** — breaking for `modal.js` + `stats.js` `aggregateTeams`, add a backward-compatible reader; `decidedIn`; backfill `stats`), `teams.json` (`ranking`/`wcDebut`/`confederation`), `stadiums.json` (`lat`/`lng`). Light up records: attendance, discipline/fair-play, ranking upsets, confederation performance, distance. **SCHEDULE LATE — conflicts with master's daily `results.json` refreshes.** Bump `DATA_VERSION`. +- [ ] **Stage G — Layer 2 cheap data.** Extend `results.json` (attendance, **`cards`→{y,r} migration** — breaking for `modal.js` + `stats.js` `aggregateTeams`, add a backward-compatible reader; `decidedIn`; backfill `stats`), `teams.json` (`ranking`/`wcDebut`/`confederation`), `stadiums.json` (`lat`/`lng`). Light up records: attendance, discipline/fair-play, ranking upsets, confederation performance, distance. **SCHEDULE LATE — conflicts with master's daily `results.json` refreshes.** - [ ] **Stage H — Layer 3 players.** `players.json` + `player-events.json` + `awards.json` (+ optional `keeper-stats.json`). Top-scorers podium, assists/cards/saves chips, awards block, Squad of the Tournament, **Teams/Players toggle in the comparator** (the deferred half of Stage F), goal-time records. Relative photo paths (gotcha #7). - [ ] **Stage I — Layer 4 editorial.** `curiosities.json` (bilingual EN+PT) + `all-time-baselines.json`; editorial record-cards + "this Cup vs history" panel. -- [ ] **Stage J (round 2) — polish over the NEW G/H/I features.** Repeat the audit on the added sections (a11y/responsive/perf, Lighthouse, EN/PT review) + bump `DATA_VERSION` for the new data files + README refresh. +- [ ] **Stage J (round 2) — polish over the NEW G/H/I features.** Repeat the audit on the added sections (a11y/responsive/perf, Lighthouse, EN/PT review) + README refresh. --- diff --git a/.agents/issues.md b/.agents/issues.md index bbd891e..637c7fb 100644 --- a/.agents/issues.md +++ b/.agents/issues.md @@ -73,16 +73,17 @@ Chrome/Edge. ### Why deferred (the real risk) A naïve precaching SW would cache `data/*.json` and **silently defeat the 2026-06-16 live-refresh -system** (the 90s `results.json` poll with `cache:'no-store'` + the `DATA_VERSION` cache-buster) — -open tabs would stop seeing new scores, and `DATA_VERSION` bumps would do nothing. It would also make +system** (the 90s `results.json` poll with `cache:'no-store'`, plus the `?t=Date.now()` cache-buster +on every data fetch) — open tabs would stop seeing new scores. It would also make the "stale JS module" gotcha (#5) *permanent* (cached assets live until the cache name changes). ### How to implement (if revisited) — constraints, not optional 1. **Never cache `data/*.json`.** Use network-only, or network-first with the cache only as an offline fallback (so an offline launch shows the last-seen results). The 90s poll must stay the owner of freshness. -2. **Version the SW cache** with a constant mirroring/derived from `DATA_VERSION`; clean up old caches - on `activate` — otherwise every code deploy risks serving stale JS forever (gotcha #5). +2. **Version the SW cache** with a dedicated cache-name constant bumped on each deploy (there is no + longer a `DATA_VERSION` to mirror — data freshness is handled by `?t=Date.now()`); clean up old + caches on `activate` — otherwise every code deploy risks serving stale JS forever (gotcha #5). 3. **Register at the subpath** (`worldcup2026/sw.js`) so the SW scope matches the deploy (gotcha #7); keep `start_url`/`scope` relative as they already are. 4. App-shell strategy: cache-first (versioned) for `index.html` + `assets/css` + `assets/js` + @@ -109,8 +110,9 @@ published `results.json` (daily push) only appeared after F5. - **Not a live-feed problem.** `results.json` is a manual post-match push, so there is no new server data *during* a match — a faster "during live" poll buys nothing. A **fixed** 90s poll is correct; dynamic/state-based polling was rejected (complexity for no gain, double-schedule risk per gotcha #6). -- **Cache-busting must use `?t=${Date.now()}` + `cache:'no-store'`, NOT `?v=DATA_VERSION`** — that - constant is frozen in the open tab and Hostinger sends no cache headers (gotcha #2). +- **Cache-busting must use `?t=${Date.now()}` + `cache:'no-store'`** — a frozen per-tab constant + would never refetch and Hostinger sends no cache headers. (As of 2026-06-18 the initial + `loadData()` fetch also uses `?t=Date.now()`; the old `?v=DATA_VERSION` constant was removed.) - **Signature = full response text**, not a finished-count (a count misses score corrections, `stats` backfill on an already-finished match, and added penalties). - **`thirdPlaceAssignment` lives in `bracket-config.json`, not `results.json`** → on a detected change diff --git a/.agents/project-memory.md b/.agents/project-memory.md index c2e4b05..52917ff 100644 --- a/.agents/project-memory.md +++ b/.agents/project-memory.md @@ -138,8 +138,9 @@ automated tests / linter (explicit spec constraint). - The data is **not live** — it's a manual push after each match. So poll is **fixed** (`POLL_INTERVAL_MS = 90s`), not state-based. `startResultsPolling()` (called at the end of `init()`, after views register listeners) arms one `setInterval` (`if (pollTimer) return`). - `pollResults()` fetches `data/results.json?t=${Date.now()}` with `cache:'no-store'` — **NOT** - `?v=DATA_VERSION` (frozen in the tab + no Hostinger cache headers → would serve cached; gotcha #2). + `pollResults()` fetches `data/results.json?t=${Date.now()}` with `cache:'no-store'`. (As of + 2026-06-18 the initial `loadData()` fetch also uses `?t=Date.now()`; the old hand-bumped + `?v=DATA_VERSION` cache-buster was removed — see Cache-busting runbook.) - **Signature = full response text** (catches score corrections, `stats` backfill, penalties — a finished-count signature would miss them). On change: rewrite `data.results` **and rebuild `data.resultByMatchId`** (the derived map), `invalidateBracket()`, dispatch `datachange`. @@ -200,8 +201,8 @@ automated tests / linter (explicit spec constraint). ### Daily data refresh Follow **`how-refresh-data.md`** (project root) before touching any `data/*.json`. In short: edit -`data/results.json` (scores/status, two-source rule, `penalties` only on knockout ids 73–104) → bump -`DATA_VERSION` → verify in preview → commit (two-commit convention) → push (user's go) → deploy. +`data/results.json` (scores/status, two-source rule, `penalties` only on knockout ids 73–104) → +verify in preview → commit (two-commit convention) → push (user's go) → deploy. Frozen files (never edit): `stadiums/teams/groups/bracket-config.round32/assets/code`. `how-update.md` stays as the schema reference for the (completed) mock→real migration. @@ -221,13 +222,15 @@ letter appears in **at most one** slot; unfilled slots stay `null`: | 7 | M85 (vs Winner B) | E/F/G/I/J | | 8 | M87 (vs Winner K) | D/E/I/J/L | -### DATA_VERSION (cache-busting) -`app.js` `loadData()` appends `?v=${DATA_VERSION}` to every `data/*.json` fetch (constant near the -top, currently `'2026-06-17-rev3'`). **Bump on every data refresh** (format `YYYY-MM-DD-revN`; -increment `revN` for same-day re-edits). The live-refresh poll deliberately uses `?t=` + `no-store` -instead (see Live data refresh). Note: **JS/CSS are not versioned** (no build step) — on Hostinger -returning visitors may serve stale code until their browser re-fetches; new visitors / hard-refresh -see it at once. Accepted. +### Cache-busting (2026-06-18: DATA_VERSION removed) +`app.js` `loadData()` appends `?t=${Date.now()}` to every `data/*.json` fetch — same scheme the +live-refresh poll already used. **There is no `DATA_VERSION` constant to bump anymore** (removed +2026-06-18); every load gets a unique URL, so Hostinger can never serve a stale `results.json` and +the daily refresh has zero cache step. ~~Previously appended `?v=${DATA_VERSION}` (a hand-bumped +`YYYY-MM-DD-revN` constant) — retired because the manual bump was easy to forget and `Date.now()` +guarantees freshness.~~ Note: **JS/CSS are not versioned** (no build step) — on Hostinger returning +visitors may serve stale code until their browser re-fetches; new visitors / hard-refresh see it at +once. Accepted. ### App version (footer) Single source of truth: **`assets/js/i18n.js` line 9** — `const APP_VERSION = 'v1.0.X'`. Auto-shown @@ -236,7 +239,7 @@ bugfix, schema change, deploy). Commit e.g. `refactor(footer): bump version to v ### Commit convention (standardized 2026-06-15) Every `/update-worldcup` run = **two commits** (full spec in `how-refresh-data.md`): -1. **Data commit** (`results.json` + `DATA_VERSION`, + `bracket-config.json` on the 3rd-place day): +1. **Data commit** (`results.json`, + `bracket-config.json` on the 3rd-place day): - 1 game → `data: update DD/MM/YYYY HH:MM HOMExAWAY HxA` - N games → `data: update DD/MM/YYYY — N jogos` + one body line per game. - Penalties (knockout only): suffix `(pen HxA)`. @@ -360,7 +363,8 @@ variant (Option C) was the recommended shape. Polish over A–F: i18n audit (no hardcoded strings), a11y (sections `aria-label`led + `tabindex=-1`, table caption + sort buttons + `aria-sort`, sub-nav is a `