Commit Graph

2367 Commits

Author SHA1 Message Date
Scott Idem
64b4bce185 fix(pres_mgmt): obscure email in POC + presenter email confirm dialogs
Non-trusted users see joh***@example.com in the confirm() prompt and
button title instead of the full address. Trusted staff see the full
email unchanged. Matches the obscure_email() pattern already used in
ae_comp__badge_obj_li.svelte.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 13:45:10 -04:00
Scott Idem
86845829dc Bug fix for permission to see out of sync affiliations field. 2026-06-24 13:29:31 -04:00
Scott Idem
4139e281ee Lots of little changes to make things better for the end users. Staff, members, presenters, etc. 2026-06-24 13:23:33 -04:00
Scott Idem
5bf9a72fcd feat(sys-bar): full reset button for anonymous users in panel header
Anonymous users (potentially stuck on stale JS) now see a Full Reset
button in the panel header instead of Clear IDB — matching the same
compact icon+reveal-label pattern as the authenticated Clear IDB button,
but error-styled and wired to handle_clear_storage_and_idb.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 13:04:53 -04:00
Scott Idem
ad8eef0cec refactor(fix-sw): single RELOAD_DELAY_S constant, set to 11s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 12:59:31 -04:00
Scott Idem
6449d27696 feat(fix-sw): add countdown timer and icon to Reload Now button
Button now shows a live countdown (7→0s) so users can see exactly when
the auto-reload will fire, with a RefreshCw icon per button UX standard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 12:53:39 -04:00
Scott Idem
826e448af7 fix(fix-sw): show origin and clarify reset only affects this domain
Displays the actual origin (e.g. https://idaa.org) and adds explicit
copy stating this does not affect other sites, browser history,
passwords, or settings — so users don't panic thinking their entire
browser is being wiped.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 12:46:10 -04:00
Scott Idem
a10b4d18bb fix(sys-bar+fix-sw): accurate button labels and full storage reset
- sys bar: fix wrong title on Full Reset button (was "Clear IDB only",
  now accurately describes SW + Cache + IDB + localStorage + sessionStorage)
- sys bar: rename "Reload Page" → "Clear IDB & Reload" and wire it to
  handle_clear_idb_only instead of a bare window.location.reload()
- testing/fix-sw: expand from SW+Cache only to full storage nuke —
  adds IDB (via indexedDB.databases() with known-names fallback),
  localStorage, sessionStorage; auto-reloads to / after 3s; shows
  per-step status log with success/warn/error colour coding

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 12:44:02 -04:00
Scott Idem
dda7a91f9f fix(sw): postMessage all open tabs on activate to break stale-JS loop
After clients.claim(), the new SW sends SW_ACTIVATE_RELOAD to every open
window tab. +layout.svelte now listens for this alongside the existing
controllerchange listener. The had_controller guard prevents a spurious
reload on fresh page loads where no SW was controlling the tab.

WHY: controllerchange only fires in JS that already has the listener
(added 2026-06-22). Tabs stuck on builds from before that date (e.g.
October 2025 users) never registered it, so the SW update under them
was silent. The postMessage path reaches those tabs directly. Users who
are already on new JS get the reload from controllerchange; users on old
JS get it from the message event once they receive this new SW.

Note: October 2025 users still need a manual Full Reset on their first
visit after this deploy (old JS has no message listener). After that one
reset they are permanently self-healing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 12:21:21 -04:00
Scott Idem
37065b5a7c fix(pres_mgmt): remove passcode guard from POC email sign-in link
Newly imported POC persons may not have a passcode set yet. The previous
guard caused send_poc_email_link() to silently exit for these persons,
making the email button appear to do nothing. Only poc_person_primary_email
is required to send the email; passcode falls back to '' matching the
presenter email button pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 12:18:10 -04:00
Scott Idem
dcc0f9a05b feat(files): multi-select delete + quick-delete toggle on /core/files/
Adds checkbox column with select-all header, a selection action bar showing
count and "Delete X selected" (one confirm for the whole batch, sequential
delete with progress tracking), and a "Quick delete" checkbox that suppresses
the per-file confirm dialog for single-file deletes. Selection clears on
each new search. Designed for rapid orphan cleanup after Check Orphans.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 20:17:29 -04:00
Scott Idem
c18b32c2d6 chore(api): remove legacy CRUD wrappers and dead commented code
Deleted `delete_ae_obj_id_crud` from api.ts (last legacy export, no callers)
and purged ~200 lines of commented-out dead functions from ae_core_functions.ts
(`load_ae_obj_id__site_domain`, `update_ae_obj_id_crud`, `update_ae_obj_id_crud_v2`).
V3 CRUD migration is now 100% complete with no legacy remnants. TODO updated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 19:14:21 -04:00
Scott Idem
00364b00d2 More style clean up 2026-06-23 19:08:02 -04:00
Scott Idem
9421308cb4 Manually adjusting more of the styles with trial and error. 2026-06-23 18:21:22 -04:00
Scott Idem
7c129d3237 polish(pres_mgmt): dark-mode token cleanup on agree/consent forms + style guide update
Replace all forbidden hardcoded colors (red/green bg, text-red-*, text-green-*)
with Skeleton semantic tokens (error/success) so forms render correctly in dark mode.
Update agreement text wrapper from bg-white/dark:bg-gray-900 to bg-surface-50-950.
Document Flowbite Svelte Modal standard pattern (incl. note that classes.footer
padding override does not work in current version).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 17:56:29 -04:00
Scott Idem
7e255a7845 polish(pres_mgmt): consistent agree/consent modals + contrast + layout fixes
- Standardize all 3 consent modals (presenter × 2, session POC): same
  placement="top-center" size="lg", no custom height hacks, let Flowbite's
  native <dialog> handle scrolling; consistent footer Close button with X icon
- Modal titles now include person name; removes the double-header (inner <h2>
  in both form components was redundant with the modal title)
- Agreement text wrapper: bg-surface-100-900 → prose dark:prose-invert +
  bg-white dark:bg-gray-900 for proper dark-mode contrast on CMS HTML content
- Section/header bar changes color green when agreed (red when not), with
  check icon; "Change to not agreed?" button style aligned between both forms
- Remove pb-16 from pres_mgmt layout (leftover from defunct sticky action bar)
- Add @source for flowbite-svelte/dist so backdrop:bg-gray-900/50 is generated
  (modal backdrop dim was never active before — Tailwind wasn't scanning it)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 16:47:46 -04:00
Scott Idem
536b445950 fix(pres_mgmt): agree check and sign-in URL for multi-session presenters
Two fixes for presenters who have records in multiple sessions:

1. presenter_agree_ok now uses lq__event_presenter_obj.agree (the
   current page's record) instead of lq__auth__event_presenter_obj.agree
   (the sign-in record). Previously, agreeing on Presenter B while signed
   in via Presenter A's link had no effect on B's upload gate.

2. presenter_sign_in_url derived conditionally omits person_id for
   email-only presenters — URL builder moved from inline template
   to a $derived so the condition is readable.

Removes unused lq__auth__event_presenter_obj liveQuery from presenter page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 15:37:16 -04:00
Scott Idem
c2e42e1c0a refactor(pres_mgmt): make person_id optional in presenter sign-in URLs
Email-only presenters (no Person record) no longer have person_id in
their sign-in URLs — sign_in_out falls back to presenter_id and
expand_auth_for_person resolves identity via Dexie lookup.
Person-linked presenters still include person_id as before.

Removes the confusing case where person_id == event_presenter_id in
URLs for email-only presenters.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 15:37:09 -04:00
Scott Idem
85870b67f5 fix(pres_mgmt): remove email from presenter sign-in URLs
Previously, presenters without a Person record had their email address used
as the person_id fallback in Copy Link and emailed sign-in URLs. This exposed
the email in browser history, server logs, and to anyone the link was shared
with.

Replaced .email fallback with .event_presenter_id in all three URL-building
locations:
- Copy Link clipboard value (presenter detail page)
- Email sign-in button person_id (presenter detail page)
- Email sign-in button person_id (presenter list component)

The sign-in handler's presenter_id_hint mechanism looks up the email from
Dexie using the event_presenter_id already in the URL, so cross-session auth
still works without the email being in the URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 14:54:24 -04:00
Scott Idem
5d6008431c fix(pres_mgmt): encodeURIComponent for poc_sign_in_url + null-key guard
- poc_sign_in_url derived: replace encodeURI() with per-param
  encodeURIComponent() — same fix applied to presenter URLs. passcodes
  may contain special characters; encodeURI() would leave them unencoded.
- session_sign_in(): guard the presentation_id and presenter_id auth__kv
  writes so they only run when non-null. A pure POC link has neither param
  in the URL, so writing auth__kv[null] was creating junk 'null' string
  keys that never matched anything.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 14:48:25 -04:00
Scott Idem
6d5c87bad0 fix(pres_mgmt): cross-session presenter auth, URL encoding, sign-in gate
- expand_auth_for_person: added presenter_id_hint param to look up the
  signing presenter's email from Dexie, enabling cross-session auth even
  when person_id in the URL is a string ID (not an email address)
- presenter_is_authed: added auth__kv.presenter[email] check so a
  presenter signed in on one session auto-unlocks matching records across
  all sessions for the same event
- URL construction: replaced encodeURI() with per-param encodeURIComponent()
  in email_sign_in__event_presenter, email_sign_in__event_session, and the
  Copy Link button — encodeURI() silently passes '+' unencoded, causing
  URLSearchParams.get() to decode it as a space and break '+' email aliases
- Sign-in gate: changed from `if (url_person_pass)` to presence of
  url_person_id + presenter_id/session_id so sign-in works when passcode
  is empty/null (common for presenter records without a passcode configured)
- Fixed param?: Type syntax in sign_in_out.svelte (presenter_id_hint) —
  Vite's type-stripping leaves the ? marker producing invalid JS on HMR

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 14:39:40 -04:00
Scott Idem
219f0a6507 Bug fix for when a POC is signed in. Also adjusted style to make the button more obvious. 2026-06-23 13:27:17 -04:00
Scott Idem
7ccc199b1d refactor(src): normalize component naming conventions (Group 2 cleanup)
pres_mgmt route: 8 co-located component files had no prefix, inconsistent
with every other module in the codebase. Renamed to ae_comp__* convention:
  event_page_menu, locations_page_menu, location_page_menu, location_view,
  presenter_page_menu, presenter_view, session_page_menu, session_view.
  Each had exactly one importer — import paths updated.

leads route: ae_tab__ prefix was unique to this module. The 3 active tab
files renamed to ae_comp__tab_* (ae_comp__tab_add, ae_comp__tab_start,
ae_comp__tab_manage). Three unused files (ae_tab__add_search_scan,
ae_tab__lead_list, ae_tab__list) had zero importers and were removed.

PascalCase import bindings (AE_Record_Controls, AE_AITools, AE_Object_Flags)
left unchanged — Svelte requires capitalized component names in templates;
this is a style-only concern and not worth touching without a broader
component naming convention decision.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:49:08 -04:00
Scott Idem
b1c2438867 refactor(src): root-level clutter cleanup (Group 4)
- Move 10 theme CSS files from src/ root to src/styles/ — update app.css
  @import paths from ./ae-*.css to ./styles/ae-*.css. Keeps src/ root tidy
  without changing how the themes are bundled.
- Trash aeclci_v1.css — not imported anywhere, dead file.
- Move pwa_install.svelte.ts from lib/pwa/ (single-file dir) into lib/elements/
  alongside element_pwa_install_prompt.svelte; update 2 imports.
- Move src/types/temporary-svelte-augments.d.ts into src/lib/types/ (canonical
  type location); trash empty src/types/ dir.
- idaa/clear-caches/ route slug NOT renamed — URL is embedded in Novi portal
  iframe config; requires coordinated portal update outside this repo.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:39:17 -04:00
Scott Idem
7fa9e107b8 refactor(src): resolve orphaned/misplaced files (Group 3 cleanup)
Five Svelte components removed from ae_core/ (data/logic lib dir) and moved
to elements/ where reusable UI components live:
  ae_comp__hosted_files_download_button, ae_comp__hosted_files_upload,
  ae_comp__hosted_files_clip_video, ae_comp__hosted_files_clip_video_li,
  ae_comp__site_config_editor — all import paths updated.

ae_core__organization.ts deleted — zero importers, dead code.

ae_events/types/ae_badge_template_cfg.ts promoted to ae_events root and
renamed ae_events__badge_template_cfg.ts (follows module naming convention);
types/ subdir removed.

ae_events/badges/css/ badge layout CSS files moved to elements/styles/
(the dedicated styles dir); badges/ subdir removed.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:33:58 -04:00
Scott Idem
4d6dd980c2 refactor(src): consolidate duplicate lib directories (Group 1 cleanup)
Three pairs of duplicate/split directories collapsed into their canonical homes:

- src/lib/api/ → src/lib/ae_api/: api.ts moved alongside the individual
  api_*.ts files it aggregates; all 85 import lines updated across the codebase.

- src/lib/utils/ → src/lib/ae_utils/: ae_string_snippets.ts and utils.ts
  moved; one import updated (ae_stores.ts). utils.ts had no importers.

- src/lib/ae_elements/ → src/lib/elements/: AE_AITools, AE_Object_Flags,
  AE_Record_Controls moved and renamed to snake_case (ae_ai_tools.svelte,
  ae_object_flags.svelte, ae_record_controls.svelte); 6 import paths updated.
  Local binding names left unchanged for a separate Group 2 pass.

svelte-check: 0 errors, 0 warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:22:10 -04:00
Scott Idem
3f73fc059e fix(sw): guard navigator.serviceWorker access before feature check; fix EOF newline
Accessing navigator.serviceWorker.controller before the 'serviceWorker' in navigator
guard would throw a TypeError on browsers without SW support. Moved the guard into
the had_controller expression so the property is never accessed on unsupported browsers.

Also adds the missing trailing newline to core__export.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:09:21 -04:00
Scott Idem
3bc93857dd fix(build): replace optional TypeScript params to fix SSR build
esbuild strips ': Type' from 'param?: Type' but leaves 'param?' in the
output, which is invalid JavaScript and causes Rollup to fail during the
Vite SSR build. Changed all 5 occurrences across source files from
'param?: Type' to 'param: Type | undefined = undefined', preserving the
same optional semantics while producing valid JavaScript after stripping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:56:51 -04:00
Scott Idem
cf9975f50f fix(sw): skip controllerchange reload on first activation
The reload should only fire when an existing SW is replaced by a new one
(old → new), not when the SW activates for the first time on a fresh page
load (null → first). The spurious reload on fresh loads was caused by
checking unconditionally.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 15:26:48 -04:00
Scott Idem
677ec9d918 feat(build): inject build time and version into health endpoint
Vite define injects __BUILD_TIME__ and __BUILD_VERSION__ at build time
so /health returns the exact timestamp and package version of the running
build — useful for verifying deploys without guessing what changed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 15:13:04 -04:00
Scott Idem
39f2e6ccfa refactor(core): fix svelte-check errors and clean up ae_core_functions
- Fix two broken V1/V2 api calls (get_ae_obj_id_crud, update_ae_obj_id_crud)
  that no longer exist on the api object — replaced with V3 equivalents
- Comment out two dead/uncalled functions (load_ae_obj_id__site_domain,
  update_ae_obj_id_crud) and remove them from the export; pending full removal
- Extract download_export__obj_type into core__export.ts following the
  core__*.ts module convention

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 12:33:14 -04:00
Scott Idem
81874ffa5d fix(sw): complete cache-clearing + add controllerchange auto-reload
All cache-clearing buttons and the IDAA clear-caches page previously
cleared IDB/localStorage but left service worker registrations and Cache
Storage intact. On the next reload the SW re-served the old JS bundle,
leaving users stuck on stale code despite appearing to reload. This
caused recurring stale-state reports from IDAA and other clients for
4+ months.

Two gaps closed:
1. Every clear path (root page buttons, sys bar, help tech, idaa/clear-caches)
   now unregisters SW registrations and clears Cache Storage before touching
   IDB and localStorage. Order: SW → Cache Storage → IDB → localStorage.
2. Added controllerchange listener in +layout.svelte effect 4. When the new
   SW activates and calls clients.claim(), this listener reloads the page so
   open tabs run the new JS bundle instead of keeping old code in memory
   indefinitely. Without this, skipWaiting + clients.claim work correctly on
   the SW side but the page side never picks up the update.

Also added thorough code comments and updated REFERENCE__Common_Agent_Mistakes
(#15) and BOOTSTRAP doc (#8) to document the full root cause so this cannot
be silently re-broken by a future agent or refactor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 12:17:51 -04:00
Scott Idem
66c794ee53 fix(core): align menu + dashboard colors and order
Menu: Files moved between People and Data Stores; color tertiary (matches Users/People).
Dashboard: Sites secondary→primary, Files secondary→tertiary, Data Stores + Lookups surface→secondary. All cards now match menu color groupings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 19:19:39 -04:00
Scott Idem
dae610795b feat(core): add Files card to dashboard, fix card colors, expand per-page options
Dashboard: Users + People cards corrected to tertiary (matched menu);
Files card added between People and Data Stores using secondary (matched menu).
Files per-page options extended to 200/400/800/1000/1500/2000.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 19:16:14 -04:00
Scott Idem
af636f5b53 fix(files): total size reflects displayed rows, not all loaded results
When orphan filter is active, total was summing all 50 loaded files
rather than the filtered subset shown in the table.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 18:56:24 -04:00
Scott Idem
5689bfebbc fix(files): use new backend action endpoints for event_file delete + orphan scan
DELETE /v3/action/event_file/{id} now handles full atomic cleanup (link
removal, physical file, hosted_file record) in one call — replaces the
multi-step Redis pre-warm workaround. orphan_scan endpoint replaces the
N+1 per-file /links fetch on the admin files page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 18:18:34 -04:00
Scott Idem
f3c6580b69 fix(files): reliable hosted_file cleanup + orphan detection in /core/files/
Event file delete (Pres Mgmt):
- Re-implement cleanup using /links pre-fetch before delete_hosted_file calls.
  The /links endpoint calls get_id_random() per link which populates Redis.
  Without this, redis_lookup_id_random('event_file', id) raises 404 in the
  delete handler → silent skip → physical file never removed.
  Now mirrors the same pattern used by the /core/files/ admin page delete.

/core/files/ admin page:
- Add orphan check mode: "Check Orphans" button batch-fetches links for all
  visible results in parallel (reusing links_map cache), then filters table
  to show only files with zero links.
- Orphan files get a warning badge in the filename column.
- Results header toggles to show "N orphans of M" when filter is active.
- Unlink icon imported from lucide for orphan UI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 18:02:04 -04:00
Scott Idem
94b3dd84af fix(files): actually delete physical files when removing event_file or hosted_file
event_file delete was broken since the module was first created (Oct 2024).
delete_ae_obj_id__event_file passed delete_hosted_file=true + rm_orphan=true to
the generic V3 CRUD endpoint, but delete_obj_template never handled those params —
it only did a raw sql_delete on the event_file row. The hosted_file_link record,
hosted_file DB record, and physical file on disk were never cleaned up.

Fix: call api.delete_hosted_file (the action endpoint) BEFORE deleting the
event_file record so the backend can still resolve link_to_id via Redis.
Pass link_to_type='event_file', link_to_id=event_file_id, rm_orphan=true,
method=delete. hosted_file_id is now an optional param on
delete_ae_obj_id__event_file; component passes event_file_obj.hosted_file_id.

Also fix hosted_file delete in /core/files/ admin page (same root cause):
load links first, then call delete_hosted_file for each link with correct
link_to_type/link_to_id_random and method=delete before removing the record.

Also: add clickable navigation links in the files admin link sub-row.
Direct types (event, journal, archive, post) resolve immediately; nested types
(event_session, event_location, event_presenter, journal_entry, etc.) fetch
their parent ID via the V3 CRUD endpoint and construct the correct route.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 17:47:10 -04:00
Scott Idem
015a38fd14 feat(files): add Hosted Files admin page at /core/files/
- Search hosted files across all accounts (including disabled)
- Sortable columns, pagination, per-row delete, download, and SHA-256 copy
- Lazy-load file link records per row via /v3/action/hosted_file/{id}/links
- Fix delete to load links first, remove each via correct link_to_type/link_to_id_random,
  then hard-delete with method=delete and rm_orphan=true
- Remove Linked To and Group columns (moved Group/ForType to filter bar only)
- SHA-256 column now visible at lg breakpoint (was xl)
- Added /core/files nav link to /core layout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 17:32:45 -04:00
Scott Idem
fa7889bd80 Added new clear IDB tables button to the AE system bar/menu. 2026-06-18 15:27:03 -04:00
Scott Idem
d939f3190d feat(security): implement API-verified passcode auth with JWT session
Passcodes are no longer compared locally against cached localStorage data.
Entry now POSTs to /v3/action/auth/authenticate_passcode; on success the
returned JWT (with per-role TTL) is stored in $ae_loc.jwt. Page-load
expiry check in +layout.ts resets access_type to anonymous when the JWT
has expired, targeting only auth_type='passcode' JWTs.

- Debounce (600 ms) auto-fires the check after typing stops; Enter key
  fires immediately as a secondary trigger — preserving the original UX
- Inline spinner and error message added to the passcode input
- Silent fallback to local comparison on network error or unresolved
  site_id (ghost), so IDAA staff and Electron/Launcher contexts are safe
- USE_API_PASSCODE_AUTH = true (active); local fallback retained while
  production is observed; site_access_code_kv cleanup deferred

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 13:32:44 -04:00
Scott Idem
e09757f2b1 chore: remove dead legacy CRUD API functions and helpers 2026-06-18 11:55:53 -04:00
Scott Idem
12f799b0d6 chore: add deprecation warnings for idaa_loc migration 2026-06-18 11:43:12 -04:00
Scott Idem
f603780e71 Fixing bug with random appended still 2026-06-18 09:32:46 -04:00
Scott Idem
7ef2b55af6 Fixing the permissions of things again. Yes. Some things are hidden by default for staff/trusted access differently than for admins/managers. Staff should use Edit Mode to see more details and edit things. 2026-06-18 09:19:30 -04:00
Scott Idem
2563307d71 fix(build): resolve store binding and linter warnings to harden build stability
- Removed invalid two-way bindings to read-only Dexie observables in the test page
- Fixed 'state_referenced_locally' warning in Field Editor by refactoring draft_value initialization
- Cleaned up empty else block in session list to resolve Vite build warning
- Verified successful production build and clean 'npm run check' output
2026-06-17 18:16:59 -04:00
Scott Idem
d06dcae94b feat(field-editor): modernize field editor with non-blocking modal and viewport clamping
- Completed rewrite of `element_ae_obj_field_editor.svelte` to Svelte 5 + Tailwind v4
- Set `display_modal = true`, `modal_blocking = false`, and `modal_placement = 'center'` as new defaults
- Implemented trigger-relative modal positioning with automatic viewport boundary clamping to prevent off-screen rendering
- Migrated all 12 call sites across core and events modules (Session, Presenter, Location, Exhibit, etc.)
- Removed legacy datetime-to-local manual conversion logic from views as the component now handles it natively
- Retired Skeleton-based legacy component
- Updated testing page and documentation to reflect the new standardized primitive
2026-06-17 18:01:08 -04:00
Scott Idem
ea413bbb9b style(core): enhance UI consistency, support dark mode, and reorder navigation
- Refactored core layout and dashboard to follow AE Firefly guidelines
- Added proper theme-aware backgrounds and transitioned to Skeleton v4 tokens
- Grouped navigation and cards by functional color (Teal: Infra, Indigo: Identity, Amber: Config)
- Reordered items to: Accounts, Sites, Users, People, Data Stores, Lookups, Addresses, Contacts
- Fixed color inconsistency for Activity Logs in dashboard vs navigation
- Enabled non-blocking modal mode for inline field editors in Data Stores table
2026-06-17 17:27:39 -04:00
Scott Idem
04205e4a63 feat(field-editor): add display_modal mode with placement, blocking toggle, and unsaved-changes guard
- New `display_modal` prop opens the edit panel as a native <dialog> anchored
  near the pencil trigger instead of shifting inline content
- `modal_placement` (center|above|below|left|right, default center) positions
  the dialog relative to the trigger via getBoundingClientRect + CSS transform
- `modal_blocking` (default true) toggles showModal() vs show(); non-modal
  mode adds a document pointerdown listener to close on outside click
- `cancel_edit()` now warns "Discard unsaved changes?" when draft differs from
  saved value (matches data store form behaviour); skips warning after a
  successful save
- Dialog background uses theme CSS vars directly (--color-surface-50/900) via
  :global CSS — Skeleton tonal presets are intentionally semi-transparent and
  rendered behind table content without explicit position:fixed + z-index
- Extracted edit panel to {#snippet edit_panel()} — shared by inline and
  dialog paths with no duplication
- data-stores table: all three inline field editors switched to display_modal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 17:21:17 -04:00
Scott Idem
313eca076d style(data-stores): add icon to Edit button; update style guidelines
- Edit button now has SquarePen icon + text per button UX standard
- Style guidelines: extract button icon+text rule into its own section 8
  (was buried in Accessibility); renumber Accessibility to section 9;
  add code examples and context table for the rule

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 16:24:42 -04:00