Commit Graph

2446 Commits

Author SHA1 Message Date
Scott Idem
f6c950abdf fix(pres_mgmt): fix hidden sessions toggle not showing hidden sessions
Three related fixes for the hide/show toggle in Pres Mgmt:

1. ae_events__event_session.ts: remove redundant search_query.and hide
   filter and instead pass `hidden` to api.search_ae_obj as a URL param.
   The backend StatusFilterParams defaults to hidden='not_hidden', so
   without this the API always filtered to hide=0 regardless of intent.

2. pres_mgmt/+page.svelte (SCENARIO 2): capture qry_hidden as a
   $derived.by dependency so the liveQuery instance is recreated on
   toggle — prevents hidden sessions briefly appearing before the
   debounce fires (blink fix).

3. pres_mgmt/+page.svelte (API call): use params.qry_hidden snapshot
   instead of the live store to prevent race if user toggles during a
   pending search.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 22:24:04 -04:00
Scott Idem
3d6f9035c8 docs(todo): track build_tmp_sort rollout progress
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:59:30 -04:00
Scott Idem
535efd9c4b fix(pres_mgmt): add group as leading sort prefix for event_presentation
Group should partition before priority in the sort chain, consistent with
how all other AE objects are sorted (group → priority → sort → ...).
Was accidentally omitted when switching to build_tmp_sort.

Full order: group → priority DESC → sort ASC → start_datetime ASC → code ASC → name ASC

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:48:48 -04:00
Scott Idem
4a39ca1468 refactor(sort): introduce build_tmp_sort utility; apply to event_presentation and journals
Creates src/lib/ae_core/core__idb_sort.ts with build_tmp_sort() — a shared
helper for computing tmp_sort_1/2/3 fields stored in Dexie. Fixes two bugs
present in all generic _process_generic_props implementations:
  - priority encoded as 0/1 ASC (true sorted last); now inverted: true→'0'
  - sort stored as unpadded string ("10" < "2"); now 8-char zero-padded

Applied to:
  - ae_events__event_presentation: replaces inline specific_processor code
  - ae_journals__journal + ae_journals__journal_entry: replaces manual formulas;
    journal liveQueries (.reverse().sortBy()) updated to plain .sortBy() since
    the inverted encoding handles direction without needing Dexie's .reverse()

Other modules (sessions, presenters, locations, posts, core) left unchanged
until their sort behavior is reviewed separately.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:38:25 -04:00
Scott Idem
182a066d38 fix(pres_mgmt): use tmp_sort_2 for presentation sort in Pres Mgmt and Launcher
Compute presentation-specific tmp_sort_1/tmp_sort_2 in specific_processor,
overriding the generic values from _process_generic_props which had two bugs:
- priority encoded as 0/1 ASC (backwards — true should sort first)
- sort stored as unpadded string ("10" < "2" lexicographically)
- start_datetime and code not included (presentation-specific fields)

New encoding: priority(inv)_sort(8-padded)_start_datetime_code[_name]
Both liveQueries (Pres Mgmt session page, Launcher session view) now use
.sortBy('tmp_sort_2') — cleaner and uses the indexed field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:20:50 -04:00
Scott Idem
35fed53e2a fix(launcher): sort presentations by priority > sort > start_datetime > code > name
Replaced single-field sortBy() (poster→name, oral→start_datetime) with
toArray() + JS comparator matching the same sort chain as Pres Mgmt.
Removes the sort_by branch since the comparator handles both session types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:11:14 -04:00
Scott Idem
322abc2691 fix(pres_mgmt): sort presentations by priority > sort > start_datetime > code > name
Replaced single-field sortBy('name') with toArray() + JS comparator to
implement the full desired sort chain. Dexie's sortBy() only supports a
single indexed field, so multi-field ordering requires a JS sort pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 13:38:13 -04:00
Scott Idem
cfaf687717 fix(events): event location file load on mount + launcher pruning scope fix + remove legacy launcher btn
- Location page now calls load_ae_obj_li__event_file on mount so files
  appear immediately without requiring a manual Refresh press.
- _load_event_location_sub_data (Launcher 60s sync) now uses hidden='all'
  with default limit (100) instead of hidden='not_hidden'/limit=25, which
  was pruning valid Dexie records when Pres Mgmt and Launcher were both
  open on the same location simultaneously.
- Removed the legacy launcher button (Send icon, /event/ path) from the
  Locations list; removed unused Send icon import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 21:41:32 -04:00
