Commit Graph

1824 Commits

Author SHA1 Message Date
Scott Idem
fde3801ea6 refactor: clean up try_cache defaults and add SWR to sponsorship loaders
- Remove vestigial try_cache param from generate_qr_code (never used in body)
- Remove vestigial try_cache from ae_core_functions: load_ae_obj_id__site_domain,
  update_ae_obj_id_crud, update_ae_obj_id_crud_v2 (none referenced it in body)
- Add proper SWR pattern to load_ae_obj_id__sponsorship_cfg and
  load_ae_obj_id__sponsorship; change defaults from false to true
- Change load_ae_obj_id__event_file default try_cache from false to true
  (consistent with load_ae_obj_li__event_file)
- Change load_ae_obj_id__hosted_file default try_cache from false to true
  (consistent with load_ae_obj_li__hosted_file)
- Remove stale try_cache arg from element_ae_crud.svelte caller
2026-03-11 14:57:23 -04:00
Scott Idem
50a20ebc44 chore: add cSpell words; fix deploy scripts to target ae_app service only
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 14:36:17 -04:00
Scott Idem
bf94e0dee9 fix: extend poster session type context to all file list wrapper contexts
element_manage_event_file_li_all.svelte — also derives context_session_type_code
via Dexie chain (event_presentation → session, or event_presenter → presentation →
session) and passes it to element_manage_event_file_li. Fixes the button not showing
when viewing a presenter's files from the session view.

element_manage_event_file_li_direct.svelte — extends the Dexie chain to also handle
event_session (direct lookup) and event_presentation, not just event_presenter.

Both: correct API URL to /v3/hosted_file/ per backend agent's examples.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 14:35:24 -04:00
Scott Idem
f6a6534380 fix: restore /v3/action/hosted_file path now that endpoint exists in v3 router
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 14:26:29 -04:00
Scott Idem
8cba7899db fix: correct convert_file API path from /v3/action/hosted_file to /hosted_file
The endpoint is registered under the older hosted_file router at /hosted_file/{id}/convert_file,
not under the v3 actions router. Both list and table convert buttons were sending to the wrong path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 14:12:53 -04:00
Scott Idem
477fc16f16 fix: derive poster session type from Dexie chain for presenter-linked files
v_event_file joins event_session only via event_file.event_session_id.
Files with for_type='event_presenter' have event_session_id=NULL on the
file record itself, so event_session_type_code is structurally always NULL
from the API for these files — no amount of refreshing can fix it.

Instead of relying on the file's event_session_type_code, derive the session
type in element_manage_event_file_li_direct via the Dexie chain:
  presenter.event_presentation_id → presentation.event_session_id → session.type_code

Pass the result as context_session_type_code to element_manage_event_file_li,
which now checks EITHER the file's own event_session_type_code OR the context
prop against 'poster' to show the PDF→Image convert button.

Sessions are guaranteed in Dexie because the pres_mgmt layout loads
inc_session_li:true on every navigation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 14:06:33 -04:00
Scott Idem
4690548946 fix(events): switch onMount→\$effect for file list Dexie refresh
onMount fired before the parent presenter liveQuery resolved, so
link_to_id was undefined and the refresh was silently skipped.

Using \$effect makes the background refresh re-run once link_to_id
becomes available (after the presenter Dexie lookup completes),
ensuring event_session_type_code is written to Dexie and the
PDF→image convert button renders correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 13:43:33 -04:00
Scott Idem
de8b85bb05 fix(events): refresh file list on mount to populate event_session_type_code in Dexie
The presenter detail page loads files with try_cache:false, which fetches
fresh data from the API but does NOT write it to Dexie (by design in the
SWR implementation). The file list's liveQuery then reads stale Dexie
records that lack event_session_type_code, causing the PDF→image convert
button condition to silently fail for presenter files in poster sessions.

Fix: trigger a try_cache:true background refresh on mount in the direct
wrapper so fresh API data (with event_session_type_code='poster') is
persisted to Dexie and the liveQuery re-renders with the correct field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 13:33:31 -04:00
Scott Idem
b2fa1a59dc feat(events): add PDF→webp convert button to event file list view
Mirrors the convert button added to the table view (ae_comp__event_file_obj_tbl).
The list view (element_manage_event_file_li) is the primary Pres Mgmt UI
for managing event files per object (session, presenter, location, etc.).

