docs: document service worker fix, events sort encoding, and slct account_id pattern

BOOTSTRAP__AI_Agent_Quickstart.md:
- Mistake #15 addendum: events/session modules use legacy tmp_sort_1 encoding
  (priority=true→'1'), not build_tmp_sort — requires descending sort until migrated
- Mistake #16 (new): service worker without skipWaiting+clients.claim silently serves
  stale code to long-lived tabs; explains the "can't reproduce in dev" pattern that
  likely caused the IDAA recovery meetings issue for months

CLIENT__IDAA_and_customized_mods.md:
- New "Sort Encoding" section: table of legacy vs build_tmp_sort modules with
  correct comparator direction for each
- New "Search Trigger" section: explains why $slct.account_id not $ae_loc.account_id

TODO__Agents.md:
- IDB Sort: added ae_events__event migration task + legacy encoding warning
- DevOps: marked service worker fix complete; replaced nginx caching item with
  proxy buffer tuning task

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-06-03 18:39:18 -04:00
parent 59fc7cabc6
commit 0511d9591f
3 changed files with 64 additions and 3 deletions

View File

@@ -460,11 +460,31 @@ These are real incidents — know them before you start.
**Companion Dexie trap:** `collection.reverse().sortBy('tmp_sort_*')` — Dexie ignores a collection-level `.reverse()` when `.sortBy()` is called. The sort is always ascending. To reverse the result, call `.reverse()` on the returned array after `await`. See `GUIDE__SvelteKit2_Svelte5_DexieJS.md` → `build_tmp_sort` section. **Companion Dexie trap:** `collection.reverse().sortBy('tmp_sort_*')` — Dexie ignores a collection-level `.reverse()` when `.sortBy()` is called. The sort is always ascending. To reverse the result, call `.reverse()` on the returned array after `await`. See `GUIDE__SvelteKit2_Svelte5_DexieJS.md` → `build_tmp_sort` section.
**Exception — legacy `ae_events__event.ts` encoding:** `ae_events__event.ts` (and `ae_events__event_session.ts`) do NOT use `build_tmp_sort`. They use `priority ? 1 : 0` (priority=true→`'1'`), which requires **descending** sort to put priority items first. `ae_events__event_presentation.ts` DOES use `build_tmp_sort` (it overrides the generic encoding in its `specific_processor`). Do not apply the ascending rule to raw event or session sorts until those modules are migrated to `build_tmp_sort`.
16. **Service worker without `skipWaiting()` + `clients.claim()` silently serves stale code to long-lived tabs** — The default SvelteKit service worker template does NOT include these calls. Without them, a new SW installs in the background but waits in a **"waiting"** state until every tab running the old version is closed before it activates. Users who leave a page open all day (especially IDAA members in the Novi iframe on idaa.org) run old buggy JS indefinitely after a fix is deployed.
**Symptom that should trigger this check:** Bug reports from users that developers cannot reproduce. Developers constantly refresh and open/close tabs — the new SW activates immediately for them. End users with persistent tabs never get it.
**The fix** (already applied to `src/service-worker.js` as of 2026-06-03):
```js
self.addEventListener('install', (event) => {
event.waitUntil(addFilesToCache());
self.skipWaiting(); // activate immediately, don't wait for tabs to close
});
self.addEventListener('activate', (event) => {
event.waitUntil(deleteOldCaches());
self.clients.claim(); // take control of all open tabs right away
});
```
**Trade-off:** A tab mid-session gets new JS without a page reload. For a read-heavy app like IDAA (browsing meetings) this is harmless. For a form-heavy app the risk is higher — weigh accordingly.
--- ---
## 8. Source Layout (Quick Reference) ## 8. Source Layout (Quick Reference)
``` ```text
src/lib/ src/lib/
ae_api/ — API helpers (V3 preferred) ae_api/ — API helpers (V3 preferred)
ae_core/ — Account, User, Person, Site, hosted files ae_core/ — Account, User, Person, Site, hosted files

View File

