# 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) - [ ] **[Locations] Event Locations list does not auto-load** — list must be loaded automatically on page open; currently requires manual trigger. Also needs general cleanup of the Locations list UI. - [ ] **[Files] Warn/error on `.ppt` upload** — if a presenter tries to upload a `.ppt` file (legacy PowerPoint format), show a clear warning or block the upload with an error message instructing them to use `.pptx` instead. Modern format required for processing. - [ ] **[Files] Hide draft/flagged files from list** — files marked with an X flag (draft or purpose-excluded) should not appear in the file listing. Filter them out before display. - [ ] **[Electron/Launcher] Deploy updated Aether Native Electron app to Mac laptops** — double-check the build and deployment process; verify the latest version is installed and functional on the onsite Mac laptops before April 21. - [ ] **[Pres Mgmt] POC column shown in "Sessions at this Location"** — the POC (Point of Contact) column is appearing in the Sessions at this Location view when it should be hidden. Identify the condition controlling visibility and suppress it in this context. --- ## 🚧 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. - [ ] **[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. ### [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. ### [DevOps] Remaining deployment items - [x] **Wire AE_APP_REPLICAS:** `docker-compose.yml` line 147 already has `scale: ${AE_APP_REPLICAS:-1}`. (verified 2026-03-11) - [x] **Archive ae_env_node_app:** Archived as tar.gz under `~/OSIT_dev/backups/`; old history/docs moved to `~/OSIT_dev/for_reference_only/`. (2026-03-11) - [x] **Build Optimization:** Current state finalized. Local Gitea instance stood up at `git.dgrzone.com` (Docker, home server) — future: migrate repos from Bitbucket, verify Backblaze/restic backups cover Gitea data. (2026-03-11) - [x] **Remote deploy script:** `aether_container_env/deploy.sh` — SSH-triggered from workstation via `npm run deploy:remote:test/prod`. Handles git pull (ff-only) + docker build + restart. Tested and working on test env. (2026-03-25) - [x] **`.env.default` cleanup:** Removed 16 dead variables, added missing `AE_NETWORK_NAME`/`CONTAINER_DOZZLE`/`AE_DOZZLE_PORT`, parameterized all container names (`CONTAINER_MARIADB`, `CONTAINER_PMA`, `CONTAINER_AE_OPS`) with `:-default` fallbacks in compose. ("Dozzle" = log viewer container.) (2026-03-26) - [x] **Prod deploy:** Run `npm run deploy:remote:prod` (off-peak). Prerequisites: both repos pushed to Bitbucket ✓; verify `.env.prod` exists in `/srv/apps/prod_aether_app_sveltekit/` on Linode before running. (2026-03-30) - [x] **Bitbucket → SSH migration:** Switched all three repos (`aether_app_sveltekit`, `aether_container_env`, `aether_api_fastapi`) to SSH remotes (`git@bitbucket.org`) on workstation. App passwords deprecated — SSH unaffected. (2026-03-27) - [ ] **Branch strategy cleanup:** All environments (test, prod, bak) currently pull from 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. ### [General] - [x] **Temp Cleanup:** `cleanup_tmp_files` wired in `launcher_background_sync.svelte`; called at launcher startup. Confirmed working. (2026-03-11) - [x] **`window.print()` for badge print button:** Wired in `ae_comp__badge_print_controls.svelte` — increments count, fires `window.print()`, redirects to badge search. (done) - **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)