From 68e5e01df15d89dc273c03ea8eda4c6f9d5c28d8 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Mon, 11 May 2026 12:26:51 -0400 Subject: [PATCH] A quick backup of the todo before removing things. --- .../archive/TODO__Agents__ARCHIVE_2026-05.md | 326 ++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 documentation/archive/TODO__Agents__ARCHIVE_2026-05.md diff --git a/documentation/archive/TODO__Agents__ARCHIVE_2026-05.md b/documentation/archive/TODO__Agents__ARCHIVE_2026-05.md new file mode 100644 index 00000000..54065710 --- /dev/null +++ b/documentation/archive/TODO__Agents__ARCHIVE_2026-05.md @@ -0,0 +1,326 @@ +# Frontend Agent Task List +> Use this file to track steps for complex features or bug fixes. +> **Status:** Stable — ongoing development. + + +## 🔴 BGH Conference — April 21 (Must Fix Before Event) + +- [x] **[Locations] Event Locations list does not auto-load** — added `+page.ts` to trigger + `load_ae_obj_li__event_location` on page load. Also fixed session query using stale + `event_location_id_random` index (should be `event_location_id`). (2026-04-19) + +- [x] **[Files] Warn/error on `.ppt`/`.doc` upload** — warning rows shown per-file in upload table; + non-trusted users are fully blocked (`file_list_status = 'blocked_legacy'`); trusted users see + warnings but can still upload. Covers `.ppt`, `.doc` (block) and other legacy exts (warn-only). + (2026-04-19) + +- [x] **[Files] Hide internal-purpose files from Launcher by default** — renamed `hide_draft` prop + to `show_internal_purpose_files` in `launcher_file_cont.svelte`; logic flipped so `false` (the + default) hides files with `file_purpose == 'outline'`, `'draft'`, or `'admin'`. Store key renamed + from `hide_content__draft_files` (inverted, misleading) to `show_content__internal_files: false` + (show-on-opt-in, consistent with all other `show_content__*` flags). Updated across all 8 Launcher + templates that pass this prop. (2026-04-19, revised 2026-04-20) + +- [x] **[Launcher] Remove duplicate session API call on session select** — `menu_session_list.svelte` + was calling `load_ae_obj_id__event_session` directly AND then `goto()` triggered `+page.ts` which + also called it — two concurrent calls per session click. Removed the direct call entirely; + `+page.ts` is now the sole owner of session data loading. `goto()` promise assigned to + `ae_promises.slct__event_session_id` to drive the existing `{#await}` spinner. (2026-04-20) + +- [ ] **[Electron/Launcher] Deploy + test Aether Native Electron app on Mac laptops** — build, + deploy, and verify on onsite Mac laptops. Additional testing of cache/launch flow still needed + before April 21. + +- [x] **[Pres Mgmt] POC column shown in "Sessions at this Location"** — wired + `hide__session_poc={!pres_mgmt_loc.current.show__session_li_poc_field}` in + `ae_comp__event_location_obj_li.svelte`; also set `hide__session_location={true}` since + location is implicit in that context. (2026-04-19) + +--- + +## 🔴 CMSC Charlotte — May 27 (Presentation Management) +**Drive down:** May 25 | **Setup:** May 26 morning | **Show:** May 27+ + +- [ ] **[Electron/Launcher] Clean up presentation file launch scripts** — BGH show revealed + issues with the scripts used to open/launch presentation files through the Electron Launcher. + Audit and improve the launch/open flow (script reliability, error handling, file path resolution). + Must be tested and ready before May 26 setup day. + +--- + +## 🔴 Axonius DC — June 9 (Badge Printing) +**Setup/Registration:** June 8 | **Show:** June 9 + +- [ ] **[Badges] Epson C3500 fanfold badge layout** — Axonius is using Epson C3500 printers + with fanfold (continuous) badge stock. Create/configure a fanfold badge layout compatible + with the C3500 format. Must be ready before the June 8 setup/registration day. + +--- + +## 🚧 Upcoming High Priority + +### [Stores] Svelte 4 → Svelte 5 State Migration (prerequisite for Phase 2c) +The app uses `svelte-persisted-store` (Svelte 4 store contract) for all core persisted state +(`ae_loc`, `idaa_loc`, `ae_api`, `ae_sess`, etc.). In Svelte 5 `$effect`, reading **any field** +of a Svelte 4 store subscribes to the **entire store** — coarse-grained reactivity. This is the +root cause of the IDAA Novi re-auth bug (2026-03-30): unrelated `$ae_loc` writes (e.g. iframe +height, SWR cfg reload) triggered the Novi verification effect repeatedly. + +Migration target: replace `svelte-persisted-store` with Svelte 5 `$state`-based persistence +(e.g. `runed` `PersistedState`, or a lightweight custom wrapper). This gives fine-grained +reactivity — only effects that actually read a changed field re-run. + +**Phased approach (do NOT do all at once):** + +- [ ] **Phase A — Project plan + wrapper decision:** Write `PROJECT__Stores_Svelte5_Migration.md`. + Decide: `runed` library vs. custom `$state` + localStorage wrapper. Audit all store consumers. + Identify stores in priority order. Estimate blast radius per store. + +- [ ] **Phase B — Core auth stores (highest impact, start here):** + - `ae_loc` (persisted) — auth flags, site cfg, UI state; ~471 consumer sites across 150+ files + - `idaa_loc` (persisted) — Novi auth, IDAA query prefs + These two cause the most reactive noise. Migrating them also unlocks Phase 2c (separate `ae_auth` + store) since the callsite sweep is now required anyway. + +- [ ] **Phase C — Remaining persisted stores:** + - `ae_api` (persisted) — API config / JWT + - `ae_events_stores` persisted entries (badges, launcher, leads, pres_mgmt loc stores) + +- [ ] **Phase D — Non-persisted writable stores:** + - `ae_sess`, `idaa_sess`, `slct`, `slct_trigger`, `ae_auth_error`, `ae_trig`, `ae_snip`, etc. + - Lower urgency (no localStorage churn), but fine-grained reactivity still beneficial. + +- [ ] **Phase E — Phase 2c (unblocked after B):** Split `ae_loc` into `ae_auth` + `ae_app` + (see entry below — ~471 callsites, but sweep is cheap once already touching every consumer). + +**Project plan doc needed:** Yes — scope is app-wide. Do NOT start Phase B without Phase A. + +--- + +### [Stores] Refactor — Phase 2c (deferred) +Phases 1, 2a, 2b are complete (see ✅ Completed below). One phase remaining: + +- [ ] **Phase 2c — Actual separate stores (`ae_auth`, `ae_app`):** Requires touching ~471 + `$ae_loc.*` auth-field read sites across 150+ files. Deferred until a Svelte runes migration + of the store layer itself (touching every component anyway makes the callsite sweep cheap). + +### [Backend] Join event_location_id onto event_presenter API view +The `event_presenter` object currently has `event_session_id` but not `event_location_id`. +When navigating from the Presenter View to the Launcher, the frontend has to do a secondary +session lookup to discover the location (magic redirect in launcher base `+page.svelte`). +Joining `event_session.event_location_id` into the presenter view/response would let the +frontend pass the location directly in the Launcher URL without the extra lookup. +- [x] Backend: added `event_location_id` (and `event_location_id_random`) to the `event_presenter` view or API response (2026-04-09) +- [x] Frontend: updated `ae_EventPresenter` type and `properties_to_save`; now pass as `events__launcher_id` in `presenter_page_menu.svelte` (2026-04-09) + + + + + +### [TypeScript] svelte-check hidden errors — discovered 2026-03-27 +**HOW WE FOUND THIS:** The `@lucide/svelte` 0.577.0 update (2026-03-10) dropped `class` from +`IconProps`. Fixing it required a `declare module '@lucide/svelte'` augmentation. That +augmentation was mistakenly placed in `app.d.ts`, which is a *script-context* declaration file +(no `export {}`). In that context, `declare module` is an **ambient replacement**, not a merge — +it wiped all icon exports from svelte-check's view, surfacing 1368 previously hidden errors. +Once moved to `src/lucide-augment.d.ts` (a proper module file with `export {}`), the masking +lifted and the real pre-existing errors became visible. + +**Lesson:** A broken ambient declaration can silently hide unrelated errors. If svelte-check +suddenly jumps to 0 errors, verify it's not because a bad `.d.ts` replaced a package's types. + +**Current state (2026-03-31):** 32 errors, 0 warnings — all `ModalProps.children`. + +- [ ] **[flowbite-svelte] `ModalProps.children` — 31 errors across 26 files.** The flowbite-svelte + `Modal` component API changed; `children` is no longer a direct prop (now Svelte snippet-based). + Affected files span journals, pres_mgmt, events/settings, and IDAA archives. + Run `npx svelte-check 2>&1 | grep ModalProps` to get the current list. + Fix pattern: replace `children` prop binding with Svelte snippet syntax per flowbite-svelte docs. + +### [Journals] Journal Entry Config follow-ups + +- [ ] **[Journals] Visibility / audience toggle contrast** — the flag buttons need a clearer + selected state in both light and dark mode. +- [ ] **[Journals] Footer button style** — the actual `Done` button should read like a real button, + not a seamless footer spacer. +- [ ] **[Journals] Entry passcode secondary auth** — `passcode_hash` stores a hash; compare the + entered passcode hash to the stored hash, gate entry loading, and honor the TTL-based access + window. This is secondary entry auth, not a plain-text passcode field. +- [ ] **[Journals] Summary AI shortcut** — add an AI summarize button next to Entry Details + Summary so staff can generate a summary directly from the modal. +- [ ] **[Journals] Archive On sizing** — constrain the Archive On control to a reasonable width + instead of letting it expand to full width. +- [ ] **[Journals] Archive On behavior** — define what Archive On actually means and wire the + behavior; it is currently just a UI field with no live effect. + +- [x] **[IDAA] Do not cache IDAA data in IDB when access is denied (2026-04-19, audited 2026-04-28)** + Full audit confirmed all protection layers are in place. No code changes required. + - All `+page.ts` / `+layout.ts` under `src/routes/idaa/` are clean — no SWR loads run before auth resolves. + - All `$effect` SWR calls in IDAA `+page.svelte` files are gated on `$idaa_loc.novi_verified || $ae_loc.trusted_access`. + - `(idaa)/+layout.svelte` purges `db_posts`, `db_archives`, `db_events` on auth failure, no-UUID/no-session, and inconsistent state. + - `sign_out()` calls `indexedDB.deleteDatabase()` on all IDAA databases. + - API 401/403 responses fail-fast in `api_get_object.ts` (throw before any IDB write). + - `idaa_trig` is in-memory `writable()` only — cannot carry stale trigger state across sessions. + - `$effect` auth guards in IDAA page components are reactivity guards (prevent spurious SWR calls on coarse `$ae_loc` writes), NOT auth-bypass guards. SvelteKit layout hierarchy already prevents child components from mounting when `(idaa)/+layout.svelte` blocks rendering. + - Doc: SvelteKit layout hierarchy security model captured in `GUIDE__SvelteKit2_Svelte5_DexieJS.md` and `BOOTSTRAP__AI_Agent_Quickstart.md` (Mistake #7). + +- [ ] **[IDAA] Make `contact_li_json_ext` searchable — Recovery Meeting contact search (2026-04-08)** + Members cannot search for meetings by contact name or email. `contact_li_json` data is not + included in `default_qry_str` and MariaDB cannot substring-search a JSON longtext directly. + The `event` table already has `contact_li_json_ext` (STORED GENERATED, indexed) to work around this. + + **Backend (blocked on this first):** Add `contact_li_json_ext` to the searchable fields + whitelist for the `event` object type — likely a one-line change in `ae_obj_types_def.py` + or the event object definition. Message sent to backend agent 2026-04-08. + + **Frontend (after backend ships):** + - `src/lib/ae_events/ae_events__event.ts` → `search__event()`: add `contact_li_json_ext` + as an OR condition alongside `default_qry_str` when `qry_str` is present. + - `src/routes/idaa/(idaa)/recovery_meetings/+page.svelte` fast-path IDB filter: parse + `contact_li_json` and include contact names/emails in the local text match check. + +- [ ] **[IDAA / Events] Audit `default_qry_str` coverage in other event search pages.** + The backend was updated 2026-03-31 to expose `default_qry_str` in API responses. + Frontend fix applied to Recovery Meetings (`+page.svelte` + `properties_to_save`). + Check all other event search pages that use `db_events.event.filter()` or a secondary + post-API text filter — they may have the same mismatch (local searches `name`/`description` + only while server uses `default_qry_str`). Start with: any route under `/events/` or `/idaa/` + that has a full-text search input. + +### [IDAA] Jitsi config editor + live site fix +- [ ] **Fix live site (id=17) `jitsi_token_endpoint` pointing to dev-api:** DB has + `https://dev-api.oneskyit.com/api/jitsi_token` for both site 10 and site 17 (IDAA live). + Need to update site 17 in **production** to `https://api.oneskyit.com/api/jitsi_token`. + SQL: `UPDATE site SET cfg_json = JSON_SET(cfg_json, '$.jitsi_token_endpoint', 'https://api.oneskyit.com/api/jitsi_token') WHERE id = 17;` + +- [ ] **Add IDAA Jitsi config editor UI** to the jitsi_reports page (administrator_access only), + alongside the existing Jitsi URL Builder section. Should allow editing key fields in + `site_cfg_json` without needing phpMyAdmin: + - `jitsi_token_endpoint` — the JWT signing endpoint (needs to point to prod) + - Jitsi domain default (currently hardcoded as `jitsi.dgrzone.com` fallback in the page) + - `novi_jitsi_mod_li` — list of Novi UUIDs who get moderator privileges + Read from `$ae_loc.site_cfg_json`, PATCH the site record via V3 CRUD + (`PATCH /v3/crud/site/{id}/`), reload `$ae_loc.site_cfg_json` on save so it takes + effect without re-login. + +### [IDAA] Jitsi Reports still incomplete +- [x] **Finish Jitsi Reports filters** — added Novi UUID exclusion plus meeting-name whitelist + filtering, with room-level unique counts based on Novi UUID when present. (2026-05-06) + +### [PWA] Service worker ignoring `chrome-extension://` requests +Browser console shows repeated errors: +```text +TypeError: Failed to execute 'put' on 'Cache': Request scheme 'chrome-extension' is unsupported +``` +The service worker's fetch/install handler is trying to cache requests with `chrome-extension://` +URLs (injected by browser extensions), which the Cache API rejects. Fix: filter out non-`http`/`https` +requests before attempting to cache. In the service worker fetch handler, add a guard: +```js +if (!event.request.url.startsWith('http')) return; // skip chrome-extension:// etc. +``` +Locate in `static/service-worker.js` or the Vite PWA plugin config. Low severity — doesn't break +functionality, but pollutes the console and may cause unhandled promise rejections. + +### [CSS] Global placeholder text color — too dark in light mode +Placeholder text inherits full input text color in light mode (Tailwind CSS default), making +placeholders indistinguishable from filled-in values. Most visible in badge print controls +where placeholders show the actual badge value (e.g. "John Smith"). + +Workaround: scoped `::placeholder` rule added to `ae_comp__badge_print_controls.svelte` +(gray-400 light / gray-500 dark) — `commit 7733ef8`. + +**Long-term fix:** Add a global rule to the main CSS (e.g. `src/app.css` or a theme file): +```css +::placeholder { + color: #9ca3af; /* gray-400 */ + opacity: 1; /* overrides Firefox's 0.54 default */ +} +.dark ::placeholder { + color: #6b7280; /* gray-500 */ +} +``` +Once the global rule is in place, remove the scoped workaround from the badge controls. + + + +### [Backend/DevOps] Re-add `Access-Control-Allow-Private-Network: true` CORS header +Chrome's Private Network Access (PNA) policy blocks public-origin iframes from fetching +private-network addresses. Symptom: when `dev-api.oneskyit.com` resolves to a LAN IP +(testing from home), Chrome blocks the site domain lookup → ghost account → `site_cfg_json` +never loads → `novi_idaa_api_key` is null → IDAA Novi verifier spins forever → timeout banner. +Firefox unaffected. Production unaffected (public IPs only). + +- [ ] **Re-add PNA header to API CORS config** — `dev-api` Nginx or FastAPI CORS middleware + must respond with `Access-Control-Allow-Private-Network: true` when Chrome sends + `Access-Control-Request-Private-Network: true` in the preflight. This was fixed ~1 month + ago and regressed. Check Nginx site config and FastAPI `CORSMiddleware` settings. + Low urgency (dev-only, Firefox workaround available), but blocks home-network iframe testing. + +### [DevOps] Remaining deployment items + +- [ ] **Simplify Dockerfile env file selection** — Currently the Dockerfile uses a `BUILD_MODE` arg to + select between `.env.dev`, `.env.test`, `.env.prod` during the Docker build. This is unnecessary + complexity: each server (test Linode, prod Linode, workstation) only ever runs one environment, so + there will only ever be one env file present in that server's app directory. + + **The fix:** Each server's app dir (`/srv/apps/test_aether_app_sveltekit/`, etc.) should have a + plain `.env` file (gitignored, placed manually during server setup). The Dockerfile should just + `COPY . .` and `cp .env .env.runtime` unconditionally — no `if prod / elif test / else dev` + branching for env file selection. + + **What this changes:** + - `aether_app_sveltekit/Dockerfile` — remove the `BUILD_MODE`-driven `cp` block; always use `.env` + - Each Linode app dir gets a plain `.env` instead of `.env.test` / `.env.prod` + - Workstation keeps `.env.local` (for `npm run dev`) and `.env.dev` (for `build:docker:dev`) — + those stay as-is since they legitimately coexist locally + - `BUILD_MODE` arg can stay if needed for other build differences; just stop using it to pick the env file + - Update `.gitignore` in sveltekit to un-ignore `.env.test` / remove stale entries if desired + + **Do not touch before the April 21 show.** Low risk but unnecessary churn right before an event. + +- [ ] **Branch strategy cleanup:** All environments (test, prod, bak) currently pull from the same + branches. `deploy.sh` defaults are `ae_app_3x_llm` / `development` — acceptable for now but + should establish proper branch separation (e.g. `main`/`master` for prod). + +- [ ] **Tier 2 deploy (Gitea webhook):** Push-triggered deploys via Gitea webhook → listener on + Linode → `deploy.sh`. Deferred until Gitea usage is more established. + + +### [Files] Download button — wrong ID used in `handle_click()` (2026-04-22) +`ae_comp__hosted_files_download_button.svelte` resolves `file_id` for the download call as +`hosted_file_obj?.id || hosted_file_obj?.hosted_file_id || hosted_file_id`. When called from +Manage Files with an `event_file_obj`, `hosted_file_obj.id` = `event_file_id` (set by +`_process_generic_props` via the `_random` strip logic), so the chain stops at the wrong value. +The download call goes to `/v3/action/hosted_file/{event_file_id}/download` instead of using the +correct `hosted_file_id`. May work if the backend accepts event_file_id at that endpoint — +needs live verification. + +**Status (2026-04-22):** Tested — downloads ARE working despite the wrong ID. The backend +V3 action endpoint appears to silently accept `event_file_id` at the `hosted_file` download +path (or maps between the two). Working by accident, not by design. Needs proper fix before +it breaks — if the backend ever tightens that endpoint, all Manage Files downloads will 404. + +**Fix:** In `handle_click()` and both `$effect` blocks and the `content` snippet, replace: +```ts +const file_id = hosted_file_obj?.id || hosted_file_obj?.hosted_file_id || hosted_file_id; +``` +with: +```ts +const file_id = hosted_file_obj?.hosted_file_id ?? hosted_file_id; +``` +The direct-download `` path is unaffected (already uses `event_file_id` → correct endpoint). + +### [Files] `db_events.file.clear()` on upload clears all cached files (2026-04-22) +In `ae_comp__event_files_upload.svelte` line 114, `db_events.file.clear()` wipes the entire +`file` Dexie table, not just files for the current session/presenter. Normally harmless (the +reload right after repopulates), but if multiple sessions' file lists are open simultaneously +they'd briefly flash empty. Low priority — only noticeable in multi-panel workflows. + +### [General] +- **Input Field Audit:** Several input fields are missing `name`/`id` attributes or `data-testid`. Known examples: badge override fields in `ae_comp__badge_obj_view.svelte`; template name input in `ae_comp__badge_template_form.svelte`. Matters for: accessibility, autofill, label associations, and test targeting. (For tests, use `getByLabel()` rather than `input[value*=...]` which only checks the HTML attribute, not the Svelte-bound DOM property.) + +## ✅ Completed (2026-04) +## ✅ Completed (archived) +See the full completed history in: +[documentation/archive/TODO__Agents__ARCHIVE_2026-03.md](documentation/archive/TODO__Agents__ARCHIVE_2026-03.md) +[documentation/archive/TODO__Agents__ARCHIVE_2026-04.md](documentation/archive/TODO__Agents__ARCHIVE_2026-04.md)