@@ -457,6 +457,32 @@ filtered) replaces it after the background refresh completes. The IDB path does
- Add `contact_li_json_ext` to the IDB fast-path filter in `search__event()` and the recovery - Add `contact_li_json_ext` to the IDB fast-path filter in `search__event()` and the recovery
meetings page so contact matches appear instantly from cache, not only after API refresh. meetings page so contact matches appear instantly from cache, not only after API refresh.
### Sort Encoding — Events Use Legacy (Not `build_tmp_sort`)
`ae_events__event.ts` builds `tmp_sort_1` with the **legacy encoding**: `priority ? 1 : 0`
(priority=true → `'1'`). This is the **opposite** of `build_tmp_sort` (priority=true → `'0'`).
| Module | Encoding | Correct comparator |
| --- | --- | --- |
| `ae_events__event.ts` (Recovery Meetings) | Legacy: `priority=true→'1'` | **Descending** `b.localeCompare(a)` |
| `ae_events__event_session.ts` | Legacy: `priority=true→'1'` | **Descending** `b.localeCompare(a)` |
| `ae_events__event_presentation.ts` | `build_tmp_sort` (overrides legacy in `specific_processor`) | **Ascending** `a.localeCompare(b)` |
| Journals, Posts, Archives | `build_tmp_sort` | **Ascending** `a.localeCompare(b)` |
**Do not apply the `build_tmp_sort` ascending rule to raw event or session sorts** until
`ae_events__event.ts` is migrated (tracked in TODO__Agents.md under IDB Sort rollout).
### Search Trigger — Use `$slct.account_id`, Not `$ae_loc.account_id`
The recovery meetings search `$effect` gates on `$slct.account_id` (set only by the bootstrap
Sync Effect, non-persisted). Do NOT change this back to `$ae_loc.account_id`.
**Why:** `$ae_loc` is a persisted store that hydrates from localStorage on page load. Its
`account_id` may be stale from a previous session (e.g., a dev/demo account_id left behind).
Using it as the gate fires the API call with the wrong account before bootstrap has run,
producing either a 403 or wrong-account data. `$slct.account_id` is null until bootstrap
sets it — a reliable gate. See mistake #14 in `BOOTSTRAP__AI_Agent_Quickstart.md`.
### My Meetings (Favorites) ### My Meetings (Favorites)
Members can star meetings to build a personal "My Meetings" list. The star toggle appears: Members can star meetings to build a personal "My Meetings" list. The star toggle appears:
@@ -873,4 +899,4 @@ ae_loc.idaa_loc = { novi_uuid: 'test-uuid-value', ... };
--- ---
**Document Status:** ✅ Current **Document Status:** ✅ Current
**Last Verified:** 2026-05-19 — Access Gate: documented new `verify_error_type` error-handling states and retry/reset UI; Search Architecture: corrected contact-search status (now works via `default_qry_str` in API path — two root causes fixed 2026-05-18/19); noted IDB fast-path gap as remaining enhancement **Last Verified:** 2026-06-03 — Recovery Meetings: documented legacy `tmp_sort_1` encoding for events (requires descending sort, not ascending); documented `$slct.account_id` gate pattern for search trigger; noted service worker `skipWaiting`/`clients.claim` requirement for long-lived IDAA iframe sessions (root cause of user-reported loading failures that could not be reproduced in dev)

View File

@@ -43,6 +43,15 @@ The app uses `svelte-persisted-store` (coarse reactivity). Migration target: rep
### [Data Layer] IDB sorting + content version rollout ### [Data Layer] IDB sorting + content version rollout
Sorting baseline is now `build_tmp_sort` (ASC chain, no `.reverse()` on tmp-sort lists). Sorting baseline is now `build_tmp_sort` (ASC chain, no `.reverse()` on tmp-sort lists).
**⚠️ Exception:** `ae_events__event.ts` and `ae_events__event_session.ts` use **legacy encoding**
(`priority ? 1 : 0`, priority=true→`'1'`). Their sort comparators must remain **descending**
until the modules are migrated to `build_tmp_sort`. `ae_events__event_presentation.ts` already
uses `build_tmp_sort` (overrides generic encoding in its `specific_processor`). See
`CLIENT__IDAA_and_customized_mods.md` → "Sort Encoding" for full table.
- [ ] **[IDB Sort] Migrate `ae_events__event.ts` to `build_tmp_sort`** — requires bumping
`IDB_CONTENT_VERSIONS.events.event` (currently v3) and switching all event sort comparators
to ascending. Check all pages that sort events before doing this.
- [ ] **[IDB Sort] Roll out to `ae_events__event_session`** after sort behavior review. - [ ] **[IDB Sort] Roll out to `ae_events__event_session`** after sort behavior review.
- [ ] **[IDB Sort] Roll out to `ae_events__event_presenter`** after sort behavior review. - [ ] **[IDB Sort] Roll out to `ae_events__event_presenter`** after sort behavior review.
- [ ] **[IDB Sort] Roll out to `ae_events__event_location`** after sort behavior review. - [ ] **[IDB Sort] Roll out to `ae_events__event_location`** after sort behavior review.
@@ -73,7 +82,13 @@ Sorting baseline is now `build_tmp_sort` (ASC chain, no `.reverse()` on tmp-sort
backend field (restoring global/cross-device persistence). Frontend code is in backend field (restoring global/cross-device persistence). Frontend code is in
`launcher_file_cont.svelte` — search for `file_display_overrides`. `launcher_file_cont.svelte` — search for `file_display_overrides`.
- [ ] **[Backend] Re-add `Access-Control-Allow-Private-Network: true` CORS header.** - [ ] **[Backend] Re-add `Access-Control-Allow-Private-Network: true` CORS header.**
- [ ] **[DevOps] Nginx caching** — Investigate `index.html` cache-pickup issues. - [x] **[DevOps] Service worker `skipWaiting` + `clients.claim`** — Root cause of "users see
old code / can't reproduce in dev testing": the SW sat in waiting state until all tabs closed.
IDAA members leave idaa.org open all day. Fixed 2026-06-03: both calls added to
`src/service-worker.js`. See mistake #16 in `BOOTSTRAP__AI_Agent_Quickstart.md`.
- [ ] **[DevOps] Nginx proxy buffer tuning** — Buffer settings copied from PHP guide; not
optimal for Node.js. `proxy_busy_buffers_size` technically exceeds safe limit. Re-examine
when enabling compression (now re-enabled) stabilizes.
- [ ] **[DevOps] Simplify Dockerfile env file selection** — Use plain `.env` instead of `BUILD_MODE`. - [ ] **[DevOps] Simplify Dockerfile env file selection** — Use plain `.env` instead of `BUILD_MODE`.
--- ---