Scott Idem
e7620a1c06 fix(events): replace db_events.file.clear() with targeted reload in refresh button
Same nuclear cache-clearing bug as the upload component fix. Clicking "Refresh
files" for one Location was wiping every event_file record from Dexie, leaving
all other Locations and Presenters with no files until their own background
syncs fired.

Now does a targeted load for the specific object only — same pattern as the
upload component commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 21:07:00 -04:00
Scott Idem
e4e2174c97 fix(upload): replace db_events.file.clear() with targeted per-object reload
db_events.file.clear() after every upload was nuking the entire Dexie file
table. Every liveQuery watching any file list (Launcher, other locations,
sessions, presenters) would immediately show 0 results. Only the uploaded-to
object's files were reloaded; all others remained empty until their own
background syncs fired — intermittent disappearance that depended on timing.

Fix: targeted load_ae_obj_li__event_file for only the current link_to_id,
which uses the SWR pattern (returns cache + background refresh that includes
the newly created file). Other objects' file caches are untouched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 20:33:12 -04:00
Scott Idem
d3bf314c62 fix(launcher): refresh file lists periodically to prune deleted/hidden files
The Launcher's background sync never called load_ae_obj_li__event_file for
presenter/session files. That function contains stale-record pruning that
removes deleted or hidden files from Dexie; without it, the Launcher's IDB
retained stale file records indefinitely until manually cleared.

Changes:
- refresh_presenter_data: add inc_file_li=true so presenter files are pruned
  every 120s via the existing presenter loop
- refresh_current_session_files(): new function that fetches/prunes session-
  level file lists for the selected session
- timer__file_list: 60s interval for refresh_current_session_files
- $effect on event_session_id: fires refresh_current_session_files immediately
  on session switch (no wait for next timer tick)

Propagation time: deleted/hidden files visible on remote Launchers within
~60s (session files) or ~120s (presenter files) automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 20:12:10 -04:00
Scott Idem
d32355a1a2 docs(launcher): add cfg menu inventory and v3.1 design docs
MODULE__AE_Events_Launcher_Config_Menu.md — v3.0 inventory of the
3-tab drawer layout (now superseded but kept as reference baseline).
MODULE__AE_Events_Launcher_Config_Menu_new.md — v3.1 unified design
spec that drove the sidebar tab migration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:17:07 -04:00
Scott Idem
213eabd8c1 feat(launcher): migrate cfg menu to 7-tab sidebar layout (v3.1)
Replaces the 3-tab horizontal bar (Setup / Device / Dev) with a vertical
sidebar navigation matching the v3.1 design spec. New tab structure:

  General       — App Modes, Screen Saver (operator-facing)
  Connectivity  — Remote Controller & WebSocket
  Sync & Health — Sync Timers, System Health
  Native OS     — OS controls (native or edit_mode preview)
  Wallpaper     — Desktop wallpaper settings
  Advanced      — Launch Timing, Updates (edit_mode only)
  Maintenance   — Local Resets, Debug Panel (edit_mode only)