Same conditions: edit_mode on, extension=pdf, event_session_type_code=poster.
Per-row status: idle → converting → done | error with retry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 13:24:41 -04:00
Scott Idem
2e08f5ff15 feat(events): restore PDF→webp convert button in event file table
Adds a per-row "Convert PDF → Image" button in ae_comp__event_file_obj_tbl.
Only shown when edit_mode is on, the file is a PDF, and the session
type_code is 'poster' — poster sessions need images in the Launcher modal
(which uses <img>, not a PDF viewer).

Calls GET /v3/action/hosted_file/{id}/convert_file (pdf2image, 3840px wide,
first page, saves as a new hosted_file linked to the same parent object).
Per-row status tracking: idle → converting → done | error with retry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 13:01:26 -04:00
Scott Idem
241e05bc79 feat: add store_versions.ts — localStorage schema versioning for ae_loc and ae_events_loc
Persistent stores grow and change over time. svelte-persisted-store deep-merges
old localStorage values with new defaults, so stale values (e.g. hash_prefix_length: 1)
silently survive schema changes and cause subtle bugs.

- src/lib/stores/store_versions.ts:
  Single source of truth for AE_LOC_VERSION / AE_EVENTS_LOC_VERSION.
  Side-effect on import: reads raw localStorage and wipes if __version mismatches.
  Must be imported first in ae_stores.ts and ae_events_stores.ts so the wipe
  happens before persisted() hydrates from localStorage.

- ae_stores.ts + ae_events_stores.ts:
  Import store_versions as first import; add __version to persisted store defaults.

- documentation/TODO__Agents.md:
  Added stores refactor task — both store files need a cleanup pass.

