Commit Graph

2563 Commits

Author SHA1 Message Date
Scott Idem
37c8e20302 fix(pres_mgmt): remove auth gate from presenter email access link button
A signed-in POC/chair/moderator who has session auth was blocked from
seeing the Email Access Link button because presenter_is_authed includes
auth__kv.session[session_id]. POCs need to help presenters sign in
regardless of their own auth state.

show__email_access_link (staff-only feature toggle) is the correct gate.
No auth gate needed — same pattern as the session POC email button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 14:56:55 -04:00
Scott Idem
6ab4166da0 fix(pres_mgmt): decouple email access link buttons from require_agree flags
Presenter email button: removed dependency on require__presenter_agree,
fixed auth gate that blocked trusted staff (presenter_is_authed includes
trusted_access, so !presenter_is_authed always hid the button from staff).
New condition: show when email feature is on AND person has email AND
(staff OR presenter not yet authed).

Session POC email button: removed dependency on require__session_agree.
Staff need to send sign-in links regardless of whether an agreement form
is in use. Added confirm dialog and descriptive title attribute. Updated
copy-link btn_title for consistency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 14:43:41 -04:00
Scott Idem
04ae723309 fix(pres_mgmt): restore Add Person and Save Biography on presenter page
Three regressions in presenter_view.svelte:

- update_ae_obj__event_presenter calls for "Add Person" and "Save
  Biography" were missing event_presentation_id. The function falls
  back to events_slct.event_presentation_id which is never set on
  this page, so both calls returned null silently.

