From 9af5a292b6e8be1d0ea5949d9e32808f0688cfe0 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Thu, 16 Apr 2026 19:11:25 -0400 Subject: [PATCH] Updating to do lists. --- documentation/TODO__Agents.md | 53 +--- .../history/TODO__Agents__ARCHIVE_2026-04.md | 227 ++++++++++++++++++ 2 files changed, 231 insertions(+), 49 deletions(-) create mode 100644 documentation/history/TODO__Agents__ARCHIVE_2026-04.md diff --git a/documentation/TODO__Agents.md b/documentation/TODO__Agents.md index 7cf2d330..f58d3f39 100644 --- a/documentation/TODO__Agents.md +++ b/documentation/TODO__Agents.md @@ -106,11 +106,6 @@ suddenly jumps to 0 errors, verify it's not because a bad `.d.ts` replaced a pac only while server uses `default_qry_str`). Start with: any route under `/events/` or `/idaa/` that has a full-text search input. - - [x] **[package.json] Remove orphaned ShadCN/bits-ui packages.** `shadcn-svelte` and `bits-ui` - remain in `package.json` but have no usages — `src/lib/components/ui/` was removed 2026-03-27 - (trashed to `~/tmp/gemini_trash/shadcn_components_ui_2026-03-27`). Removed from `package.json` and - `package-lock.json` on 2026-04-02. - ### [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). @@ -141,10 +136,6 @@ if (!event.request.url.startsWith('http')) return; // skip chrome-extension:// e 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. -### [Badges] Remaining badge work before first live event -- **Badge print controls UX polish:** Scott has improvements in mind — TBD next session. - File: `ae_comp__badge_print_controls.svelte`. - ### [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 @@ -167,44 +158,6 @@ Once the global rule is in place, remove the scoped workaround from the badge co -### [Leads] Exhibitor Lead Scanning — IN PROGRESS (demo-ready prep) -Module is substantially built as a PWA (no Electron). Core flow works end-to-end. -Spec: `documentation/PROJECT__AE_Events_Exhibitor_Leads_v3.md` and `_detail.md`. -Full audit: `src/routes/events/[event_id]/(leads)/` and `src/lib/ae_events/ae_events__exhibit*.ts`. - -**What's working:** -- Exhibit search/landing (`/leads/`) — SWR, local + API search, sort -- Exhibit detail page — 4-tab layout, sticky header with Add/List toggle, auto-refresh timer -- Tab 1 (Start): sign-in via shared passcode OR licensed user (email + passcode) -- Tab 2 (Add): QR scan (confirm mode — replaced rapid/qualify) + manual badge search; duplicate/re-enable detection on both -- Tab 3 (List): SWR lead list, licensee filter (All / My Leads), sort options, export button -- Tab 4 (Manage): admin tools, booth profile edit, passcode, license mgmt, custom questions config, app settings (refresh interval, clear IDB/localStorage, reload) -- Lead detail page: view/edit custom question responses, exhibitor notes (TipTap), priority/enable flags -- Export wired to V3 action endpoint `/v3/action/event_exhibit/{id}/tracking_export` (CSV/XLSX) - -**Remaining before demo:** -- [x] **Export endpoint** — V3 action endpoint confirmed live on backend (2026-03-16). Returns 403 if - `leads_api_access` is not enabled on the exhibit — expected behavior. Export button now gated in - UI: only renders when `$lq__exhibit_obj?.leads_api_access === true`. Enable via: - `PATCH /v3/crud/event_exhibit/{id}` with `{ "leads_api_access": true }`. -- [x] **`allow_tracking` gate** — implemented (2026-03-16). QR scanner shows a warning card and - blocks the add. Manual search shows a ShieldOff "Opt-Out" badge per row and guards `add_as_lead`. - Opt-in model: `allow_tracking` must be explicitly `true` on the badge. Also added `allow_tracking` - and `agree_to_tc` to `ae_EventBadge` in `ae_types.ts`. - **Demo note:** ensure test badges have `allow_tracking = true` or no one can be added. -- [x] **Payment component** — `ae_comp__exhibit_payment.svelte` fully implemented (2026-03-27). - Reads Stripe config from `$ae_loc.site_cfg_json` (`stripe_publishable_key`, `stripe_btn_1/3/6/10_license`). - License tier selector (1/3/6/10 users) with `{#key}` remount pattern for Stripe web component. - 3 states: paid confirmation (priority=true), admin setup hint / "contact organizer" (no Stripe config), - payment form. `client_reference_id=exhibit_id`. TypeScript declaration in `app.d.ts`. - Stripe keys verified visible in `$ae_loc.site_cfg_json` on dev/demo site. Keys need validity check in Stripe dashboard. -- [x] **End-to-end smoke test (canceled by client)** — sign in with shared passcode, scan/search a badge, add a lead, view detail, add notes/responses, export CSV; canceled 2026-04-09. -- [x] **Install prompt** — PWA install nudge implemented (2026-03-16). `pwa_install.svelte.ts` - singleton captures `beforeinstallprompt` (Chrome/Android/desktop) and detects iOS Safari - for manual "Share → Add to Home Screen" instructions. Reusable `element_pwa_install_prompt.svelte` - placed on the Leads Start tab between the feature grid and sign-in. `pwa_install.init()` wired - into root `+layout.svelte`; dismiss persists 7 days via localStorage. svelte-check: 0 errors. - ### [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) @@ -222,6 +175,8 @@ Full audit: `src/routes/events/[event_id]/(leads)/` and `src/lib/ae_events/ae_ev - [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-03) +## ✅ Completed (2026-04) ## ✅ Completed (archived) -See the full completed history in [documentation/TODO__Agents__ARCHIVE_2026-03.md](documentation/TODO__Agents__ARCHIVE_2026-03.md). +See the full completed history in: +[documentation/history/TODO__Agents__ARCHIVE_2026-03.md](documentation/history/TODO__Agents__ARCHIVE_2026-03.md) +[documentation/history/TODO__Agents__ARCHIVE_2026-04.md](documentation/history/TODO__Agents__ARCHIVE_2026-04.md) diff --git a/documentation/history/TODO__Agents__ARCHIVE_2026-04.md b/documentation/history/TODO__Agents__ARCHIVE_2026-04.md new file mode 100644 index 00000000..7cf2d330 --- /dev/null +++ b/documentation/history/TODO__Agents__ARCHIVE_2026-04.md @@ -0,0 +1,227 @@ +# Frontend Agent Task List +> Use this file to track steps for complex features or bug fixes. +> **Status:** Stable — ongoing development. + + +## 🚧 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. + + - [x] **[package.json] Remove orphaned ShadCN/bits-ui packages.** `shadcn-svelte` and `bits-ui` + remain in `package.json` but have no usages — `src/lib/components/ui/` was removed 2026-03-27 + (trashed to `~/tmp/gemini_trash/shadcn_components_ui_2026-03-27`). Removed from `package.json` and + `package-lock.json` on 2026-04-02. + +### [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. + +### [Badges] Remaining badge work before first live event +- **Badge print controls UX polish:** Scott has improvements in mind — TBD next session. + File: `ae_comp__badge_print_controls.svelte`. + +### [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. + + + +### [Leads] Exhibitor Lead Scanning — IN PROGRESS (demo-ready prep) +Module is substantially built as a PWA (no Electron). Core flow works end-to-end. +Spec: `documentation/PROJECT__AE_Events_Exhibitor_Leads_v3.md` and `_detail.md`. +Full audit: `src/routes/events/[event_id]/(leads)/` and `src/lib/ae_events/ae_events__exhibit*.ts`. + +**What's working:** +- Exhibit search/landing (`/leads/`) — SWR, local + API search, sort +- Exhibit detail page — 4-tab layout, sticky header with Add/List toggle, auto-refresh timer +- Tab 1 (Start): sign-in via shared passcode OR licensed user (email + passcode) +- Tab 2 (Add): QR scan (confirm mode — replaced rapid/qualify) + manual badge search; duplicate/re-enable detection on both +- Tab 3 (List): SWR lead list, licensee filter (All / My Leads), sort options, export button +- Tab 4 (Manage): admin tools, booth profile edit, passcode, license mgmt, custom questions config, app settings (refresh interval, clear IDB/localStorage, reload) +- Lead detail page: view/edit custom question responses, exhibitor notes (TipTap), priority/enable flags +- Export wired to V3 action endpoint `/v3/action/event_exhibit/{id}/tracking_export` (CSV/XLSX) + +**Remaining before demo:** +- [x] **Export endpoint** — V3 action endpoint confirmed live on backend (2026-03-16). Returns 403 if + `leads_api_access` is not enabled on the exhibit — expected behavior. Export button now gated in + UI: only renders when `$lq__exhibit_obj?.leads_api_access === true`. Enable via: + `PATCH /v3/crud/event_exhibit/{id}` with `{ "leads_api_access": true }`. +- [x] **`allow_tracking` gate** — implemented (2026-03-16). QR scanner shows a warning card and + blocks the add. Manual search shows a ShieldOff "Opt-Out" badge per row and guards `add_as_lead`. + Opt-in model: `allow_tracking` must be explicitly `true` on the badge. Also added `allow_tracking` + and `agree_to_tc` to `ae_EventBadge` in `ae_types.ts`. + **Demo note:** ensure test badges have `allow_tracking = true` or no one can be added. +- [x] **Payment component** — `ae_comp__exhibit_payment.svelte` fully implemented (2026-03-27). + Reads Stripe config from `$ae_loc.site_cfg_json` (`stripe_publishable_key`, `stripe_btn_1/3/6/10_license`). + License tier selector (1/3/6/10 users) with `{#key}` remount pattern for Stripe web component. + 3 states: paid confirmation (priority=true), admin setup hint / "contact organizer" (no Stripe config), + payment form. `client_reference_id=exhibit_id`. TypeScript declaration in `app.d.ts`. + Stripe keys verified visible in `$ae_loc.site_cfg_json` on dev/demo site. Keys need validity check in Stripe dashboard. +- [x] **End-to-end smoke test (canceled by client)** — sign in with shared passcode, scan/search a badge, add a lead, view detail, add notes/responses, export CSV; canceled 2026-04-09. +- [x] **Install prompt** — PWA install nudge implemented (2026-03-16). `pwa_install.svelte.ts` + singleton captures `beforeinstallprompt` (Chrome/Android/desktop) and detects iOS Safari + for manual "Share → Add to Home Screen" instructions. Reusable `element_pwa_install_prompt.svelte` + placed on the Leads Start tab between the feature grid and sign-in. `pwa_install.init()` wired + into root `+layout.svelte`; dismiss persists 7 days via localStorage. svelte-check: 0 errors. + +### [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-03) +## ✅ Completed (archived) +See the full completed history in [documentation/TODO__Agents__ARCHIVE_2026-03.md](documentation/TODO__Agents__ARCHIVE_2026-03.md).