Layout changes:
- Sidebar nav (w-48) + scrollable main content area replace inline tab bar
- Tab header shows label + description subtitle
- Technical Mode toggle is now a labeled button (not hidden icon)
- Footer shows Account/Device context; Reload moved to header
- {#key active_tab} wrapper ensures clean component remount on tab switch
- Remove unused icons (SlidersHorizontal, HeartPulse, Timer, CloudDownload)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:14:52 -04:00
Scott Idem
872291b0a0 fix(launcher): replace Flowbite Modal with custom overlay for cfg panel
Two problems with the Flowbite <Modal> approach:
1. Built-in dismissable CloseButton rendered with no functional dismiss path
   (no title/form), appearing centered in the panel.
2. size="xl" (max-w-7xl) left no backdrop area on typical laptop screens,
   making outsideclose impossible to trigger.

Replace with a simple custom overlay: full-screen backdrop div that closes
on click, inner panel with stopPropagation. Matches the original Drawer
pattern. close_cfg() writes to store immediately on backdrop click for
reliable persistence independent of effect timing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:04:34 -04:00
Scott Idem
25d17841e4 fix(launcher): fix cfg modal default-open and outside-click persistence
Two bugs in the Launcher Config Modal after the Drawer→Modal migration:
1. Pre-existing persisted configs (missing hide_drawer__cfg field) caused
   !undefined = true, opening the modal on every fresh load. Fixed by adding
   a field-level initialization guard after the full-object guard.
2. $-syntax writes inside untrack() were suppressed by svelte-persisted-store,
   so outside-click closure was never persisted. Fixed by using events_loc.update()
   directly to ensure the write reaches localStorage serialization. Added equality
   guard to effect 1 to prevent spurious modal flicker from whole-store re-fires.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 21:36:01 -04:00
Scott Idem
6282fb167f fix(launcher): use $derived.by for session liveQueries to fix stale presentation/presenter data
When switching sessions within the same location, presentations and presenters
were not updating. The root cause: plain $derived(liveQuery(...)) never recreates
the Observable when slct__event_session_id changes, because liveQuery's async
callback runs in Dexie's zone where Svelte tracking is off. Dexie's range-level
change detection then ignores new session data (it arrives under a different
event_session_id index value, outside the originally observed range).

Replaced all four liveQuery declarations with $derived.by(() => { const id = ...;
return liveQuery(...id...); }) — the same pattern already used in +layout.svelte
for location-dependent queries. Svelte tracks the id read in the outer closure
and recreates the Observable on every session change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 19:55:17 -04:00
Scott Idem
a90572bcb8 fix(idaa): ensure breakout links preserve site access key and uuid
Proactively re-injects 'key' (site access key) and 'uuid' (Novi token)
into 'Open Externally' and 'Copy Link' URLs on the Video Conferences
page. This prevents authentication failures when members open meetings
in a new browser tab after SvelteKit internal navigation has dropped
the bootstrap parameters.

Updated CLIENT__IDAA_and_customized_mods.md to document the requirement
for these keys in breakout URLs.
2026-05-23 11:31:10 -04:00
Scott Idem
194c89f6d1 style(launcher): layout and Tailwind class adjustments
+layout.svelte: add lg:min-h-8/12 and max-h-screen to main content area.
launcher_background_sync.svelte: reposition sync monitor panel (bottom-15,
left-2, z-10 — was bottom-20, left-4, z-9999).
launcher_menu.svelte: reorder Tailwind classes for readability, no change
to applied styles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:09:08 -04:00
Scott Idem
469729ce22 revert(help_tech): restore ae_loc preservation in Clear & Reload button
Reverts the change from d1f5d0e2f that removed ae_loc preservation.
The tech help component is used across non-Launcher contexts where
users are authenticated normally and should not be signed out.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:06:56 -04:00
Scott Idem
d1f5d0e2fd fix(launcher): clear ae_loc in cache cleanup; align tech help Clear & Reload
menu_launcher_controls: handle_cache_cleanup now removes both ae_events_loc
and ae_loc from localStorage, giving a true clean slate on reload.

e_app_help_tech: Clear & Reload button no longer silently re-saves ae_loc
after clearing — if edit mode wipes localStorage, ae_loc goes with it.
Updated confirm message and title tooltip to say "you will be signed out"
instead of the previous misleading "sign-in will be preserved."

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:05:16 -04:00
Scott Idem
9c83567430 feat(launcher): add Clear Cache and Reload Launcher buttons to controls bar
Fills in two new buttons added to menu_launcher_controls.svelte:
- Clear Cache: removes 'ae_events_loc' from localStorage and deletes the
  ae_events_db IndexedDB database, then reloads — clears stale launch state
  without touching downloaded file cache or user prefs (theme/font size).
- Reload Launcher: calls native.window_control({ action: 'reload' }) in
  Electron, falls back to window.location.reload() in browser mode.

Also fixes a stray 'lucide-svelte' import (merged Recycle into '@lucide/svelte')
and separates cache_status from reset_apps_status so button labels stay correct
when multiple actions fire.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:02:26 -04:00
Scott Idem
b4d0d82141 fix(launcher): fix VLC stopping 10-15 seconds after open on macOS
Root cause: run_cmd uses exec() which blocks until the child exits. The
direct VLC binary forks its GUI process and exits — exec returns and the
post_script begins. The old post_script polled for VLC focus (up to 10s)
then sent Cmd+F, which fired mid-playback and stopped the video.

Fix 1 — nohup + &: detaches VLC from exec immediately so run_cmd returns
in ~0ms. This decouples the launcher flow from VLC's lifecycle.

Fix 2 — --fullscreen flag: VLC opens fullscreen directly via CLI option.
Eliminates the Cmd+F keystroke that was the proximate cause of the stop.

Fix 3 — > /dev/null 2>&1: silences VLC's verbose logging to prevent
exec's 1MB stdout buffer from overflowing and killing the process.

post_script simplified to a single `tell application "VLC" activate`
to bring VLC to the foreground after the 3s startup delay.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:10:37 -04:00
Scott Idem
15bfe6d5d6 feat(launcher): move Reset Apps to always-visible controls bar
Adds a presenter-accessible "Reset Apps" button to menu_launcher_controls
that is always visible (no edit mode required). Kills presentation apps
(PowerPoint, Keynote, Acrobat, VLC, soffice) — critical recovery path for
presenters stuck on stage with a frozen app.

Also: warning colors on All Files / All Sessions when showing non-default
(hidden) content, and state-aware tooltips on the Display Mode toggle that
describe current state and what pressing will do.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:02:22 -04:00
Scott Idem
dddf4b6170 feat(launcher): restore Kill Apps button in Native OS config
Kills the standard conference presentation app set between sessions:
Microsoft PowerPoint, Keynote, Adobe Acrobat Reader DC, VLC, soffice.

- Calls native.kill_processes({ process_name_li }) via existing relay
- Process list overridable per device via event_device.other_json.launcher.kill_process_li
- Button lives in Native OS config > System Actions (edit mode only)
- Reuses system_status for feedback — shows which apps are being killed
- Original list recovered from git history of legacy architecture docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 16:43:42 -04:00
Scott Idem
587b815446 docs(todo): mark composable flow + slide scripts done; add event_file cfg_json backend task
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 15:58:38 -04:00
Scott Idem
ca51a82dae feat(launcher): richer tooltip on file download button
Tooltip now shows file size, created/updated timestamps, and open_in_os
setting alongside the existing SHA256 and hosted ID info.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 15:58:35 -04:00
Scott Idem
a38320c7f5 fix(launcher): monospace font for session list date/time column
Datetime values align cleanly across rows when rendered in font-mono.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 15:58:31 -04:00
Scott Idem
c76fb8f2b5 fix(launcher): open_in_os win routing, display override, and onsite ext fix
- open_in_os='win' now routes to Windows launch profiles (pptxwin/pptwin/odpwin/pdfwin)
  via WIN_EXTENSION_MAP in get_launch_profile() — was silently ignored before
- Display override migrated from non-existent cfg_json backend field to localStorage
  ($events_loc.launcher.file_display_overrides) — only visible in edit mode; TODO added
  for proper backend column when event_file gains cfg_json
- Onsite mode WIN extension rename now covers all 4 types (pptx, ppt, odp, pdf)
  instead of only pptx/ppt
- open_in_os button shows LoaderCircle spinner during API call
- Remove cfg_json from properties_to_save (column does not exist on event_file table)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 15:58:27 -04:00
Scott Idem
a26ea8b49c fix(launcher): optimistic update for display override button
Without this, the button depended on the liveQuery round-trip to show
the new state — invisible on stale IDB caches that predate the cfg_json
properties_to_save fix. Now mutates event_file_obj locally on click so
the button reflects the new state immediately, with the background
refresh as confirmation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 14:18:58 -04:00
Scott Idem
21fad1a698 fix(launcher): restore open_in_os win routing, fix cfg_json in IDB, fix display state
open_in_os = 'win': get_launch_profile() now maps pptx→pptxwin, ppt→pptwin,
odp→odpwin, pdf→pdfwin when open_in_os is 'win', routing to the Windows-variant
launch profiles (Parallels/CrossOver). Was never wired in native mode — feature
was silently lost in the MasterKey→Launcher port.

cfg_json missing from properties_to_save: the per-file display override was
always read as undefined from Dexie because cfg_json was never saved. Added
cfg_json to properties_to_save so display_override and any other cfg fields
persist correctly. NOTE: IDB_CONTENT_VERSIONS for event_file is not yet wired;
existing devices need a manual cache clear to pick up the new field.

Display override button: removed $ae_loc.is_native gate — must be configurable
from any device ahead of the event, not only on the podium Mac.

Display toggle persistence: quick_display_mode now reads from and writes to
$events_loc.launcher.display_mode so the last-set state survives page reloads
instead of always defaulting to 'extend'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 14:12:12 -04:00
Scott Idem
33e9eeef78 fix(launcher): retry activate in post-script loop to beat macOS focus-stealing
All app post-scripts called activate once before the poll loop, then only
checked `frontmost` passively. When Electron retains focus (common when the
app is spawned via run_cmd), macOS focus-stealing prevention blocks the one-
shot activate and VLC/PowerPoint/etc. never come to front. The poll loop
times out and fires the keystroke at Electron instead.

Fix: move activate inside the repeat loop so it re-fires every 0.5s until
macOS yields focus. Also bumped VLC post_delay_ms 1000→2000 and iterations
15→20 for slow conference machines.

Affected profiles: VLC (mac), PowerPoint (mac), LibreOffice (mac+win),
Acrobat (mac+win).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:51:53 -04:00
Scott Idem
172ea994c7 refactor(launcher): consolidate menu controls and anchor to bottom
- Combine Extend/Mirror into a single toggle button, moved behind edit_mode
- All edit-mode controls (All Files, All Sessions, Display) now share consistent preset-tonal-tertiary styling
- Remove the always-visible display row and its non-native-mode disclaimer
- Wrap Menu_launcher_controls in mt-auto to keep it pinned to the bottom of the sidebar regardless of session count
- Add min-w-20 to file size chip to prevent collapse on narrow sessions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:48:53 -04:00
Scott Idem
17b549a75c docs/refactor: finalize V3 cleanup and archive badge config project
- Moved PROJECT__AE_Events_Badges_Config_Cleanup.md to archive.
- Updated PROJECT__Use_AE_API_V3_CRUD_upgrade.md with latest audit and migration status.
- Migrated ae_comp__event_presenter_form_agree.svelte to modern V3 update_ae_obj helper.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 23:04:07 -04:00
Scott Idem
3de01af1a1 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>
2026-05-21 23:02:25 -04:00
Scott Idem
518a450b91 docs(events): reorganize badges and leads documentation
Standardized documentation structure for Badges and Leads modules into
focused technical references and practical onsite guides.

- Refined MODULE__AE_Events_Badges.md (Core data integrity & sync logic)
- Renamed MODULE__AE_Events_Exhibitor_Leads.md to MODULE__AE_Events_Leads.md
- Renamed MODULE__AE_Events_Badges_Onsite.md to GUIDE__AE_Events_Badges_Onsite.md
- Expanded GUIDE__AE_Events_Onsite_Runbook.md with Badge and Leads sections.
- Maintained all critical business logic, including the 'Override Fields' pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:40:06 -04:00
Scott Idem
cb767ed115 docs(events): reorganize presentation and launcher documentation
Split the monolithic MODULE__AE_Events_PressMgmt_Launcher.md into focused,
granular modules to improve maintainability and onsite utility.

- Created MODULE__AE_Events_Presentation_Management.md (Back-office focus)
- Created MODULE__AE_Events_Launcher.md (Podium display focus)
- Created GUIDE__AE_Events_Onsite_Runbook.md (SRR and onsite workflows)
- Promoted PROJECT__AE_Events_Launcher_Native_integration.md to
  MODULE__AE_Events_Launcher_Native.md (Permanent technical reference)
- Renamed 'Press Mgmt' references to 'Presentation Management' for clarity.
- Removed redundant README.md in launcher route.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:36:00 -04:00
Scott Idem
86201f0fc1 feat(launcher): implement force-sync and chronological download priority
Onsite operators can now manually trigger a full pre-sync of all location
materials via a "Force Sync Location" button in the Launcher config.
This ensures podium Macs have all content cached before an event starts.

- Added trigger__force_location_sync to launcher session store.
- Implemented force_location_sync() in background sync engine to perform
  recursive metadata fetches for all sessions in a location.
- Optimized download queue with a 4-tier chronological sort:
  1. Event/Location assets (Global)
  2. Sessions by start time (Earliest first)
  3. Presentations by start time (Sequential order)
  4. File creation date (First-in fairness for on-time uploads)
- Updated module and native integration documentation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:29:13 -04:00
Scott Idem
60e3fc539e docs(devops): add Nginx caching investigation task for app version pickup issue
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 18:31:51 -04:00
Scott Idem
b3029a4d27 docs: update TODO and add BOOTSTRAP mistake #13 for API retry regression
TODO__Agents.md:
- Added the two additional fixes from the review pass to the PATCH/DELETE
  retry hardening entry: default timeout 60s→20s, and DELETE missing
  ae_auth_error banner on 401/403.

BOOTSTRAP__AI_Agent_Quickstart.md:
- Added mistake #13: breaking the API retry loop by returning errors from
  the TypeError/AbortError block instead of throwing them. Documents the
  Jan 2026 regression (commit a10accfaa), the three retry classes that must
  be preserved, and a quick verification method.
- Filled the gap at item #7 (was missing, causing off-by-one numbering
  from item 8 onward). Items renumbered 8-14 → 7-13.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 18:21:01 -04:00
