docs: cleanup and archive agent TODO list
Archived completed May 2026 tasks and streamlined the active list to focus on upcoming events and the final V3 API surgical cleanup. - Created TODO__Agents__ARCHIVE_2026-05.md with completed items. - Streamlined TODO__Agents.md for active show support (CMSC, Axonius). - Added V3 CRUD migration tracking for core site and utility helpers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,556 +2,91 @@
|
|||||||
> Use this file to track steps for complex features or bug fixes.
|
> Use this file to track steps for complex features or bug fixes.
|
||||||
> **Status:** Stable — ongoing development.
|
> **Status:** Stable — ongoing development.
|
||||||
|
|
||||||
|
|
||||||
## 🔴 CMSC Charlotte — May 27 (Presentation Management)
|
## 🔴 CMSC Charlotte — May 27 (Presentation Management)
|
||||||
**Drive down:** May 25 | **Setup:** May 26 morning | **Show:** May 27+
|
**Drive down:** May 25 | **Setup:** May 26 morning | **Show:** May 27+
|
||||||
|
|
||||||
**[Electron/Launcher] Clean up presentation file launch profiles** — BGH show revealed issues
|
|
||||||
with the profiles used to open/launch presentation files. Architecture decision: move launch
|
|
||||||
logic to the Svelte side so it can be changed without an Electron rebuild. Electron becomes a
|
|
||||||
thin OS primitive layer; all business logic lives in Svelte and device config.
|
|
||||||
|
|
||||||
Why this matters: the profile map is policy, while the native template is the exact runtime
|
|
||||||
command. Keeping those separate avoids a second hidden source of truth and keeps Electron from
|
|
||||||
guessing defaults.
|
|
||||||
|
|
||||||
**Electron groundwork (2026-05-11) — DONE:**
|
|
||||||
- [x] `run_osascript` hardened — temp `.scpt` file approach; handles multi-line + special chars
|
|
||||||
- [x] `native:copy-from-cache-to-temp` primitive added — copy to tmp, caller decides launch
|
|
||||||
- [x] `native:launch-from-cache` executes a provided `native_template` string — AppleScript or `shell:` prefix; no Electron-side fallback
|
|
||||||
- [x] `get_launch_profile()` in `launcher_file_cont.svelte` reads from device config then event config; resolves to a `native_template` string and passes it to `launch_from_cache`
|
|
||||||
- [x] Built-in Launcher defaults refactored into canonical profile names plus extension aliases (`ae_launcher__default_launch_profiles.ts`)
|
|
||||||
- [x] Device-level Launch Timing section added under Launcher Configuration → Device, with per-profile `launch_profiles[profile].post_delay_ms` overrides
|
|
||||||
- [x] **URL file launch support (2026-05-13)** — `event_file.extension = 'URL'` (or filename starting with `http://`/`https://`) is treated as a non-downloaded URL. Background sync skips URL files so they are never treated as cacheable hosted files. Shared `AE_Comp_Hosted_Files_Download_Button` now hard-bypasses the download path for URL records. In native mode, `handle_open_file()` routes to `native.open_external({ url, app: 'chrome' })` with `'default'` fallback. Health section crash fixed (guarded `native_device` against undefined in preview/edit mode).
|
|
||||||
- [x] **[Launcher/Electron] Display mirroring auto-detection (2026-05-20)** — `native:set-display-layout` rewrote to auto-detect displays via `displayplacer list` when no `configStr` provided. Old code silently returned `{ success: false }` (swallowed by `.catch(() => {})` in relay). Now parses `displayplacer list` output, extracts quoted display strings, builds correct mirror/extend commands. Manual `configStr` still takes priority when provided.
|
|
||||||
|
|
||||||
**Svelte-side migration — remaining before May 26:**
|
|
||||||
- [x] **[Launcher] Built-in Svelte default profiles (2026-05-11)** — canonical profile constants live in `ae_launcher__default_launch_profiles.ts` with extension aliases and a `resolve_launch_profile()` 3-step fallback (device config → event config → built-in defaults). Covers macOS (`pptx`, `ppt`, `key`, `odp`, `pdf`), media (`mp4`, `mkv`, `mp3`, etc.), Windows/Parallels variants, and URL path.
|
|
||||||
- [ ] **[Launcher] Composable open flow** — refactor `handle_open_file()` to use
|
- [ ] **[Launcher] Composable open flow** — refactor `handle_open_file()` to use
|
||||||
`copy_from_cache_to_temp` + `run_osascript` / `run_cmd` directly instead of the all-in-one
|
`copy_from_cache_to_temp` + `run_osascript` / `run_cmd` directly instead of the all-in-one
|
||||||
`launch_from_cache`. Finer error handling at each step (verify copy succeeded before
|
`launch_from_cache`. Finer error handling at each step.
|
||||||
attempting script; surface failure clearly in UI).
|
- [ ] **[Launcher] Slide control scripts in Svelte config** — Move AppleScript one-liners from
|
||||||
- [x] **[Launcher] Error handling + fallback (2026-05-14)** — post-script failure is non-fatal: surfaces `'fallback'` status with error detail (file already open). If `open_cmd` itself fails, falls back to `open_local_file_v2` (OS default); surfaces combined error detail if that also fails. UI renders `'open'` / `'fallback'` / `'error'` states distinctly.
|
Electron to device config or Svelte constants.
|
||||||
- [ ] **[Launcher] Slide control scripts in Svelte config** — `control_presentation` AppleScript
|
- [ ] **[Launcher] `kill_processes` target list in config** — Implement UI for manual "Kill Apps"
|
||||||
one-liners are hardcoded in Electron (`shell_handlers.ts` lines 149–159). The Svelte side
|
button and auto-cleanup on file open.
|
||||||
(`launcher_cfg_native_os.svelte`) already calls `native.control_presentation({ app, action })`
|
- [ ] **[Launcher] End-to-end test on macOS** — test pptx and key opens on a real podium Mac.
|
||||||
with next/prev/start/stop buttons wired and working. The Electron IPC call is stable enough
|
|
||||||
for current shows.
|
|
||||||
|
|
||||||
**Remaining (post June 10):** Move scripts to device config (`data_json.control_scripts`) or
|
|
||||||
Svelte constants so behavior can be changed without an Electron rebuild. Replace
|
|
||||||
`native.control_presentation()` call with `native.run_osascript(script)` using the
|
|
||||||
config-resolved script string. The `run_osascript` primitive is already in place; this is
|
|
||||||
purely a wiring/config task. Low priority — hardcoded scripts work fine for PowerPoint and
|
|
||||||
Keynote for now.
|
|
||||||
- [ ] **[Launcher] `kill_processes` target list in config** — The `kill_processes` IPC primitive
|
|
||||||
exists in Electron and is exposed via `electron_relay.ts`, but **is never called from anywhere
|
|
||||||
in Svelte** — no routes, no config components, no file launch flow. No UI exists for it yet.
|
|
||||||
|
|
||||||
**What needs doing (post June 10):**
|
|
||||||
- Decide where the "kill on cleanup" action lives: end of `handle_open_file()` (auto), or a
|
|
||||||
manual "Kill Apps" button in Native OS config, or both.
|
|
||||||
- Process names should come from device config (`data_json.kill_process_li`) with a built-in
|
|
||||||
fallback list (e.g. `['Microsoft PowerPoint', 'Keynote', 'LibreOffice Impress']`).
|
|
||||||
- The Native OS config section (`launcher_cfg_native_os.svelte`) is the natural home for a
|
|
||||||
manual kill button; auto-cleanup on file open would go in `launcher_file_cont.svelte`.
|
|
||||||
|
|
||||||
**Device tab length note:** The Device tab now has 6 collapsible sections (Sync Timers, Health,
|
|
||||||
Native OS, Wallpaper, Launch Timing, Updates). Consider moving Launch Timing + a future Kill
|
|
||||||
Apps control into a dedicated **"Presentation"** section or a fourth tab to keep Device focused
|
|
||||||
on machine/OS concerns rather than per-app launch behavior.
|
|
||||||
- [x] **[Launcher] Launcher config UI — launch_profiles editor (2026-05-14)** — Launch Timing section in `launcher_cfg_launch_timing.svelte` exposes per-profile `post_delay_ms` overrides with Save/Reset per row. PATCHes `event_device.other_json.launcher.launch_profiles` via V3 CRUD. Wired into `launcher_cfg.svelte`. Shown under Technical Mode (`$ae_loc.edit_mode`).
|
|
||||||
- [ ] **[Launcher] End-to-end test on macOS** — test pptx and key opens on a real podium Mac
|
|
||||||
before May 26 setup day. Verify: file copies to tmp correctly, script fires, app opens in
|
|
||||||
slideshow mode, error fallback works.
|
|
||||||
- [ ] **[Launcher/Electron] Wallpaper stops applying after several changes (post-CMSC)** —
|
- [ ] **[Launcher/Electron] Wallpaper stops applying after several changes (post-CMSC)** —
|
||||||
After setting the wallpaper 3–5 times in a session, macOS silently ignores further `set desktop
|
Append timestamp/random suffix to temp filename so macOS always sees a new path.
|
||||||
picture` calls even though the SvelteKit side reports "Saved & Applied ✓". Restore Default
|
|
||||||
(`restore_macos_default_wallpaper`) immediately unblocks it; closing/reopening Electron does
|
|
||||||
not. **Workaround:** use Restore Default, then re-apply. **Root cause:** macOS caches the
|
|
||||||
current wallpaper path and skips the AppleScript call when the downloaded file lands at the
|
|
||||||
same temp path. **Fix (post-CMSC):** in the Electron `set_wallpaper` handler
|
|
||||||
(`aether_app_native_electron`), append a timestamp or random suffix to the temp filename on
|
|
||||||
every download so macOS always sees a new path (e.g. `wallpaper_1748123456.jpg` instead of
|
|
||||||
`wallpaper.jpg`).
|
|
||||||
- [ ] **[Launcher/Electron] Wallpaper drift after display hotplug (post-CMSC)** —
|
- [ ] **[Launcher/Electron] Wallpaper drift after display hotplug (post-CMSC)** —
|
||||||
In live setups, wallpaper can randomly reset when projectors/displays are unplugged or
|
Add resilient reconciliation loop or event-driven reapply on topology change.
|
||||||
reattached. Add a resilient strategy that avoids unnecessary churn when wallpaper is already
|
|
||||||
correct.
|
|
||||||
**Options to evaluate:**
|
|
||||||
- periodic reconciliation loop with backoff/jitter and a cheap "is wallpaper already correct?"
|
|
||||||
check before applying
|
|
||||||
- event-driven reapply when display topology changes (new display detected), leveraging the
|
|
||||||
updated Electron display library
|
|
||||||
- hybrid: event-driven first, periodic safety check as fallback
|
|
||||||
**Goal:** keep podium/projector wallpaper stable without repeatedly setting wallpaper when no
|
|
||||||
change is needed.
|
|
||||||
- [ ] **[Launcher/Electron] `run_cmd`/`run_cmd_sync` — phantom `return_stdout` param (low priority)** —
|
|
||||||
`electron_relay.ts` passes `return_stdout` in the args object, but both IPC handlers ignore it
|
|
||||||
(stdout is always returned). Effectively a no-op, but creates a misleading API contract. Fix:
|
|
||||||
remove the param from relay calls, or honor it in the handlers. No behavioral impact currently.
|
|
||||||
- [ ] **[Launcher/Electron] `power_control` — sudo requirement not surfaced in UI (low priority)** —
|
|
||||||
`shutdown` and `reboot` require `sudo` on Linux. macOS works without it; Launcher only targets
|
|
||||||
macOS so this is a non-issue in production. If Linux podiums are ever deployed, `power_control`
|
|
||||||
shutdown/reboot will fail silently with a permissions error. No fix needed before CMSC.
|
|
||||||
- [ ] **[Launcher/Electron] `manage_recording` — aperture binary path on packaged builds** —
|
|
||||||
Handler resolves the aperture binary via a dev-relative path. Needs verification that the path
|
|
||||||
resolves correctly inside a packaged `.app` bundle (`app.asar` / `resources/`). Not blocking
|
|
||||||
for CMSC (recording not part of CMSC workflow). Verify on next packaged build test.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔴 Axonius DC — June 9 (Badge Printing)
|
## 🔴 Axonius DC — June 9 (Badge Printing)
|
||||||
**Setup/Registration:** June 8 | **Show:** June 9
|
**Setup/Registration:** June 8 | **Show:** June 9
|
||||||
|
|
||||||
- [ ] **[Badges] Epson C3500 fanfold badge layout** — Axonius is using Epson C3500 printers
|
- [ ] **[Badges] Epson C3500 fanfold badge layout** — Create/configure a fanfold badge layout
|
||||||
with fanfold (continuous) badge stock. Create/configure a fanfold badge layout compatible
|
compatible with the Epson C3500 continuous stock format.
|
||||||
with the C3500 format. Must be ready before the June 8 setup/registration day.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🚧 Upcoming High Priority
|
## 🚧 V3 CRUD Migration (Surgical Cleanup)
|
||||||
|
Finalizing the 100% adoption of V3 Standard endpoints and retirement of legacy wrappers.
|
||||||
|
|
||||||
### ~~[IDAA] Random "Access Denied" — Root Cause Review & Fixes~~ ✅ Resolved (2026-05-19)
|
- [x] **[Badges] Presenter Agreement Form** — migrated to `update_ae_obj` (2026-05-21)
|
||||||
|
- [ ] **[Core] Site Domain Bootstrap Refactor** — `load_ae_obj_by_fqdn__site_domain` in
|
||||||
All known root causes fixed across 10+ commits to `src/routes/idaa/(idaa)/+layout.svelte`.
|
`core__site_domain.ts` still uses legacy ID-lookup-by-FQDN. Refactor to use V3
|
||||||
Deploying as of 2026-05-19. Monitor for further member reports.
|
`api.search_ae_obj` with fqdn filter per integration guide.
|
||||||
|
- [ ] **[Core] Legacy Utility Helpers** — Refactor `ae_core_functions.ts` to use V3 helpers.
|
||||||
#### All fixes applied
|
- [ ] **[Cleanup] Delete Legacy Wrappers** — Once all callsites are migrated, remove
|
||||||
- [x] **Server-side Novi verification migrated (key fix for hotel/VPN/Cloudflare-filtered networks)**
|
`src/lib/ae_api/api_get__crud_obj_id.ts` and the legacy exports from `api.ts`.
|
||||||
`verify_novi_uuid()` now calls `GET /v3/action/idaa/novi_member/{uuid}` through the Aether
|
|
||||||
backend (server-to-server, Redis-cached 4h) instead of making a browser-to-Novi call.
|
|
||||||
Eliminates false Access Denied for members on hotel/conference WiFi, VPNs, and corporate
|
|
||||||
networks where the member's IP was rejected by Novi/Cloudflare.
|
|
||||||
Frontend: `(idaa)/+layout.svelte` | Backend: FastAPI `aether_api_fastapi` | Docs: `GUIDE__AE_API_V3_for_Frontend.md` §12, `CLIENT__IDAA_and_customized_mods.md`
|
|
||||||
- [x] Novi TTL extended to **12 hours** (5 min → 45 min → 12 h) — covers a full conference day
|
|
||||||
- [x] Access Denied on iframe reload (sessionStorage URL preservation) — `2855e091f`
|
|
||||||
- [x] TTL cache bypassed when `$ae_loc` auth flags reset — `2855e091f`
|
|
||||||
- [x] "Verification Unavailable" screen distinct from "Access Denied" — `2855e091f`
|
|
||||||
- [x] "Try Again" without page reload (`retry_count` pattern) — `2855e091f`
|
|
||||||
- [x] 12 s AbortController hard timeout on Novi fetch — `e921ca973`
|
|
||||||
- [x] Network/AbortError gets 3 s grace + one retry — `e921ca973`
|
|
||||||
- [x] Clear Cache & Reload added to Access Denied state (iframe mode) — `2855e091f`
|
|
||||||
- [x] `VERIFY_TIMEOUT_MS` 8 s → 35 s (was firing mid-retry, causing premature Reset clicks) — `53fd5e7de`
|
|
||||||
- [x] `sessionStorage` try-catch (iOS Safari Private Browsing throws on access) — `53fd5e7de`
|
|
||||||
- [x] Appshell stores guarded behind `account_id` — `8850db89c`
|
|
||||||
- [x] Recovery meetings over-filtering bug (API `default_qry_str`) — `76e21b08f`
|
|
||||||
- [x] A→Z sort in recovery meetings API revalidation path — `c0386f27b`
|
|
||||||
- [x] `events.event` IDB content version bump (stale cache) — previous commit
|
|
||||||
|
|
||||||
#### Root layout SWR verified safe:
|
|
||||||
The root `+layout.ts` builds `ae_loc_init` as a plain site-config object (no `authenticated_access`,
|
|
||||||
`trusted_access`, or `access_type` fields). The root layout sync effect
|
|
||||||
`$ae_loc = { ...current_loc, ...ae_acct.loc }` therefore cannot overwrite Novi-set auth flags.
|
|
||||||
Confirmed safe — this is NOT a cause of Access Denied.
|
|
||||||
|
|
||||||
#### Remaining architectural note:
|
|
||||||
The long-term fix for the coarse `$ae_loc` reactivity (Svelte 4 store) causing Effect 2 to
|
|
||||||
re-run on unrelated writes is tracked under **[Stores] Svelte 4 → Svelte 5 State Migration**
|
|
||||||
below. The TTL + `verify_in_flight` guards are the current mitigation.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### ~~[IDAA] Server-side Novi verification — 503 not auto-retried~~ ✅ Fixed (2026-05-20)
|
## 🚧 High Priority Workstreams
|
||||||
|
|
||||||
---
|
### [Stores] Svelte 4 → Svelte 5 State Migration
|
||||||
|
The app uses `svelte-persisted-store` (coarse reactivity). Migration target: replace with Svelte 5
|
||||||
### [API] GET/POST retry hardening — differentiate timeout aborts vs intentional aborts
|
`$state`-based persistence for fine-grained updates.
|
||||||
**Status:** ✅ Completed (2026-05-21)
|
|
||||||
|
|
||||||
Recent API helper fixes restored retry/backoff for transient network `TypeError` failures.
|
|
||||||
Timeout-triggered aborts are now handled separately from intentional/user aborts so the
|
|
||||||
retry loop behavior is correct.
|
|
||||||
|
|
||||||
**Decision (for now):** Keep the global default timeout at **20s**.
|
|
||||||
|
|
||||||
**Implemented:**
|
|
||||||
- GET/POST now explicitly distinguish abort class in helper code:
|
|
||||||
- **Intentional abort** (navigation/unmount/caller cancel): fail fast, no retry
|
|
||||||
- **Timeout abort** (helper timer): retryable via existing retry loop
|
|
||||||
- Timeout classification added with per-attempt timeout flag (not `AbortError` name-only logic).
|
|
||||||
- Backoff behavior retained for retryable failures (`2s -> 4s -> 6s -> 8s`, cap 8s).
|
|
||||||
- Existing fail-fast class retained for 400/401/403/422, with auth-expired store signaling on 401/403.
|
|
||||||
- Validation done:
|
|
||||||
- `npx svelte-check` clean
|
|
||||||
- API Playwright tests updated/fixed and passing (`v3_api_security.modern`, `v3_api_nested_crud`)
|
|
||||||
|
|
||||||
**Timeout policy improvement (class-based):**
|
|
||||||
- Keep **20s default** as baseline.
|
|
||||||
- Add request classes with explicit timeout selection at callsites/wrappers (not random per-page values):
|
|
||||||
- fast CRUD/read/search: ~20s baseline
|
|
||||||
- medium actions: higher bounded timeout
|
|
||||||
- heavy actions (uploads, exports, ffmpeg/video clip): explicit long timeout already required
|
|
||||||
- Centralize the class mapping so timeout intent is clear and audit-friendly.
|
|
||||||
|
|
||||||
**Primary files:**
|
|
||||||
- `src/lib/ae_api/api_get_object.ts`
|
|
||||||
- `src/lib/ae_api/api_post_object.ts`
|
|
||||||
- Wrapper callsites in `src/lib/ae_api/` and legacy bridge points in `src/lib/api/api.ts`
|
|
||||||
|
|
||||||
**Acceptance criteria:**
|
|
||||||
- Timeout-aborted requests retry according to retry_count/backoff policy.
|
|
||||||
- User/navigation aborts still fail fast with no retry.
|
|
||||||
- No regression on 400/401/403/422 fail-fast handling.
|
|
||||||
- Existing long-running flows that already set explicit timeouts (uploads/video tools/exports)
|
|
||||||
continue to function without behavior regressions.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### [API] PATCH/DELETE retry hardening — parity with GET/POST
|
|
||||||
**Status:** ✅ Completed (2026-05-21)
|
|
||||||
|
|
||||||
PATCH and DELETE now implement the same retry-classification model used in GET/POST,
|
|
||||||
including timeout abort separation and capped retry backoff.
|
|
||||||
|
|
||||||
**Implemented:**
|
|
||||||
- PATCH:
|
|
||||||
- Per-attempt timeout controller with explicit timeout-abort flag.
|
|
||||||
- Retries timeout/network transient failures only.
|
|
||||||
- Intentional caller aborts fail fast (no retry).
|
|
||||||
- Fail-fast retained for 400/401/403/422.
|
|
||||||
- Backoff capped at `2s -> 4s -> 6s -> 8s`.
|
|
||||||
- DELETE:
|
|
||||||
- Same timeout-vs-intentional abort separation.
|
|
||||||
- Same retry class for timeout/network transient failures.
|
|
||||||
- Same caller-abort fail-fast behavior.
|
|
||||||
- Explicit fail-fast for 400/401/403/422.
|
|
||||||
- Backoff capped at `2s -> 4s -> 6s -> 8s`.
|
|
||||||
|
|
||||||
**Mutation safety note:**
|
|
||||||
- PATCH/DELETE can have ambiguous commit state on timeout. Current policy is conservative:
|
|
||||||
retries target obvious transient failure class (timeout/network), while caller aborts remain
|
|
||||||
fail-fast to avoid duplicate side effects during navigation/unmount flows.
|
|
||||||
|
|
||||||
**Primary files:**
|
|
||||||
- `src/lib/ae_api/api_patch_object.ts`
|
|
||||||
- `src/lib/ae_api/api_delete_object.ts`
|
|
||||||
|
|
||||||
**Acceptance criteria:**
|
|
||||||
- ✅ PATCH and DELETE timeout-aborts retry under capped backoff.
|
|
||||||
- ✅ Caller/navigation aborts do not retry.
|
|
||||||
- ✅ No regression for 400/401/403/422 fail-fast behavior.
|
|
||||||
- ✅ `npx svelte-check` clean, API-focused Playwright tests remained green during rollout.
|
|
||||||
|
|
||||||
**Additional fixes found during review pass (2026-05-21, commit ea765d8ad):**
|
|
||||||
- PATCH + DELETE: default timeout lowered from 60s → 20s to match GET/POST. No callers set
|
|
||||||
explicit timeouts; 60s × 5 retries = 5-minute worst case before giving up.
|
|
||||||
- DELETE: added `ae_auth_error` import and session-expired banner on 401/403. All other
|
|
||||||
files (GET/POST/PATCH) trigger the banner; DELETE was missing it, causing stale-session
|
|
||||||
deletes to silently return false with no user-visible feedback.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### [Testing] V3 API performance probe (basic stress rounds)
|
|
||||||
**Status:** ✅ Completed baseline harness (2026-05-21)
|
|
||||||
|
|
||||||
Implemented a gated Playwright probe for quick repeated list-query timing against live V3 endpoints.
|
|
||||||
|
|
||||||
**Files:**
|
|
||||||
- `tests/v3_api_latency_probe.test.ts`
|
|
||||||
- `tests/README.md` (run/tuning docs)
|
|
||||||
|
|
||||||
**Current capabilities:**
|
|
||||||
- Measures rounds for event sessions, journal entries, and user lists.
|
|
||||||
- Writes per-run JSON + Markdown reports to `tests/results/`.
|
|
||||||
- Optional anomaly thresholds for error-rate / p95 / empty-row detection.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### [Launcher/VLC] Linux playback — fullscreen + pause-on-end not working
|
|
||||||
**Status:** Mac ✅ working perfectly; Linux 🚧 deferred for later investigation
|
|
||||||
**Date discovered:** 2026-05-20
|
|
||||||
|
|
||||||
macOS VLC profile (direct binary path) successfully:
|
|
||||||
- Opens VLC with the media file
|
|
||||||
- Plays + pauses on the last frame (instead of returning to playlist)
|
|
||||||
- Fullscreen toggle works (Cmd+F via AppleScript post-script)
|
|
||||||
|
|
||||||
Linux VLC command (`vlc --no-play-and-exit --play-and-pause "{{path}}"`) currently:
|
|
||||||
- Does NOT go fullscreen
|
|
||||||
- Does NOT pause on the last frame (plays through, returns to playlist)
|
|
||||||
|
|
||||||
**Current state:** Both macOS and Linux commands in `ae_launcher__default_launch_profiles.ts`.
|
|
||||||
macOS is the primary venue deployment platform; Linux support is nice-to-have.
|
|
||||||
|
|
||||||
**Investigation needed:** Determine if the VLC flags are being interpreted on Linux,
|
|
||||||
or if there's a launcher execution layer issue (e.g. `shell:` prefix handling).
|
|
||||||
File: `src/lib/ae_events/ae_launcher__default_launch_profiles.ts` — `make_vlc_mirror_linux_profile()`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### [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`.
|
- [ ] **Phase A — Project plan + wrapper decision:** Write `PROJECT__Stores_Svelte5_Migration.md`.
|
||||||
Decide: `runed` library vs. custom `$state` + localStorage wrapper. Audit all store consumers.
|
- [ ] **Phase B — Core auth stores (highest impact):** `ae_loc`, `idaa_loc`.
|
||||||
Identify stores in priority order. Estimate blast radius per store.
|
- [ ] **Phase C — Remaining persisted stores:** `ae_api`, `ae_events_stores`.
|
||||||
|
- [ ] **Phase D — Non-persisted writable stores:** `ae_sess`, `slct`, `ae_snip`, etc.
|
||||||
|
|
||||||
- [ ] **Phase B — Core auth stores (highest impact, start here):**
|
### [Stores] IDB Content Version System
|
||||||
- `ae_loc` (persisted) — auth flags, site cfg, UI state; ~471 consumer sites across 150+ files
|
- [x] Write `check_and_clear_idb_tables()` helper.
|
||||||
- `idaa_loc` (persisted) — Novi auth, IDAA query prefs
|
- [x] Wire helper into `db_journals.ts` and IDAA layout.
|
||||||
These two cause the most reactive noise. Migrating them also unlocks Phase 2c (separate `ae_auth`
|
- [ ] Roll out to `db_events.ts` (module-wide: session, presenter, badge, etc.).
|
||||||
store) since the callsite sweep is now required anyway.
|
- [ ] Roll out to `db_core.ts` (site_domain, person, user).
|
||||||
|
|
||||||
- [ ] **Phase C — Remaining persisted stores:**
|
### [TypeScript] svelte-check hidden errors
|
||||||
- `ae_api` (persisted) — API config / JWT
|
- [ ] **[flowbite-svelte] `ModalProps.children` — 31 errors across 26 files.**
|
||||||
- `ae_events_stores` persisted entries (badges, launcher, leads, pres_mgmt loc stores)
|
Replace `children` prop binding with Svelte snippet syntax.
|
||||||
|
|
||||||
- [ ] **Phase D — Non-persisted writable stores:**
|
### [Journals] Journal Entry Config follow-ups
|
||||||
- `ae_sess`, `idaa_sess`, `slct`, `slct_trigger`, `ae_auth_error`, `ae_trig`, `ae_snip`, etc.
|
- [ ] **[Journals] Entry passcode secondary auth** — implement `passcode_hash` comparison.
|
||||||
- Lower urgency (no localStorage churn), but fine-grained reactivity still beneficial.
|
- [ ] **[Journals] Summary AI shortcut** — add button to modal.
|
||||||
|
|
||||||
- [ ] **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] IDB Content Version System
|
## 🧪 Testing & Optimization
|
||||||
Scaffolded in `store_versions.ts` (`IDB_CONTENT_VERSIONS` constant + `check_and_clear_idb_table()`
|
|
||||||
helper) and `core__idb_dexie.ts` (`check_and_clear_idb_tables()` batch helper). Mirrors
|
|
||||||
`AE_LOC_VERSION` but targets Dexie table contents rather than localStorage keys.
|
|
||||||
|
|
||||||
**Currently active:** `journals.journal_entry` (db_journals.ts), `events.event` (IDAA layout).
|
|
||||||
All other tables are defined but not yet wired.
|
|
||||||
|
|
||||||
**Real-world impact:** Stale IDB records from a `properties_to_save` change were the root cause
|
|
||||||
of the IDAA Recovery Meetings "no meetings found" bug — a ~1-year unresolved issue (2025–2026).
|
|
||||||
Fixed 2026-05-16 by wiring `events.event` into the IDAA layout and bumping its version to 2.
|
|
||||||
See `BOOTSTRAP__AI_Agent_Quickstart.md` mistake #13 for the full postmortem.
|
|
||||||
|
|
||||||
**How it works:**
|
|
||||||
- `check_and_clear_idb_table(db_table, 'module', 'table')` reads a localStorage key with the
|
|
||||||
expected version from `IDB_CONTENT_VERSIONS`
|
|
||||||
- On mismatch (or missing key), the Dexie table is cleared and the key is updated
|
|
||||||
- SWR repopulates from API on next access — no explicit reload needed
|
|
||||||
- Cost on version match: one `localStorage.getItem()` — effectively free
|
|
||||||
- Bump a table's version in `IDB_CONTENT_VERSIONS` when `properties_to_save` changes shape
|
|
||||||
|
|
||||||
**IDAA consideration:**
|
|
||||||
IDAA tables are already cleared by `indexedDB.deleteDatabase()` on sign-out/auth failure in
|
|
||||||
`(idaa)/+layout.svelte`. The content version check is a *complementary* deploy-time reset, not
|
|
||||||
a replacement.
|
|
||||||
|
|
||||||
**Tasks:**
|
|
||||||
- [x] Write `check_and_clear_idb_tables()` helper in `core__idb_dexie.ts` (2026-05-14)
|
|
||||||
- [x] Wire helper into `db_journals.ts` (pilot — `journal_entry: 2` cleared stale content_md_html) (2026-05-14)
|
|
||||||
- [x] Wire `events.event` into IDAA layout `(idaa)/+layout.svelte` + bump version to 2 (2026-05-16)
|
|
||||||
- [ ] Roll out to `db_events.ts` (module-wide: session, presenter, badge, device, location, file)
|
|
||||||
- [ ] Roll out to `db_core.ts` (site_domain, person, user)
|
|
||||||
- [ ] Roll out to IDAA modules (`db_posts.ts`, `db_archives.ts`) — verify auth-wipe interaction first
|
|
||||||
- [ ] Consolidate the two `check_and_clear_idb_table*` helpers (single-table in `store_versions.ts`, batch in `core__idb_dexie.ts`)
|
|
||||||
|
|
||||||
### [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).
|
|
||||||
|
|
||||||
### [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] IDB fast-path contact search — Recovery Meetings (2026-04-08, updated 2026-05-19)**
|
|
||||||
**API path is now working** — `default_qry_str` already includes contact name/email.
|
|
||||||
Two bugs were fixed 2026-05-19: (1) STORED GENERATED columns had stale values; forced
|
|
||||||
rebuild via fake updates. (2) Frontend secondary filter was re-checking text against
|
|
||||||
response fields, silently dropping API results that matched only via `default_qry_str`.
|
|
||||||
|
|
||||||
**Remaining gap — IDB fast-path only:** The local cache fast-path returns all cached meetings
|
|
||||||
without text filtering; users see the unfiltered list first, then the API-filtered result
|
|
||||||
replaces it. To make contact matches appear instantly from cache:
|
|
||||||
- `src/lib/ae_events/ae_events__event.ts` → fast-path filter in `search__event()`: parse
|
|
||||||
`contact_li_json` and include contact names/emails in the local text match.
|
|
||||||
- `src/routes/idaa/(idaa)/recovery_meetings/+page.svelte` fast-path display: same filter.
|
|
||||||
Backend enhancement (`contact_li_json_ext` whitelist) is not required for this — the IDB
|
|
||||||
records already store `contact_li_json` raw JSON which can be parsed client-side.
|
|
||||||
|
|
||||||
|
- [ ] **[IDAA] IDB fast-path contact search** — parse `contact_li_json` in `search__event()`.
|
||||||
- [ ] **[IDAA] Optimize Recovery Meetings SQL VIEW and indexes.**
|
- [ ] **[IDAA] Optimize Recovery Meetings SQL VIEW and indexes.**
|
||||||
The current search query can be taxing on the server. With ~150 active meetings, the view
|
- [ ] **[IDAA / Events] Audit `default_qry_str` coverage** in all other event search pages.
|
||||||
logic and supporting indexes need a performance review to ensure fast responses as the
|
- [ ] **[Launcher/VLC] Linux playback investigation** — fullscreen + pause-on-end flags.
|
||||||
database grows. (Requested 2026-05-18)
|
|
||||||
|
|
||||||
- [ ] **[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
|
## ⚙️ DevOps & Backend
|
||||||
- [ ] **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),
|
- [ ] **[Backend] Re-add `Access-Control-Allow-Private-Network: true` CORS header.**
|
||||||
alongside the existing Jitsi URL Builder section. Should allow editing key fields in
|
- [ ] **[DevOps] Nginx caching** — Investigate `index.html` cache-pickup issues.
|
||||||
`site_cfg_json` without needing phpMyAdmin:
|
- [ ] **[DevOps] Simplify Dockerfile env file selection** — Use plain `.env` instead of `BUILD_MODE`.
|
||||||
- `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~~ ✅ Fixed (2026-05-14)
|
|
||||||
Guard added to `src/service-worker.js` fetch handler: `if (!event.request.url.startsWith('http')) return;`
|
|
||||||
Also skips cross-origin requests entirely (origin check). No console errors from extension URLs.
|
|
||||||
|
|
||||||
### [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] Nginx caching — app version pickup issue
|
|
||||||
- [ ] **Investigate Nginx reverse proxy caching so users pick up new app deploys.**
|
|
||||||
Some users are not getting the updated app after a deploy. SvelteKit hashes JS/CSS bundle
|
|
||||||
filenames (cache-busting is automatic), but if Nginx or the browser caches `index.html`
|
|
||||||
itself, users get stale HTML pointing to old (possibly deleted) hashed assets.
|
|
||||||
|
|
||||||
**Check:**
|
|
||||||
- `proxy_cache` / `expires` directives in Nginx config for the SvelteKit app location
|
|
||||||
- Actual `Cache-Control` header on `/` — `curl -I https://<host>/` to verify
|
|
||||||
- Any service worker registration that might add another caching layer
|
|
||||||
|
|
||||||
**Expected fix:** Serve `index.html` with `Cache-Control: no-cache` (or `no-store`).
|
|
||||||
Hashed static assets (`/_app/immutable/`) can stay aggressively cached (`max-age=31536000,
|
|
||||||
immutable`). Root page must always be fresh so users pick up the new bundle references.
|
|
||||||
|
|
||||||
**Task ID:** #182928308 (shared Kanban)
|
|
||||||
|
|
||||||
### [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
|
|
||||||
|
|
||||||
Low risk but unnecessary churn — defer until after the next active show.
|
|
||||||
|
|
||||||
- [ ] **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] `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)
|
## ✅ Completed (archived)
|
||||||
See the full completed history in:
|
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-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)
|
[documentation/archive/TODO__Agents__ARCHIVE_2026-04.md](documentation/archive/TODO__Agents__ARCHIVE_2026-04.md)
|
||||||
|
[documentation/archive/TODO__Agents__ARCHIVE_2026-05.md](documentation/archive/TODO__Agents__ARCHIVE_2026-05.md)
|
||||||
|
|||||||
@@ -1,326 +1,54 @@
|
|||||||
# Frontend Agent Task List
|
# Frontend Agent Task List (Archived May 2026)
|
||||||
> Use this file to track steps for complex features or bug fixes.
|
|
||||||
> **Status:** Stable — ongoing development.
|
|
||||||
|
|
||||||
|
## ✅ Completed (2026-05)
|
||||||
|
|
||||||
## 🔴 BGH Conference — April 21 (Must Fix Before Event)
|
### [API] GET/POST retry hardening — differentiate timeout aborts vs intentional aborts
|
||||||
|
**Status:** ✅ Completed (2026-05-21)
|
||||||
|
- GET/POST now explicitly distinguish abort class in helper code.
|
||||||
|
- Timeout-triggered aborts are retryable via existing retry loop; intentional aborts fail fast.
|
||||||
|
- Backoff behavior retained (`2s -> 4s -> 6s -> 8s`).
|
||||||
|
- Validation done via Playwright tests.
|
||||||
|
|
||||||
- [x] **[Locations] Event Locations list does not auto-load** — added `+page.ts` to trigger
|
### [API] PATCH/DELETE retry hardening — parity with GET/POST
|
||||||
`load_ae_obj_li__event_location` on page load. Also fixed session query using stale
|
**Status:** ✅ Completed (2026-05-21)
|
||||||
`event_location_id_random` index (should be `event_location_id`). (2026-04-19)
|
- PATCH and DELETE now implement the same retry-classification model used in GET/POST.
|
||||||
|
- Added explicit fail-fast for 400/401/403/422.
|
||||||
|
- DELETE now triggers the session-expired banner on 401/403.
|
||||||
|
|
||||||
- [x] **[Files] Warn/error on `.ppt`/`.doc` upload** — warning rows shown per-file in upload table;
|
### [Testing] V3 API performance probe (basic stress rounds)
|
||||||
non-trusted users are fully blocked (`file_list_status = 'blocked_legacy'`); trusted users see
|
**Status:** ✅ Completed baseline harness (2026-05-21)
|
||||||
warnings but can still upload. Covers `.ppt`, `.doc` (block) and other legacy exts (warn-only).
|
- Implemented a gated Playwright probe for quick repeated list-query timing against live V3 endpoints.
|
||||||
(2026-04-19)
|
- Writes reports to `tests/results/`.
|
||||||
|
|
||||||
- [x] **[Files] Hide internal-purpose files from Launcher by default** — renamed `hide_draft` prop
|
### [IDAA] Random "Access Denied" — Root Cause Review & Fixes
|
||||||
to `show_internal_purpose_files` in `launcher_file_cont.svelte`; logic flipped so `false` (the
|
**Status:** ✅ Resolved (2026-05-19)
|
||||||
default) hides files with `file_purpose == 'outline'`, `'draft'`, or `'admin'`. Store key renamed
|
- Server-side Novi verification migrated to V3 action endpoint.
|
||||||
from `hide_content__draft_files` (inverted, misleading) to `show_content__internal_files: false`
|
- Extended Novi TTL to 12 hours.
|
||||||
(show-on-opt-in, consistent with all other `show_content__*` flags). Updated across all 8 Launcher
|
- Hardened retry and timeout logic in `+layout.svelte`.
|
||||||
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`
|
### [IDAA] Server-side Novi verification — 503 not auto-retried
|
||||||
was calling `load_ae_obj_id__event_session` directly AND then `goto()` triggered `+page.ts` which
|
**Status:** ✅ Fixed (2026-05-20)
|
||||||
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,
|
### [IDAA] Jitsi Reports filters
|
||||||
deploy, and verify on onsite Mac laptops. Additional testing of cache/launch flow still needed
|
**Status:** ✅ Finished (2026-05-06)
|
||||||
before April 21.
|
- Added Novi UUID exclusion plus meeting-name whitelist filtering.
|
||||||
|
|
||||||
- [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
|
### [PWA] Service worker ignoring `chrome-extension://` requests
|
||||||
Browser console shows repeated errors:
|
**Status:** ✅ Fixed (2026-05-14)
|
||||||
```text
|
- Added guard to filter out non-http/https requests before Attempting to cache.
|
||||||
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
|
### [Electron/Launcher] Display mirroring auto-detection
|
||||||
Placeholder text inherits full input text color in light mode (Tailwind CSS default), making
|
**Status:** ✅ Completed (2026-05-20)
|
||||||
placeholders indistinguishable from filled-in values. Most visible in badge print controls
|
- `native:set-display-layout` now auto-detects displays via `displayplacer list`.
|
||||||
where placeholders show the actual badge value (e.g. "John Smith").
|
|
||||||
|
|
||||||
Workaround: scoped `::placeholder` rule added to `ae_comp__badge_print_controls.svelte`
|
### [Launcher] Force Sync Location
|
||||||
(gray-400 light / gray-500 dark) — `commit 7733ef8`.
|
**Status:** ✅ Completed (2026-05-21)
|
||||||
|
- Implemented manual trigger and background engine logic to pre-cache all location files.
|
||||||
|
|
||||||
**Long-term fix:** Add a global rule to the main CSS (e.g. `src/app.css` or a theme file):
|
### [Launcher] Chronological Download Priority
|
||||||
```css
|
**Status:** ✅ Completed (2026-05-21)
|
||||||
::placeholder {
|
- Refactored download queue to prioritize Event Assets > Early Sessions > Presentation Order > Created Date.
|
||||||
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.
|
|
||||||
|
|
||||||
|
### [Launcher] Error handling + fallback
|
||||||
|
**Status:** ✅ Completed (2026-05-14)
|
||||||
### [Backend/DevOps] Re-add `Access-Control-Allow-Private-Network: true` CORS header
|
- Post-script failure surfaces 'fallback' status; `open_cmd` failure falls back to OS default.
|
||||||
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 `<a>` 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)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user