graphify-out/ is a local dev artifact (like .svelte-kit/) — the
post-commit hook keeps it fresh on disk automatically. No need to
track it in git; removes the commit-after-every-commit noise.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents the graphify query-before-grep workflow for agents:
query/explain/path commands, auto-rebuild via post-commit hook,
and GRAPH_REPORT.md for broad architecture overview. Adds row
to the reading order table.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Hook ran AST update after initial commit, refreshing graph.json,
GRAPH_REPORT.md, labels, and manifest. Adds dated snapshot at
graphify-out/2026-06-23/.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
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>
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>
- 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>
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>
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>
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>
- 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>
Mistake #19 (and BOOTSTRAP item #10) incorrectly stated the dev server is
unaffected. In practice, saving the file triggers Vite HMR which hits the
same SyntaxError and crashes the page with a 500. Confirmed in session where
sign_in_out.svelte used presenter_id_hint?: string | null.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
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>
- 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>
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>
Missed by the earlier refactor sed (which only ran over src/); the mock
path in create_event_badge.spec.ts still pointed to the old $lib/api/api.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
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>
Documents the param?: Type pattern that esbuild mishandles in .svelte
files (strips the type but leaves ?, producing invalid JavaScript). Adds
the full write-up to REFERENCE__Common_Agent_Mistakes.md and a summary
entry #10 to BOOTSTRAP__AI_Agent_Quickstart.md §7.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
The postinstall hook (scripts/postinstall.mjs) runs during `npm install`, but the
Dockerfile only copied package*.json before that step, so the script wasn't present.
- Copy scripts/ alongside package*.json in the builder stage.
- Add --ignore-scripts to the deploy-stage npm install: flowbite-svelte is a
devDependency and won't be installed there, so the postinstall patch is irrelevant
and the script file won't be available in that stage anyway.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
flowbite-svelte ships TypeScript optional-param syntax (x?: string, event?: MouseEvent,
date?: Date) in its dist .svelte files. Vite's esbuild dep pre-bundler processes these
files (via dist/*/index.js re-exports) and fails with "Unexpected '?'" parse errors
whenever the lockfile changes and the dep cache is rebuilt.
- Add scripts/postinstall.mjs: patches 4 specific TypeScript signatures in
CommandPalette.svelte, ScrollSpy.svelte, and Datepicker.svelte after every npm install.
Patches are idempotent and targeted — only the ?-in-param-position syntax is removed;
optional-chaining (?.) in function bodies is untouched.
- Add "postinstall" script to package.json to run it automatically.
- Upgrade flowbite-svelte 1.31.0 → 1.33.1 (both have the same issue; 1.33.1 is current).
- npm update now works without breaking the dev server.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
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>
The previous session added flowbite-svelte to optimizeDeps.exclude to
fix an esbuild TypeScript syntax error with 1.33.1. But tailwindcss 4.3+
is now stricter: when a style virtual module fails to load (which happens
when the package is excluded from pre-bundling), tailwindcss receives the
raw .svelte file content — including TypeScript — and rejects it with
"Invalid declaration: Side".
With flowbite-svelte 1.31.0, only Drawer and Modal are imported. Neither
their dist files nor their transitive deps have TypeScript optional-param
syntax (?: ) that would cause esbuild to fail. Safe to remove the exclusion.
Updated the comment to explain when/why to re-add it if upgrading.
Dev server: clean start, HTTP 200 ✔ | npm run build ✔
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
npm update (c4d4d2bde) silently upgraded @sveltejs/kit (2.53→2.66),
rollup (4.59→4.62), and svelte (5.53→5.56) together, which caused the
SSR production build to fail: rollup received raw .svelte files without
vite-plugin-svelte transforming them (non-deterministic, race condition).
Fix: restore stable package-lock from 468ed61b3, then selectively update
only tailwindcss and its ecosystem (4.2.1→4.3.1) to resolve DEP0205.
Align @tailwindcss/vite constraint to ^4.3.0 to match.
Also adds flowbite-svelte to optimizeDeps.exclude — it ships TypeScript
optional-param syntax in compiled .svelte dist files that esbuild rejects
during dependency pre-bundling (will matter when flowbite-svelte updates).
Build tested: npm run build ✔ | svelte-check: 0 errors 0 warnings ✔
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
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>
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>
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>
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>