Scott Idem
ea765d8ad2 fix(api): lower patch/delete timeout to 20s and add delete auth error banner
Two gaps found during review of the recent retry-hardening commits:

1. api_patch_object.ts and api_delete_object.ts still defaulted to 60s
   timeout while GET/POST were lowered to 20s. No callers set an explicit
   timeout, so the default was the only value used. With retry_count=5 and
   the new backoff policy, 60s per attempt = 5+ minutes worst-case wait.
   Lowered to 20s to match GET/POST and keep worst-case under ~2 minutes.

2. api_delete_object.ts had no ae_auth_error import and no session-expired
   banner on 401/403. A stale-session DELETE would silently return false
   with no user feedback. Added browser + ae_auth_error imports and the
   ae_auth_error.set() call matching the pattern in GET/POST/PATCH.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 18:11:32 -04:00
Scott Idem
db5acdd30a docs: align API retry hardening status with implemented helpers 2026-05-21 18:04:06 -04:00
Scott Idem
a000e07647 api: harden delete retry classification and backoff 2026-05-21 17:58:59 -04:00
Scott Idem
7f9368589a api: harden patch retry classification and backoff 2026-05-21 17:53:30 -04:00
Scott Idem
55d3d49595 test: add v3 latency probe and modernize api coverage 2026-05-21 17:48:00 -04:00
Scott Idem
f5cf1ef398 api: separate timeout abort retries from intentional aborts 2026-05-21 15:46:30 -04:00
Scott Idem
d5d552a029 Badge layout fix for Axonius 2026-05-21 15:19:48 -04:00
Scott Idem
689bb326cb fix(api): restore network-error retry and add backoff in get/post_object
The Jan 2026 "offline-first fast-paths" commit (a10accfaa) inadvertently
broke retries for transient network failures (ERR_NETWORK_CHANGED, WiFi
roam events, etc.). The original code's .catch() returned undefined, which
fell through to the `if (!response) throw` path and correctly entered the
retry loop. After a10accfaa, .catch() returned the error as a value, and
the subsequent `instanceof Error` check returned false immediately —
bypassing all retries for the most common failure mode in
hotel/conference environments.

