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>
Documents ae_send_message recipient names, the directory-name vs
recipient-name gotcha, and ae_inbox inbox defaults. Mirrors the
equivalent section added to the backend bootstrap.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
Two new items in DevOps & Backend: V3 CRUD regression fix for
event_file delete (delete_obj_template ignores cleanup params) and
orphan scan endpoint for hosted_file. Both logged after message to
backend agent 2026-06-18.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
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>
- 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>
- TODO__Agents.md: check off completed passcode JWT migration items;
document the three remaining cleanup steps (deferred ~a few days)
- PROJECT__AE_Site_Passcode_Security.md: update status to active/cleanup-deferred,
check off completed implementation checklist items
- GUIDE__SvelteKit2_Svelte5_DexieJS.md: add new section documenting the
async-function-from-$effect guard-reset infinite loop pattern, with the
real example from the passcode auth bug (2026-06-18)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
- 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
- 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
- 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
- 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>
- 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>
Row is no longer a giant click target. Code, Name, and Type cells now use
AE_Field_Editor for inline editing (pencil in edit_mode). Edit button opens
the full modal for everything else. Preview column hidden (kept in markup).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- order_by_li was sent as an array; backend expects plain object — fixes sort
- pass enabled/hidden directly to search_ae_obj (was defaulting to 'enabled'/'not_hidden')
- account column now shows code/short_name from Dexie cache via SvelteMap
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
element_data_store_form.svelte is now the single source of truth for
editing data stores — owns the modal, all form fields, change detection,
save/delete API calls, and IDB cache update.
- element_data_store.svelte: remove ~120 lines of duplicated form/handler
code; now delegates to AE_DataStore_Form via bind:open + callbacks
- data_stores/+page.svelte: open_edit/open_new are now 2 lines each;
remove all draft state, submit_status, handle_save/delete; fix label
a11y (wrapping labels on all filter + bulk-rename inputs)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add original_obj prop + has_changes bindable output to element_data_store_form
- Derive has_changes by comparing each draft field to original_obj; null = always dirty (new record)
- Wire bind:has_changes + original_obj={is_new ? null : editing_obj} in management page
- Fix Save button: preset-filled-primary → preset-filled-primary-500 (matches element_data_store)
- Disable Save when !has_changes; block modal outsideclose when changes are pending
- Restore textarea rows 10 → 15 to match element_data_store.svelte
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New element_data_store_form.svelte handles all form fields for creating/
editing a Data Store. Replaces the inline form in the management page modal.
Features vs old inline form:
- Help text on every label (type descriptions, constraint notes, etc.)
- Advanced section (collapsible, hidden by default): Enable, Hide, Priority,
Sort, Group, Notes — each with hint text
- For ID: editable on new, read-only on edit (with explanation why)
- show_account_field / show_for_fields props for embedded widget use later
- html_edit_mode + show_advanced are internal state, reset via {#key} on parent
Management page: drops html_edit_mode state + Code/Eye/editor imports; uses
{#key editing_obj?.id ?? 'new'} to recreate the form on each record change.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- api.ts: remove get_data_store_obj_w_code (hit /data_store/code/, non-V3)
and its export. V3 get_data_store (/v3/data_store/code/) stays.
- ae_core_functions.ts: remove load_ae_obj_code__data_store (wrapper around
the removed function) and its export from core_func.
element_data_store.svelte replaced this with Dexie LiveQuery + V3 API.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Click any column header to sort; click again to toggle ASC/DESC.
Sort re-runs the current search immediately if results are showing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add Bulk Rename panel: code filter (% wildcard), find/replace text,
preview table before apply, sequential PATCH with IDB cache update
- Fix Code filter label/placeholder to show % wildcard syntax
- Add note that API results are scoped to the active account (backend behavior)
- Replace bg-black/5 with bg-surface-500/10 for light/dark compatibility
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Full CRUD for all data_store records: search by code, account_id,
for_type, for_id; create/edit/delete via modal with type-aware content
editor (CodeMirror / TipTap / textarea). Wired into core nav and
dashboard. for_id shown read-only on edit (DB integer FK constraint).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
for_id is an integer FK in the DB but the frontend passes the random
string ID — sending it on update causes a 400. These fields are
parent-context set at creation time and should never change on edit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two fixes in presenter_view:
1. Name-sync warning (given/family mismatch) was showing even when no
Person was linked. Guard now checks person_id first.
2. Person link replaced the two-step Re-link button flow with on_open
pattern (matches Session POC). Pencil+Re-link button removed; pencil
icon opens the editor and loads the person list in one action.
Admin-only re-link restriction preserved: non-admin staff with a
linked person see a read-only link instead of the editor.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v_event_presenter and v_event_presentation both use INNER JOIN with event
on event_id. Without event_id in the payload the view returns 0 rows after
INSERT, the API falls back to a minimal response, and Dexie save fails
with "Object is missing a valid ID". Pull event_id (and event_session_id
for presenters) from events_slct at creation time.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace pill grid (too tall) with a single-row label + select
- Use <optgroup> to keep System / AE grouping without any extra height
- Prune unused Skeleton system themes: concord, crimson, hamlindigo,
rocket, terminus, vintage removed (6 of 10 — never used in practice)
Remaining: nouveau, cerberus, modern, wintry
- Added comment noting Firefly event-specific variants can be pruned
when their events are no longer active
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Theme picker (e_app_sys_bar.svelte):
- Replace flat <select> dropdown with grouped pill buttons
- Two groups: 'System' (Skeleton defaults) and 'AE' (custom themes)
- Active theme highlighted via bg-primary-500 (shows in the current theme's
own primary color — instant visual confirmation)
- Pill labels shortened where helpful (e.g. 'AE_Firefly_SteelBlue' → 'Steel ✦')
- Rename theme_options → skeleton_themes + ae_themes; extract apply_theme()
shared handler (removes duplicated setAttribute + ae_loc.update pattern)
Orphaned component removal (→ ~/tmp/agents_trash):
- e_app_theme.svelte — only imported by the dead legacy menu; the sys_bar
Appearance section fully covers it
- e_app_sys_menu_legacy.svelte — no consumers anywhere in the codebase;
sys_bar (mounted in +layout.svelte) fully replaces it
- e_app_cfg.svelte — only mounted from the dead legacy menu; its live
functionality (iframe toggle, reload, URL builder) is all in sys_bar's
Dev/Tools section
npx svelte-check: 0 errors (file count drops from 5403 → 5400)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- app.css: import ae-c-lci-new.css alongside existing ae-c-lci.css
- e_app_theme.svelte, e_app_sys_bar.svelte, e_app_url_builder.svelte:
add 'LCI (New ✦)' option pointing to AE_c_LCI_new selector
Both themes coexist — switch between 'LCI' and 'LCI (New ✦)' in the
theme picker to compare old vs brand-guide-accurate colors and fonts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New parallel theme (data-theme='AE_c_LCI_new') based on the LCI Brand
Guidelines (March 2023, leanconstruction.org). The current ae-c-lci.css
is untouched. Both can coexist.
To activate for review: add @import './ae-c-lci-new.css' to app.css and
add 'AE_c_LCI_new' as a theme option in e_app_theme.svelte /
e_app_sys_bar.svelte / e_app_url_builder.svelte.
Changes vs current theme:
- Primary blue: anchored to #3a5997 (oklch 39% 0.14 264°) — was too
light (47%) and undersaturated (C=0.11). Pantone Surf the Web.
- Secondary: rebuilt from 3-stop LCI scale (#d4e7f7 → #3598dc → #173378),
hue shifted from 264° to 245° (brighter sky-blue direction).
- Tertiary purple: corrected to #8f44ad oklch(43% 0.20 309°) — was too
light (52.73%) and low chroma (0.17). Pantone Dewberry.
- Success teal: minor tweak to #1bbc9d oklch(68% 0.14 175°). Pantone Mint Leaf.
- Error red: corrected to #df3527 oklch(53% 0.27 28°) — was too light
(59.32%) and undersaturated (C=0.21). Pantone Cherry Tomato.
- Typography: heading-font-family → Proxima Nova/Montserrat (brand spec);
base-font-family → Palatino/serif (brand spec). See file for Montserrat
Google Fonts note and app-UI override guidance.
- Heading color: primary-500 (LCI blue) per brand guide PDF.
- Surface: hue shifted from 196° (teal, wrong direction) to 248° (blue).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Updated Element_ae_obj_field_editor_new.svelte with on_open callback support.
- Improved Select field UX in the editor with an inline loading spinner when options are empty.
- Streamlined session_view.svelte by using on_open to trigger person record loading automatically.
- Removed redundant manual 'Select Person' button in favor of automated lazy-loading.
element_data_store.svelte:
- Source/Visual HTML mode toggles: add Code/Eye icons and title attributes
- Cancel button: add X icon and title="Discard changes and close"
- Delete button: add title="Permanently delete this data store — cannot be undone"
- Save button: add title, and Check icon for updated/created success state
(Check was imported but unused; now put to work matching field editor pattern)
- Remove Eraser import (unused)
- Remove ds_submit_results $state (declared but never read in template —
submit status already tracked via $ae_sess.ds.submit_status; drop the
assignment in handle_submit_form too)
element_ae_obj_field_editor_new.svelte:
- Fix duplicate is_editing declaration: user promoted it to a $bindable prop;
remove the now-conflicting local $state declaration
npx svelte-check: 0 errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Integrated AE_Comp_Editor_CodeMirror as a supported field_type.
- Enhanced button UX with descriptive Lucide icons and title text (Eraser for Clear, etc.).
- Switched Location View description field to use the CodeMirror editor.
- Updated test playground to include a CodeMirror example.
Rolls out the full rewrite of the generic inline field editor, standardizing on
Tailwind v4 + Flowbite styling and resolving several long-standing contract issues.
Component Improvements:
- Fully implemented datetime/date conversion (component now owns format normalization).
- Added type-safety via Svelte 5 generics (<script generics="T">).
- Added automatic select value coercion (prevents stuck optimistic state).
- Added support for 'email', 'url', and 'tel' field types.
- Rebuilt styling on Tailwind v4 utility classes, removing legacy Skeleton UI.
- Improved accessibility: added ARIA labels, Escape-to-cancel, and autofocus.
- Improved error handling with visible inline error messages.
Rollout/Migration:
- Migrated all 8 primary call sites (person_view, device_li, locations_li,
location_view, presentation_li, leads_manage, presenter_view, session_view).
- Swapped manual datetime pre-conversion at call sites for internal handling.
- Updated the test playground to show legacy vs. new side-by-side.
This migration runs the new component in parallel with the old one (still present)
ensuring a safe transition.
Creates the _new version of the field editor element alongside the working
original (which remains untouched). The _new file starts from the original's
hardened optimistic-update state machine and adds:
- Svelte 5 generics (T) on current_value/draft_value instead of any
- email / url / tel added to the field_type union with edit-mode branches
- object_reload prop removed (was declared, never implemented — on_success
is and remains the caller's cache-refresh hook)
- to_input_value() / from_input_value() stubs at the two right call sites
for datetime conversion (both directions, TODO #4 to implement)
- coerce_select_value() stub for select type-mismatch fix (TODO #5)
- Inline TODO mini how-to checked-list mirroring the project doc
- Styling still uses Skeleton classes — tagged for Tailwind/Flowbite swap
(TODO #6) and a11y gaps marked at their exact markup locations (TODO #7)
Companion files:
- documentation/PROJECT__AE_Obj_Field_Editor_New.md — full plan, migration
order for all 8 call sites, naming convention note
- documentation/TODO__Agents.md — new entry pointing to the project doc
- documentation/README__Docs_Index.md — project doc added to Active Projects
npx svelte-check: 0 errors, 1 expected benign warning (state_referenced_locally
on the field_type initializer, documented in-file).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pure reformatting, no content change. Each bullet/paragraph is now one
logical line instead of manually wrapped at ~80-100 chars, which looked
ragged with short trailing fragments in narrow/variable-width editor
panels. Editors soft-wrap long lines naturally; manual hard wraps don't
adapt to panel width.
Also gave the orphaned "Wallpaper reliability" item (previously sitting
between two --- dividers with no section header and a stray double
blank line) its own section header for consistency with the rest of
the doc.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>