# Period selector missing older months — diagnosis ## Context User reports the "From / To" period selector on the **adults** dashboard now shows **Dec 2025** as the oldest available period. The older production deployment shows Sep+Oct 2025, Nov 2025, Dec 2025+Jan 2026 (merged labels) — i.e. data going back to September 2025. The user wants to know what went sideways. Confirmed: the dropdown options on both Python and Go genuinely start at Dec 2025, not just the default selection — Sep/Oct/Nov 2025 are not in the list at all. ## Root cause — the live adults sheet header is missing those columns The fresh cache files at `tmp/go/attendance_regular_cache.json` (raw rows from Google Sheets, modifiedTime `2026-05-06T22:30:02Z`, cached `2026-05-08T00:26`) contain the actual header row for the adults tab (gid=0): ```text ['FUJ tréninky úterý 20:30-22:00', '', '', '02.12.2025', '09.12.2025', '16.12.2025', '06.01.2026', '13.01.2026', '20.01.2026', '27.01.2026', '03.02.2026', '10.02.2026', '17.02.2026', '24.02.2026', '03.03.2026', '10.03.2026', '17.03.2026', '23.03.2026', '31.03.2026', '13.04.2026', '20.04.2026', '27.04.2026', '04.05.2026', '', '', ''] ``` **The first date column in the live adults sheet is `02.12.2025` (Dec 2 2025).** There are no September, October, or November 2025 columns in the header at all. Both backends parse this faithfully (no slicing, no cutoff anywhere) and correctly produce `sortedMonths = ["2025-12", "2026-01", …, "2026-05"]`. The juniors sheet (different tab, `JUNIOR_SHEET_GID`) is **fine** — its header still contains `['', 'tier', '', '15.09.2025', '13.10.2025', '20.10.2025', '03.11.2025', '24.11.2025', '10.11.2025', '17.11.2025', '01.12.2025', …]`. So the juniors page still shows Sep+Oct / Nov / Dec+Jan correctly. So this is a **data issue in the adults attendance Google Sheet**: at some point between when production's cache was last warmed (showing Sep–Nov) and 2026-05-06, somebody (or some action) removed the columns for September, October, and November 2025 from the adults tab header. The code is doing exactly what it should. There is no parser regression. ## What to do ### 1. Restore the missing date columns in the adults attendance sheet The fix lives in Google Sheets, not in the codebase. Options, in order of preference: - **(a) Use Sheets version history.** File → Version history → See version history; find a version from before the columns were dropped (anything before about Mar 2026 should still have them). Copy the Sep/Oct/Nov 2025 date column headers and the `TRUE/FALSE` cells underneath them back into the current sheet. Only restore the 11 missing date columns; do not full-revert (you'd lose every change since then). - **(b) Pull from the production server's cache.** The production deployment evidently still has the older cache, since its dashboard renders those months. SSH there, copy `tmp/attendance_regular_cache.json`, and you can reconstruct the per-member Sep/Oct/Nov attendance counts from the `data[*][2]` map (keys `"2025-09"`, `"2025-10"`, `"2025-11"`). Re-enter those into the sheet manually as date columns + `TRUE` cells — tedious but deterministic. - **(c) Accept the loss.** If the older columns aren't recoverable, the dashboard correctly reflects what the sheet contains; nothing more to do. Which to pick depends on whether those months still need to be billed / reconciled. ### 2. Restore `ADULT_MERGED_MONTHS` (user confirmed this was unintentional) Independent of the sheet issue: commit `1257f0d` (Mar 9 2026) commented out the adult merge mappings. Once the Sep/Oct/Nov columns are back in the sheet, the dashboard would still show them as separate periods instead of the production-style "Sep+Oct 2025" and "Dec 2025+Jan 2026" merged labels. User confirmed this was unintentional. Two files to update: - [scripts/attendance.py:32-35](scripts/attendance.py#L32-L35) — uncomment the two mappings: ```python ADULT_MERGED_MONTHS = { "2025-12": "2026-01", # keys are merged into values "2025-09": "2025-10", } ``` - [go/internal/services/membership/sources.go:30](go/internal/services/membership/sources.go#L30) — mirror the same: ```go var AdultMergedMonths = map[string]string{ "2025-12": "2026-01", "2025-09": "2025-10", } ``` After this change, hit `POST /flush-cache` on each backend so the in-process post-processed adults cache is rebuilt with the new mapping. ### 3. (Optional, separate) Fix the JS auto-default that hides older months This is **not** the cause of the user's current symptom (that's the sheet issue), but it will become a UX issue once Sep/Oct/Nov columns are restored: the Python frontend's `defaultFrom = Math.max(0, maxMonthIdx - 4)` will still default the From-selector to ~5 months before the latest column on every page load, hiding restored older months until the user manually picks them. - [templates/adults.html:1047](templates/adults.html#L1047) — `var defaultFrom = Math.max(0, maxMonthIdx - 4);` - [templates/juniors.html:1028](templates/juniors.html#L1028) — same line. Drop those four lines (`defaultFrom`, `fromSelect.value = defaultFrom`, `toSelect.value = maxMonthIdx`, `applyMonthFilter()`) so the page loads with all non-future months visible — matching the Go side, which only calls `hideFutureMonths()` and leaves From at its first option. Recommend bundling this with step 2 since they touch related UI. ## Verification 1. **After step 1** — `POST /flush-cache` on Python and Go backends; reload `/adults` on each. Confirm the dropdown now lists Sep/Oct/Nov 2025. 2. **After step 2** — reload `/adults`. Confirm the dropdown shows "Sep+Oct 2025" as a single period and "Dec 2025+Jan 2026" as a single period. (Still requires the sheet columns to exist.) 3. **After step 3** — reload `/adults` and `/juniors` on Python. Confirm the table renders all non-future months on first load (Sep 2025 through the current month) instead of starting at Dec 2025. 4. **Parity check** — `make parity` should report zero diffs between Python and Go on `/api/adults` and `/api/juniors`. ## Critical files referenced - `tmp/go/attendance_regular_cache.json` — current adults sheet rows (evidence: header starts at `02.12.2025`). - `tmp/go/attendance_juniors_cache.json` — current juniors sheet rows (header still has `15.09.2025`). - [scripts/attendance.py](scripts/attendance.py) — `ADULT_MERGED_MONTHS` empty after `1257f0d`; `parse_dates` / `group_by_month` faithful. - [go/internal/services/membership/sources.go](go/internal/services/membership/sources.go) — Go counterpart, same shape. - [templates/adults.html](templates/adults.html), [templates/juniors.html](templates/juniors.html) — JS onload `defaultFrom = -4` issue (step 3). - [go/internal/web/static/js/filters.js](go/internal/web/static/js/filters.js) — Go filter UI (already correct, no changes).