Changes:
- TypeError now throws into the retry loop instead of returning false
- AbortError still returns false immediately (intentional cancel, no retry)
- Per-attempt AbortController: moved inside the loop in both files so each
  retry gets its own independent timeout (previously GET retries had no
  timeout at all after the first attempt's clearTimeout ran)
- clearTimeout() added to catch block so timer is always cancelled on error
- Exponential backoff added: 2s→4s→6s→8s (capped) between attempts;
  rapid retries on a flaky network accomplish nothing without a delay
- Default timeout lowered: 90s → 20s (generous for search/GET but avoids
  the 90s worst-case hang that amplified ERR_NETWORK_CHANGED exposure)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 13:44:12 -04:00
Scott Idem
e6db2b4d6a fix(idaa): add Clear Cache & Reload escape hatch to recovery meetings server error state
"Try Again" resets auto_retry_count but reuses the same localStorage state — if
ae_loc or ae_idaa_loc holds a stale account_id or api_secret_key, every retry
fails identically and the user is stuck in an infinite error loop.

New button clears ae_loc + ae_idaa_loc from localStorage and db_events.event
from IDB, then reloads via the sessionStorage-preserved UUID URL (same logic as
the IDAA layout's Clear Cache & Reload). Forces a fresh FQDN handshake and
re-derives correct auth state. Guidance text shown so users know to try it when
Try Again keeps failing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 12:30:53 -04:00
Scott Idem
cfc5d237c7 docs(todo): add launcher wallpaper drift hotplug follow-up
Track projector/display unplug-replug wallpaper reset behavior and evaluate loop/check/event-driven strategies.
2026-05-20 19:30:37 -04:00
Scott Idem
a56f520d4e feat(launcher): add quick mirror/extend toggle in left menu
Always visible in launcher menu, disabled outside native mode, with title text and preview-note messaging.
2026-05-20 19:28:46 -04:00