- "Add Person" confirm dialog showed null for the presenter's name
  because it referenced person_given_name (the linked person's field,
  which is null when no person is linked) instead of given_name (the
  presenter's own field).

Also: Re-link person list limit raised to 1000 (matching session POC
pattern) and added WHY comment explaining the admin-only re-link
restriction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 14:09:10 -04:00
Scott Idem
b6d162c66e Minor style changes 2026-06-15 13:23:58 -04:00
Scott Idem
fa30acf31c Minor improvements for assigning a POC to a Session. 2026-06-15 12:57:41 -04:00
Scott Idem
03b3c84921 docs: archive Field Editor V3 project (complete), update Pres Mgmt status (~70% with regressions) 2026-06-12 17:54:38 -04:00
Scott Idem
e89c982022 docs: archive V3 CRUD upgrade project (100% complete) 2026-06-12 17:46:18 -04:00
Scott Idem
c6ef729c55 docs: audit and archive completed Journals and Badges projects 2026-06-12 17:35:02 -04:00
Scott Idem
fd7ccd7ecc docs: normalize Pres Mgmt cleanup formatting 2026-06-12 17:10:31 -04:00
Scott Idem
7831179970 docs: eighth-pass classify remaining active references 2026-06-12 17:07:57 -04:00
Scott Idem
75e7ca541a docs: seventh-pass archive unsafe legacy references 2026-06-12 17:07:03 -04:00
Scott Idem
e6fb4b289f docs: sixth-pass project routing and link validation 2026-06-12 17:05:13 -04:00
Scott Idem
1e3f541a39 docs: fifth-pass guide metadata and doc ownership cues 2026-06-12 16:58:23 -04:00
Scott Idem
e966261324 docs: fourth-pass metadata normalization and archive linking 2026-06-12 16:54:34 -04:00
Scott Idem
67d2607da1 docs: third-pass overlap consolidation and guide scoping 2026-06-12 16:53:35 -04:00
Scott Idem
7192cbc0af docs: second-pass archive and naming normalization 2026-06-12 16:50:56 -04:00
Scott Idem
a227c6aaa7 docs: restructure bootstrap, add module references, and normalize docs 2026-06-12 16:48:35 -04:00
Scott Idem
e05602b87b fix(pres_mgmt): restore POC + Presenter sign-in email and copy link flows
POC (session) sign-in was silently broken:
- sign_in_out.svelte calls session_sign_in() only when session_id is a query
  param; the URL was missing &session_id=... so the function never fired.
- Fixed in: email_sign_in__event_session URL and poc_sign_in_url derivation
  in session_view.svelte.

Presenter email routed to wrong page:
- email_sign_in__event_presenter built a URL to /presenter/[id] which has no
  sign-in handler. Changed to route to /session/[session_id] (same as the
  existing copy-link on the presenter page), including presenter_id and
  presentation_id params so presenter_sign_in() fires correctly.

Multi-session/multi-presentation person-centric auth:
- poc_is_authed in session_view.svelte now also checks
  auth__person.id === poc_person_id, so a POC signed in via any of their
  session links is automatically auth'd on all sessions where they are the POC.
- presenter_is_authed derived bool added to presenter page; includes person_id
  match so a presenter is recognised on all their presentations after one
  sign-in. All file upload and file list auth gates now use it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 16:27:45 -04:00
Scott Idem
10f7f04fbc docs: fix bootstrap — remove JWT Bearer claim; add mistakes 16-17; add pres_mgmt reading entry
- Auth row in stack table wrongly said "JWT Bearer is auto-injected" — this project
  uses custom headers only (x-aether-api-key + x-account-id, NOT Bearer tokens)
- Mistake #16: $ sigil on plain prop value → store_invalid_shape at runtime
- Mistake #17: *_json / *_kv_json columns start as null — require ?. and ?? {} guards
- Renumbered old #16 (service worker) to #18
- Reading order: added Pres Mgmt module doc pointer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 16:19:52 -04:00
Scott Idem
94bdeb9a26 fix(pres_mgmt): guard poc_kv_json null access in POC profile and agree modals
poc_kv_json is null when a session has never had POC data saved. Any bracket
access on it crashed immediately on modal open. Fix:
- Reads: use ?.[poc_type] optional chaining everywhere (checkboxes, biography_updated_on)
- Writes: initialize from a shallow copy of poc_kv_json ?? {} before indexing into it,
  so the first save on a fresh session creates the structure rather than throwing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 15:55:25 -04:00
Scott Idem
080ad06a45 fix(pres_mgmt): stop treating lq__event_session_obj prop as a Svelte store in POC modals
Both ae_comp__event_session_poc_profile and ae_comp__event_session_poc_form_agree used
$lq__event_session_obj with the $ sigil throughout, expecting a store subscription. They
receive a plain resolved value from session_view.svelte, so Svelte threw store_invalid_shape
on mount. Replace all $lq__event_session_obj → lq__event_session_obj in both files.

Also clean up poc_profile: remove event_session_id_random (legacy alias) → event_session_id
in the auth check and the biography save call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 15:53:13 -04:00
Scott Idem
45f8bb5e58 fix(pres_mgmt): restore session view — name always visible, POC in hero card, email/copy links
- session_view.svelte: session name/code were only rendered in edit_mode — non-editors
  saw a blank card. Now always visible; edit_mode just wraps them in field editors.
- Restructured hero card as a <ul> with datetime, room, and POC as rows inside the card.
  POC no longer floats below as a disconnected block.
- Dynamic POC label (label__session_poc_name) used throughout: row label, modal titles,
  fallback text, and editor label — no more hardcoded "Host:".
- POC "Select Person" flow: gate select editor on person_options_loaded to prevent empty
  dropdown on open; button reads "Reload Person" after list is loaded.
- Restored email sign-in link button in POC row with idle/sending/sent/error feedback.
  Shown when require__session_agree && show__email_access_link && poc_person_primary_email.
- Restored inline copy-access-link for trusted staff (show__copy_access_link).
- session_page_menu.svelte: fix event_session_id prop — was passing event_id instead of
  event_session_id, breaking the Sign_in_out auth grant.
- ae_comp__event_session_poc_profile.svelte: migrate run() to $effect, fix poc_person_id_random
  → poc_person_id, fix events_slct reference in copy link URL.
- +page.svelte: add pres_mgmt config sync so session pages opened directly by URL get
  correct hide__session_poc and other remote config values.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 15:15:58 -04:00
Scott Idem
3085d1dc63 docs: update IDAA idaa_loc migration project doc
Rewrote PROJECT__IDAA_Stores_Svelte5_Migration_2026.md with complete
detail: full 29-file consumer inventory with hit counts per module,
exact files that only reference the localStorage key string (no changes
needed), store_versions.ts wipe note, explicit Phase 1 ordering, test
seed guidance, and updated Risk Register including R3 nested-object
merge gap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 17:33:58 -04:00
Scott Idem
7fc073053b feat(idaa): add PersistedState store for idaa_loc (not yet wired in)
Creates ae_idaa_stores__idaa_loc.svelte.ts — the Svelte 5 PersistedState
replacement for the idaa_loc persisted() store in ae_idaa_stores.ts.

Mirrors the exact shape of idaa_local_data_struct with full TypeScript
interfaces (IdaaArchivesLoc, IdaaBbLoc, IdaaRecoveryMeetingsLoc,
IdaaLocState). Drops __version, name, and title (not runtime state).

Same localStorage key (ae_idaa_loc) — existing data loads cleanly.
Not wired into consumers yet; pending review before migration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 17:22:54 -04:00
Scott Idem
582b43da34 fix(types): add file_display_overrides + launch_profiles to LauncherLocState
Both fields were being written to launcher_loc.current dynamically and
read back via 'as Record<string, unknown>' casts because they were absent
from the LauncherLocState interface and launcher_loc_defaults.

file_display_overrides: Record<string, 'extend' | 'mirror' | 'none'>
  — per-device display override map keyed by event_file_id.
  — local-only workaround until event_file.cfg_json is added on backend.
  — TODO comment preserved; migrate once the backend column exists.

launch_profiles: Record<string, Partial<LaunchProfile>> | null
  — local per-device launch profile overrides (device API config takes
    priority; these override the built-in DEFAULT_LAUNCH_PROFILES).

Defaults added to launcher_loc_defaults ({} and null respectively).
All 3 type casts in launcher_file_cont.svelte removed.
2026-06-11 17:17:29 -04:00
Scott Idem
98e31f1528 docs: update docs to reflect events store migration completion
BOOTSTRAP__AI_Agent_Quickstart.md: rewrite store reactivity trap section
to distinguish events sub-stores (PersistedState, fine-grained) from
ae_loc/idaa_loc (svelte-persisted-store, coarse). Add import/read/write
syntax examples and pointer to migration doc.

PROJECT__Stores_Svelte5_Migration.md: rewritten to reflect events module
fully complete; documents established PersistedState pattern with canonical
examples; tables show all 5 sub-stores done + events_loc retired.

TODO__Agents.md: events migration marked complete (2026-06-11); idaa_loc
and ae_loc listed as remaining work; stale events_loc file_display_overrides
ref fixed.

tests/README.md: replace Leads-only store migration note with full events
sub-store table, localStorage keys, and explanation of PersistedState
deserialization (no __version guard needed).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 16:50:06 -04:00
Scott Idem
573d20e574 feat(stores): retire events_loc — Svelte 4 persisted store fully replaced
events_loc has been completely removed after migrating all consumers:

- EVENTS_MODULE_TITLE constant replaces $events_loc.title (was always
  the static default 'OSIT\'s Æ Events', never written dynamically)
- events/+layout.svelte: qry__* writes moved to events_sess; stale-deploy
  ver check block removed (store_versions.ts handles this already)
- 3 stale pres_mgmt stragglers fixed: device_obj_li, location_page_menu,
  event_reports_page_menu now use pres_mgmt_loc.current directly
- testing/+page.svelte: missed launcher ref fixed (launcher_loc.current)
- events_loc export, events_local_data_struct, persisted import, and
  AE_EVENTS_LOC_VERSION import all removed from ae_events_stores.ts
- events_loc import cleaned from all consumer files

events_sess (in-memory writable) stays in ae_events_stores.ts unchanged.
store_versions.ts keeps its _check_and_wipe('ae_events_loc') entry to
clean lingering old data from users' browsers.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 16:41:06 -04:00
Scott Idem
83c9b9fd4f feat(stores): promote events auth state to Svelte 5 PersistedState
Creates ae_events_stores__auth.svelte.ts with PersistedState keyed
'ae_events_auth_loc' for auth__person and auth__kv (presenter/session
sign-in state). Migrated 10 component files from $events_loc.auth__* to
events_auth_loc.current.auth__*.

Also fixed stale pres_mgmt stragglers: $events_loc.pres_mgmt.* refs in
presenter_obj_li.svelte, presenter_page_menu.svelte, and [presenter_id]/
+page.svelte now use pres_mgmt_loc.current.* directly.

show_details boolean moved from events_loc to leads_loc (it belongs in
the leads module — one bind in ae_tab__manage.svelte).

auth__person, auth__kv, show_details, events_cfg_json, event_id removed
from events_local_data_struct. events_loc now only carries ver, title,
and qry__* prefs.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 16:19:49 -04:00
Scott Idem
27c775d816 feat(stores): promote launcher_loc to Svelte 5 PersistedState
Creates ae_events_stores__launcher.svelte.ts with PersistedState keyed
'ae_launcher_loc', following the same pattern as badges, leads, and
pres_mgmt. All 28 launcher component files migrated from
$events_loc.launcher.* to launcher_loc.current.*.

events_local_data_struct in ae_events_stores.ts now carries no sub-module
objects — all four sub-modules (badges, launcher, leads, pres_mgmt) are
authoritative in their own stores. Session state (events_sess.launcher)
is unchanged.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 16:00:40 -04:00
Scott Idem
5823f18161 chore(stores): remove migrated sub-objects from events_loc persisted struct
badges, leads, and pres_mgmt have each been promoted to their own
PersistedState stores (ae_badges_loc, ae_leads_loc, ae_pres_mgmt_loc).
Remove them from events_local_data_struct and drop the now-unused
*_loc_defaults imports so events_loc only carries what it owns.

launcher stays — not yet migrated (244 active refs).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 15:41:54 -04:00
Scott Idem
94e4fad061 chore(stores): remove unused default properties from ae_loc, ae_sess, events_slct, idaa_loc
Audited all three legacy persisted-store files for properties with zero
references in src/. Removed ~119 lines of dead defaults:

- ae_loc: qr_scanner_version, ds, entire mod block (archives/events/journals/posts/sponsorships)
- ae_sess: hub, mod block (archives/events/journals/posts/sponsorships/testing), download
- events_loc: ds
- events_sess: ds_loaded
- events_slct: abstract_*, badge_template_*, device_*, exhibit_tracking_*, lq__presenter_obj
- idaa_loc: ds, idaa_cfg_json, top-level qry__* (each submodule has its own), novi_rate_limited_until, novi_*_base_url (read from site_cfg_json, not idaa_loc)

No version bumps needed — removing fields from defaults is backwards-compatible.
svelte-check passes: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 15:29:48 -04:00
Scott Idem
9a1ba02b59 Can not use these links within an iframe... 2026-06-11 15:08:50 -04:00
Scott Idem
05841350fe feat(idaa): add /idaa/clear-caches page for Novi iframe cache reset
Clears all IDB databases, localStorage, and sessionStorage for the
prod-idaa.oneskyit.com origin when loaded as an iframe inside www.idaa.org.
Targets the partitioned storage bucket used by IDAA Novi iframes — direct
navigation to the site clears a different partition and has no effect.

Uses Novi-safe styling (explicit bg/text surfaces, no bare h1 elements,
inline styles on links) to survive Bootstrap v3 CSS injected by Novi.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 13:01:34 -04:00
Scott Idem
a5beff4aa8 feat(reports): add created_on timestamps and detail links to file downloads report
Show upload timestamp for every file; bold the newest upload per session/presenter
group so staff can quickly identify the most recent version. Add Session/Presenter
navigation links in each card header for direct access without searching.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 04:23:07 -04:00
Scott Idem
246d4f8ef3 fix(pres_mgmt): show session/presenter counts in File Downloads header
The summary was showing file counts by type (session-level files vs
presenter-level files), which made the session count look wrong (e.g.
6 when there are 40 sessions). Now shows unique session and presenter
counts from the grouped data, matching what the label implies.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 17:30:19 -04:00
Scott Idem
666b54bd36 fix(badges): add missing updated_on column to CSV export
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 16:36:25 -04:00
Scott Idem
89c1decf8d feat(badges): add CSV export to badge reports
Adds an "Export CSV" report to the badge reports page. Generates
a clean CSV client-side from Dexie cache — no backend call needed.

- 3 filter presets: Printed+Clean (default), Printed all, All badges
- Printed+Clean mirrors the manually-cleaned Axonius export (printed,
  non-hidden, non-test badge type)
- Timezone selector: Eastern (default), Local, UTC — addresses the
  UTC→Eastern conversion needed for post-event client exports
- 24 columns: identity fields, override pairs, print status, created_on
- UTF-8 BOM for direct Excel open without import wizard
- Auto-generated filename from event name + date + filter suffix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 16:00:18 -04:00
Scott Idem
b9d70b616f feat(reports): add two new filename format options to file downloads report
Adds 'Session Code + Date + Time + Name' and 'Session Code + Date +
Session Time + Presentation Time + Presenter Full Name' format presets.
The second format uses presentation start datetime for the pres_time
part and event_presenter_full_name for the full presenter name part.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 15:18:39 -04:00
Scott Idem
e8a49562a9 feat(pres_mgmt): prefix/suffix inputs, flex row layout, strip :443 from links
File Downloads report: add Prefix and Suffix inputs for filename customization
(e.g. "2026_06__"), longest-filename length indicator with warning above 120
chars, and switch file rows from table to flex layout so Download/Copy Link
buttons stay right-aligned regardless of filename length.

Strip redundant :443 from https download URLs in both the file downloads report
and the manage event file list clipboard links.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 15:15:16 -04:00
Scott Idem
e909c34874 Updated documentation. 2026-06-10 14:55:10 -04:00
Scott Idem
48bc52899f fix(pres_mgmt): switch direct download links to event_file endpoint
event_file ?key= auth fix is now deployed. Retire the hosted_file workaround
and use /v3/action/event_file/{event_file_id}/download?key=... as the canonical
form across the file downloads report, manage file list, and download button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 14:41:53 -04:00
Scott Idem
6b122a065e feat(pres_mgmt): File Downloads report with clean filename presets
New report at Pres Mgmt > Reports > File Downloads. Groups all event files
by session and presenter, with 10 filename format presets (original, session
code/date/name combos, presenter variants). Per-file Download button and Copy
Link button using hosted_file endpoint for ?key= auth support.

Also fixes direct download links in element_manage_event_file_li and the
hosted_files download button — event_file endpoint does not yet propagate
?key= auth internally, so all direct links now use hosted_file endpoint
which supports it today.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 14:19:25 -04:00
Scott Idem
1b81b8873c refactor(badges): move reports IDB prefetch to +page.ts load function
Replace the $effect-based background fetch with the canonical
if(browser) fire-and-forget pattern in +page.ts. Runs earlier
in the lifecycle, no store subscription overhead, and immune to
$ae_api store re-trigger side effects. Removes ae_api and
events_func imports from the component.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 12:36:31 -04:00
Scott Idem
4f74cf1353 fix(badges): reports background fetch guard used wrong field name
$ae_api.api_key does not exist — the field is api_secret_key.
The guard evaluated to true on every render, returning immediately
and never calling search__event_badge. Changed to base_url which
is the standard readiness check per the quickstart doc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 12:32:49 -04:00
Scott Idem
6dc6be9926 fix(badges): reports background fetch was not writing to IDB
try_cache=false skips db_save_ae_obj_li__ae_obj, so the API fetch
completed but liveQuery never saw the data. Removing the override
lets it default to true so results are persisted to IDB as expected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 12:27:57 -04:00
Scott Idem
97c4c1cd6b fix(badges): Remote First uncheck stuck visually checked
e.preventDefault() was called for both enable and disable clicks.
On disable, it reverted the DOM back to checked before Svelte could
sync the store update, leaving it visually stuck. Only prevent default
when enabling (to hold the unchecked state during confirmation).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 12:15:39 -04:00
Scott Idem
b6481a3507 feat(badges): Remote First confirmation warning + title tooltips
Enabling Remote First now shows an inline warning explaining that it
bypasses the local cache and queries the server on every keystroke.
User must confirm before it activates; Cancel leaves the checkbox off.
Disabling still takes effect immediately. Label and checkbox also get
title tooltips. Active state gets a warning tonal highlight.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 12:12:28 -04:00
Scott Idem
7b45b548e4 fix(badges): reports page fetches all badges on load instead of IDB-only
Reports were IDB-read-only — no data appeared until the badge search page
had already populated the cache. Added a background search__event_badge
call (limit 5000, try_cache=false) so navigating directly to /reports
always gets a fresh full dataset; liveQuery updates reactively.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 12:06:13 -04:00
Scott Idem
a1057fd776 fix(badges): throughput — weekday-first date header, keyed each block
Separators now read "Tuesday · June 9 — EDT" so day-of-week is the
lead identifier, matching how conference staff refer to the schedule.
Added key (sz) to the window-size each block.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 11:28:48 -04:00
Scott Idem
d0286f7868 feat(badges): show full date + browser timezone in throughput separators
Date separators now display "Monday, June 9 — EDT" instead of "Jun 9",
using the browser's local timezone abbreviation resolved at page load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 11:24:25 -04:00