Bump AE_LOC_VERSION or AE_EVENTS_LOC_VERSION by 1 on breaking schema changes.
Non-breaking changes (new optional fields, default value tweaks) do not need a bump.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 12:43:05 -04:00
Scott Idem
ca91afbd9d chore: Optimized Dockerfile and .dockerignore for faster deployments. 2026-03-11 12:36:34 -04:00
Scott Idem
56fd1d1760 fix: Launcher dead-code cleanup — dead else-if branch and unused handle_get_device_info
- launcher/+layout.svelte: dead {:else if $events_slct.event_session_id} branch
  (condition identical to preceding {#if}) replaced with correct
  {:else if $events_slct.event_location_id} — shows "Select a session"
  prompt when a room is chosen but no session is yet selected.

- launcher/[event_location_id]/+page.svelte: removed unreachable
  handle_get_device_info() function (never called; pre-relay pattern
  superseded by launcher_background_sync.svelte's run_device_heartbeat()).
  Cleaned up now-unused imports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 12:30:41 -04:00
Scott Idem
93efabdf00 docs(electron): fix cross-repo confusion, remove misplaced file, update integration docs
- Remove tmp_shell_handlers.ts from SvelteKit repo — this was a draft of the
  Electron main-process shell handler that was placed in the wrong repo. It used
  ipcMain (Electron main-process only) and could never run in SvelteKit. Was not
  imported anywhere but was misleading.

- Fix src/lib/electron/README.md:
  - Correct broken doc link (was AE_EVENTS_LAUNCHER_NATIVE_INTEGRATION.md,
    actual filename is PROJECT__AE_Events_Launcher_Native_integration.md)
  - Mark electron_native.js as DEPRECATED — do not import (was described as
    active "Bridge Logic", which was incorrect and confusion-causing)
  - Add clear bridge architecture diagram showing the three-layer flow
  - Note that aether_app_native_electron/ is the active Electron repo

- Update PROJECT__AE_Events_Launcher_Native_integration.md:
  - Fix Layer 1 file path: aether_app_native/ → aether_app_native_electron/
  - Section 5.3: Phase 5 actuators are all implemented, not "planned" — update
    recording, display layout, power control, window control, wallpaper to reflect
    actual implementation status; note update_app is a stub
  - Section 7: Expand IPC whitelist to cover all relay functions including new
    cleanup_tmp_files, system handlers, and full parameter signatures
  - Document get_seed_config / get_jwt as intentionally not relayed to UI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 11:59:29 -04:00
Scott Idem
556a395a3e fix: always default hash_prefix_length to 2, never preserve stale localStorage value
The event_device table has no hash_prefix_length column, so incoming_dev.hash_prefix_length
is always undefined from the API. The old merge logic preserved whatever was in localStorage,
which had a stale value of 1 from earlier testing — causing the background file sync to create
1-char cache subdirectories instead of the correct 2-char SHA-256 prefix dirs.

Background sync now consistently creates 2-char dirs matching launch_from_cache behavior.
If the API ever returns a hash_prefix_length, it will be used; otherwise the floor is 2.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 11:41:42 -04:00
Scott Idem
319b935cc5 feat(launcher): configurable .tmp cache cleanup in cfg panel
- launcher_cfg_local_actions.svelte: add "Cache Maintenance" block
  (native-only, gated by is_native && cache_root); number input for
  max age in hours, "Clean Now" button with status feedback
- launcher_background_sync.svelte: read cleanup_tmp_max_age_hours
  from events_loc.launcher store (default 24h) instead of hardcoded
  1440 minutes; setting persists across sessions via persisted store

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 10:56:39 -04:00
Scott Idem
f6344008ea security: use bootstrap key in manifest, add .tmp cache cleanup
- manifest.webmanifest/+server.ts: swap PUBLIC_AE_API_SECRET_KEY →
  PUBLIC_AE_BOOTSTRAP_KEY (least privilege; endpoint only needs a
  site-domain lookup, same as the bootstrap use case)
- electron_relay.ts: add cleanup_tmp_files() — runs `find ... -name
  "*.tmp" -mmin +N -delete` via native run_cmd bridge
- launcher_background_sync.svelte: call cleanup_tmp_files() on mount
  when is_native && cache_root are present (once per startup)
- AE__Permissions_and_Security.md: close Sev-1 audit language
- TODO__Agents.md: mark PUBLIC_AE_API_SECRET_KEY audit as complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 10:54:17 -04:00
Scott Idem
a34f70d3dd Removed and or moved old documentation. 2026-03-11 10:18:44 -04:00
Scott Idem
b479dea33e [Launcher] Add accessibility controls + doc comments to sidebar menu
- New: menu_launcher_controls.svelte — bottom control bar for the launcher
  sidebar with font size cycler (A / A+ / A−) and light/dark mode toggle,
  always visible regardless of access level; visibility toggles (All Files /
  All Sessions) moved here from launcher_menu.svelte and restyled to
  preset-tonal-tertiary with descriptive title attributes
- launcher_menu.svelte — replace inline visibility-toggle block with
  <Menu_launcher_controls />; add full header doc-comment describing
  component structure and data flow
- menu_location_list.svelte — add header doc-comment covering purpose,
  visibility rules, data flow, and the intentional non-bindable prop pattern
- documentation/TODO__Agents.md — mark font size cycler task complete
2026-03-11 10:18:13 -04:00
Scott Idem
6a98b5801b Version bump to 3.00.01 2026-03-11 09:37:47 -04:00
Scott Idem
366c66293c chore: npm update - minor/patch dependency updates
Updated 170 packages within semver ranges. Notable updates:
- svelte: 5.45.10 -> 5.53.10
- @sveltejs/kit: 2.49.2 -> 2.53.4
- tailwindcss: 4.1.18 -> 4.2.1
- dexie: 4.2.1 -> 4.3.0
- openai: 6.10.0 -> 6.27.0
- vite: 7.2.7 -> 7.3.1
- @skeletonlabs/skeleton: 4.8.0 -> 4.12.1

Skipped: eslint 9->10, @eslint/js 9->10, globals 16->17 (major bumps, need separate review)
svelte-check: 0 errors, build: success
2026-03-10 19:13:36 -04:00
Scott Idem
5eb3374ac0 chore: upgrade node:21-alpine to node:22-alpine (Active LTS)
Node 21 was a non-LTS release, EOL June 2024. Node 22 is the current
Active LTS, supported through April 2027.
2026-03-10 18:58:23 -04:00
Scott Idem
ec00f75df6 fix: revert BuildKit cache mounts (BuildKit not default on this host) 2026-03-10 17:10:19 -04:00
Scott Idem
5e0cc73084 perf: add BuildKit npm cache mounts, add compose:down script
- RUN --mount=type=cache,target=/root/.npm for both npm install steps
  Persists npm cache across builds so unchanged deps aren't re-downloaded
- deploy:staging now targets ae_app only (skip api/nginx rebuild)
- compose:down includes --profile database to remove mariadb/pma containers
  and cleanly release ae_dev_net (fixes 'Resource is still in use' warning)
2026-03-10 16:56:41 -04:00
Scott Idem
9646f7fec2 fix: remove dead PUBLIC_TESTING import from ae_stores.ts 2026-03-10 16:40:21 -04:00
Scott Idem
f03627ef3c security: move hardcoded bootstrap API key to env var
PUBLIC_AE_BOOTSTRAP_KEY replaces the hardcoded 'IDF68Em5X4HTZlswRNgepQ' in:
- src/routes/+layout.ts (site-domain bootstrap request)
- src/routes/testing/+page.svelte (trace agent key)

Added to .env.staging, .env.prod, .env.local (gitignored), and updated
.env.staging.default / .env.prod.default with XXXX placeholders.
Key can now be rotated independently from the main API secret key.
2026-03-10 16:30:11 -04:00
Scott Idem
b7d9e9669d chore: clean up env templates, docs, and TODO
- .env.staging.default / .env.prod.default: remove dead Red/Green/Blue container
  vars, OSIT_WEB_PORT vars, DOCKER_AE_EXTRA_HOST entries, AE_APP_CFG_ID,
  AE_APP_NODE_PORT_RED/GREEN/BLUE, PUBLIC_AE_API_SERVER_INTERNAL; replace real
  staging key with XXXX placeholder (default files are committed to git);
  fix .prod PUBLIC_AE_API_PORT 5005 -> 443 (external rev proxy, not gunicorn)
- TODO__Agents.md: clean up completed items, condense history, update DevOps section
- PROJECT__AE_combined_front_back_Docker.md: mark unified Docker architecture complete
2026-03-10 16:19:23 -04:00
Scott Idem
a3d7ea7a78 [Cleanup] Guard remaining unguarded console.log calls
- core__crud_generic.ts: guard patch result logs (lines 246/252) with
  if (log_lvl) — these fired on every successful patch call
- e_app_sign_in_out.svelte: already committed in previous round
- element_manage_hosted_file_li.svelte: already committed in previous round

All other console.log calls in launcher/lib files confirmed already guarded
via $B2 context check. Remaining unguarded logs are in event handlers
(fire on user action only, not hot render paths) or testing/admin pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 15:07:01 -04:00
Scott Idem
04a8edc6d1 [Perf] Fix liveQuery reactivity, silence debug logs, add performance guidelines
- launcher/+layout.svelte: convert lq__event_session_obj from $derived to
  $derived.by() so Svelte tracks event_session_id as a dependency; the old
  pattern read the store inside the Dexie async callback where Svelte's
  tracking is off, so the liveQuery never updated on session change
- ae_events__event_file.ts: fix hardcoded log_lvl: 2 in SWR fire-and-forget
  background refresh (always-on debug logging on every cache hit) → 0
- e_app_sign_in_out.svelte: lower 6 call-site log levels (1×log_lvl:2,
  5×log_lvl:1) to 0; sign-in runs on every page load
- element_manage_hosted_file_li.svelte: log_lvl:2 → 0 in refresh call;
  remove log_lvl=1 assignment + debug block inside click handler; log_lvl:1
  → 0 in delete call
- AE__Performance_Guidelines.md: add 5 Svelte 5 runes rules covering
  $derived.by() for reactive liveQuery, liveQuery purity, cheap equality
  guards ($id+updated_on, ID-join, shallow_equal), untrack() requirement,
  and log_lvl discipline

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 15:01:42 -04:00
Scott Idem
7139753c79 Docs: update TODO and add combined Docker architecture reference
TODO__Agents.md: Mark QR code on badge front as done — ae_comp__badge_obj_view.svelte
already generates the QR via core_func.js_generate_qr_code() and renders it
inside a {#await qr_data_url} block on the badge face.

PROJECT__AE_combined_front_back_Docker.md: New reference document covering
the combined front+back Docker orchestration architecture (consolidated
notes from the session).
2026-03-10 14:24:09 -04:00
Scott Idem
517c40bb11 Chore: silence debug logging across all pages (log_lvl → 0)
Set log_lvl to 0 in all pages and layouts that had it left at 1 or 2
from development. Also remove two hardcoded `log_lvl = 2` overrides
inside function bodies in reports_files.svelte and
reports_presenters.svelte that were forcing verbose output regardless
of the module-level setting.

Affected: launcher location page, leads pages (2), pres_mgmt reports (2),
presenter +page.ts, IDAA layouts (2), IDAA archives, IDAA recovery
meetings page, journals pages (2).
2026-03-10 14:23:28 -04:00
Scott Idem
283ccb3ce4 Tests: fix IDAA recovery meeting test suite
Multiple failures caused by the SWR background fetch pattern and
collapsed UI sections:

1. IDB settle wait: add waitForFunction that polls IndexedDB for
   tmp_sort_1 on the event record. tmp_sort_1 is only written by
   _process_generic_props, so its presence signals the background
   API fetch has completed and no further liveQuery re-fires will
   overwrite form inputs the test is about to fill.

2. JSON.parse for _json fields: update_ae_obj_v3 auto-serializes any
   key ending in _json to a JSON string before sending the PATCH.
   Tests now parse location_address_json, attend_json, and
   contact_li_json from the captured body before asserting field values.

3. Contact 2 section: collapsed by default when contact_2.full_name
   and email are null. Collapsed state renders type='hidden' inputs
   which Playwright's fill() rejects. Add click on the 'Contact 2
   (Optional)' toggle before filling those fields.

4. Admin Options section: same collapse pattern. Add click on the
   'Admin Options' toggle before filling status/sort/group/hide fields.

5. Increase suite timeout to 60 s: open_edit_form awaits real lookup
   API responses (pass_through_lookups=true) which can take 20-25 s
   on slow network, leaving no margin at the default 30 s limit.
2026-03-10 14:23:01 -04:00
Scott Idem
44d4b8e04f IDAA: guard attend_json.zoom against SWR IDB re-fire crash
The Zoom button onclick initialises attend_json.zoom. However the
background SWR list fetch (load_ae_obj_li__event in +layout.ts) can
overwrite $idaa_slct.event_obj with a fresh IDB record where
attend_json = {} (no zoom key), even if the Zoom button was already
clicked.

Without the guard, the $effect that rebuilds the Zoom full URL and the
template bindings below the Zoom fields access attend_json.zoom.passcode_enc
on an undefined object, throwing a TypeError and crashing the component.

Fix: add `&& $idaa_slct.event_obj.attend_json?.zoom` guard to both the
$effect condition and the {#if} block that renders the Zoom input fields.
2026-03-10 14:22:23 -04:00
Scott Idem
3f57077a8b Pres mgmt: migrate session liveQueries to $derived.by() pattern
Replace $derived(liveQuery(...)) with $derived.by(() => { const id = ...; return liveQuery(...) })
for lq__event_presenter_obj and lq__auth__event_presenter_obj in the
session page.

$derived.by() captures only the specific ID at derivation time, so
unrelated store changes do not recreate the observable. Plain $derived
closes over the entire $events_slct store object, causing unnecessary
observable recreation on any store mutation.
2026-03-10 14:21:51 -04:00
Scott Idem
46c2d2da12 Launcher: preserve legacy address fields in IDB; add file_sync to loop_info
ae_events__event.ts: Add legacy flat address fields (address_name,
address_line_1, address_city, etc.) to properties_to_save. Events
predating location_address_json still return these flat fields from
the API; they must survive an IDB round-trip without being stripped
by _process_generic_props, or the edit form's fallback reads return
undefined.

launcher_background_sync.svelte:
- Move file_sync interval into loop_info $state alongside other
  intervals; load from cfg/device config with fallback (30 s). Keeps
  all intervals in one place for UI display consistency.
- Align onMount fallback values to match loop_info defaults.
- Add sync_paused mid-loop break: long sync cycles now honour a pause
  request per-iteration rather than waiting for the entire batch.
2026-03-10 14:21:37 -04:00
Scott Idem
ffc430a727 Perf: replace JSON.stringify comparisons with efficient identity checks
JSON.stringify on large store objects (ae_loc, ae_api, slct, event lists)
was running on every navigation, comparing serialized strings of potentially
deep objects. Replace with targeted comparators:

- Root +layout.svelte: add shallow_equal() helper — O(n keys) key-by-key
  identity check instead of O(serialized bytes). Used for ae_api, ae_loc,
  and slct sync guards.

- Launcher +layout.svelte: ID-list join-compare for event_location_obj_li
  and id_li__event_location (O(n) string vs O(n*m) stringify). Refactor
  liveQuery closures to be pure (data-only, no store reads/writes inside
  the async Dexie context where Svelte reactivity tracking is undefined).
  Move store sync into separate $effects that compare updated_on + id
  (O(1)) or ID-join (O(n)) rather than full object serialization.
2026-03-10 14:20:57 -04:00
Scott Idem
2c0eba4130 DevOps: add svelte-kit sync step to Dockerfile before build
Fixes a build warning about missing .svelte-kit/tsconfig.json that
appears when building inside Docker. Running npx svelte-kit sync
pre-generates the required SvelteKit scaffolding before the main
build step.

Also update README title to reflect Svelte v5 and trim a trailing
whitespace in the environment handling section.
2026-03-10 14:20:40 -04:00
Scott Idem
18462249b3 feat: Integrated SvelteKit frontend into unified Aether orchestration. Updated deploy scripts and documentation. 2026-03-10 13:33:39 -04:00
Scott Idem
b6c55a5042 [Launcher] Fix $bindable warning on slct_event_location_id; audit TODO items
- menu_location_list.svelte: mark slct_event_location_id as $bindable(null) to
  resolve Svelte 5 compiler warning (bind:value used on non-bindable prop)
- TODO__Agents.md: audit and close resolved launcher items:
  - Location select auto-load bug: fixed via $derived.by() liveQuery pattern
  - Session Search button visibility: was never a real bug, hardcoded false
  - Dark mode select fix: already applied via app.css color-scheme rules
2026-03-10 11:30:26 -04:00
Scott Idem
d4f63138ad [DevOps] Add /health endpoint and Docker HEALTHCHECK
- src/routes/health/+server.ts: lightweight health endpoint returning 200 OK
- Dockerfile: HEALTHCHECK hitting /health every 30s, 5s timeout, 10s start period
  Enables Docker/Nginx zero-downtime routing and auto-recovery.
2026-03-10 11:29:02 -04:00
Scott Idem
01316789c6 [UI] Fix native browser controls dark mode (color-scheme sync)
Add html.dark/html.light color-scheme rules to app.css so native controls
(select dropdowns, scrollbars, date pickers) follow the app's class-based
dark mode rather than the OS theme.
2026-03-10 11:28:17 -04:00
Scott Idem
a955fad891 docs: add deployment optimization tasks to TODO list 2026-03-09 22:49:35 -04:00
Scott Idem
38b3164a0c docs: finalize README with updated deployment instructions 2026-03-09 22:27:56 -04:00
Scott Idem
9b285d7fec feat: implement automated Docker deployment and update README
- Replaced manual rsync/npm_deploy workflow with multi-stage Docker builds.
- Added Dockerfile and .dockerignore for staging and production environments.
- Added 'deploy:staging' and 'deploy:prod' scripts to package.json.
- Updated README.md with new deployment instructions.
2026-03-09 22:17:54 -04:00
Scott Idem
206faf0c71 fix: resolve TS errors and Svelte 5 state_referenced_locally warnings
- e_app_sign_in_out: type user_id/person_id as string|null (TS errors)
- archives/[archive_id]/+page.svelte: move if(browser) block to onMount
- ae_idaa_comp__archive_obj_id_edit: wrap timezone loader in onMount
- ae_idaa_comp__archive_content_obj_id_edit: wrap timezone loader in onMount
- bb/[post_id]/+page.svelte: move if(browser) block to onMount
- TODO: add completed entries, note remaining recovery_meetings warnings
2026-03-09 19:40:36 -04:00
Scott Idem
9b7832ee55 feat(themes): Add AE_Firefly variant themes — SteelBlue, Indigo, Rainbow
Three new Firefly-family themes following the AE_Firefly design system:
- AE_Firefly_SteelBlue: metallic steel blue primary (~214°), burnished gold
  secondary, cobalt navy tertiary, chrome silver surfaces
- AE_Firefly_Indigo: deep indigo primary (~266°), violet secondary, dusty
  rose tertiary, velvet slate surfaces
- AE_Firefly_Rainbow: coral-red primary (~15°), emerald green secondary,
  rich violet tertiary, sunrise cream surfaces (spans the visible spectrum)

All variants share consistent semantic colors (success/warning/error) with
AE_Firefly for cross-theme recognizability. All WCAG 2.1 AA compliant.

Also adds URL param support for theme switching:
- ?theme=AE_Firefly_SteelBlue&theme_mode=dark
- Params applied to ae_loc (persisted), then silently removed via replaceState
2026-03-09 19:22:17 -04:00
Scott Idem
2c21117a3f style(idaa): unify Admin Options toggle style across all IDAA edit forms
Replace the old float-right Show/Hide toggle button + separate collapsible
div with an inline caret-button heading inside a consistent section card
(bg-surface-100-900, border-error-400) — matching the recovery meetings v2
form style. All four forms updated: Post, Post Comment, Archive, Archive
Content. Existing class:hidden behaviour preserved so FormData is unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 18:29:39 -04:00
Scott Idem
3a1ec9a861 feat(idaa/recovery_meetings): collapse Admin Options section by default
Admin Options are rarely changed; collapsing by default reduces visual
noise on the long edit form. Hidden inputs preserve status/enable/hide/
priority/sort/group values when the section is collapsed so a save never
silently resets admin fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 18:15:46 -04:00
Scott Idem
b7352c080a feat(idaa/recovery_meetings): UX improvements to long edit form v2
- Add Save Changes button at top of form so users don't scroll to the
  bottom to save; existing meetings only (mirrors v1 behaviour)
- Collapse Contact 2 subsection behind a toggle; auto-expands when the
  meeting already has Contact 2 data saved
- Add hidden inputs when Contact 2 is collapsed so FormData preserves
  existing contact info rather than overwriting with nulls on save

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 18:13:36 -04:00
Scott Idem
8247c62d0e test(idaa): IDAA recovery meeting edit form Playwright test suite + README docs
Full payload-verification test suite for ae_idaa_comp__event_obj_id_edit_v2.

Root cause fixed: $ae_loc.lu_time_zone_list empty at mount caused Svelte 5 to
render <input type=text name=timezone required value=''> instead of the <select>
branch. HTML5 required validation silently cancelled onsubmit with no JS error
and zero network activity — waitForRequest timed out with no obvious cause.
Fix: pre-seed lu_time_zone_list in addInitScript so the <select> branch renders
on first mount with a valid value already set.

Key patterns established:
- setup_idaa_auth(): pre-seeds ae_loc + ae_idaa_loc in localStorage via
  addInitScript; includes lu_time_zone_list and window.__ae_test_mode = true
- setup_api_mocks(): selective pass-through flags for lookups and site_domain
- open_edit_form(): waitForFunction guards for name field, country lists, and
  the timezone required field before any interaction
- capture_patch_body(): registers waitForRequest before click, awaits after

README.md updated with deep-dive section covering:
- HTML5 form validation silent block and how to diagnose it
- Svelte 5 one-time value= bind trap
- addInitScript store pre-seeding pattern
- __ae_test_mode email suppression
- waitForFunction patterns for reactive state
- Route mock strategy (pass-through vs fixture)
2026-03-09 17:54:01 -04:00