diff --git a/TODO.md b/TODO.md index 49232f36..4ca0276c 100644 --- a/TODO.md +++ b/TODO.md @@ -4,63 +4,48 @@ This is a list of tasks to be completed before the next event/show/conference. --- -## Tomorrow's Priorities (Jan 22, 2026) +## High Priority (Active Task) -1. **Journal Entry Search Cleanup:** - - [ ] Update `ae_comp__journal_entry_obj_qry.svelte` to use dynamic `$journals_loc` values for `enabled` and `hidden` parameters instead of hardcoded strings. - - [ ] Verify that the search results correctly respect these filters. -2. **Hardening V3 Search (Continued):** - - [x] **Event Presenter Search:** Restore specialized business logic. (Completed 2026-01-21) - - [x] **Event Badge Search:** Restore specialized business logic. (Completed 2026-01-21) - - [ ] **Exhibit Search:** Restore missing search function and logic. - - [x] **IDAA Result Limit:** Resolved over-fetching issue; results are now strictly limited at the API, Cache, and UI layers. (Completed 2026-01-22) - - 3. **Journal Module (Config Sprint):** +1. **Aether Native V3 (Launcher):** + - [ ] Scaffold new Electron 33+ shell. + - [ ] Implement V3 "Zero-Config" bridge between shell and SvelteKit frontend. + - [ ] Reference `documentation/NATIVE_APP_V3_REWRITE_PLAN.md` for architectural constraints. --- -## Current Priorities (Jan 21, 2026) +## Current Priorities (Jan 23, 2026) -1. **Hardening V3 Search (URGENT):** - - [x] **Event Session Search:** Finalized and verified. Added `default_qry_str` to V3 body. (Completed 2026-01-21) - - [x] **IDAA Recovery Meetings Search:** Restored functionality using V3 `search__event` with `default_qry_str`. (Completed 2026-01-21) - - [x] **Journal Entry Search:** Fixed `match` operator error (switched to `like`) and resolved iteration crashes by unwrapping API envelopes. (Completed 2026-01-21) - - [x] **Legacy Compatibility:** Restored `qry_ae_obj_li__event`, `qry__event_file`, `qry__event_session`, and `qry__event_badge` aliases to resolve build errors and support Reports. (Completed 2026-01-21) - - [ ] **Global Rule:** Preserve `ft_qry`, `lk_qry`, and `and_qry` blocks as "sacred" business logic. Never put non-searchable fields in the POST body. -2. **Service Worker Reliability (Mitigated):** - - [x] **Disable Auto-Registration:** Temporarily disabled `serviceWorker.register` in `svelte.config.js` to stop `TypeError` loop. - - [x] **Fix Tool:** Moved `fix-sw` utility to `/testing/fix-sw` for future debugging. - - [ ] **Root Cause Investigation:** Re-enable SW registration later and debug why the script evaluation fails (likely caching or build artifact issues). -3. **Aether Native V3:** Technical planning complete. Ready to scaffold the new Electron 33+ shell and implement the V3 "Zero-Config" bridge. -4. **Jitsi Module Updates:** Prepare for upcoming demo. Audit `video_conferences/+page.svelte` for UI/UX improvements and stability. +1. **Journal Module (Cleanup):** + - [x] **Entry Search Refactor:** Update `ae_comp__journal_entry_obj_qry.svelte` to use dynamic `$journals_loc` values. (Completed 2026-01-23) + - [x] **Verify Filters:** Search results correctly respect Enabled/Hidden toggle states. (Completed 2026-01-23) + - [x] **Config Sprint:** Added Query Limit configuration to settings modal. (Completed 2026-01-23) +2. **Hardening V3 Search (Continued):** + - [x] **Event Session Search:** Finalized and verified. (Completed 2026-01-21) + - [x] **IDAA Recovery Meetings Search:** Restored functionality. (Completed 2026-01-21) + - [ ] **Exhibit Search:** Restore missing search function and logic. + - [ ] **Global Rule:** Preserve `ft_qry`, `lk_qry`, and `and_qry` blocks as "sacred" business logic. +3. **Service Worker Reliability (Mitigated):** + - [x] **Disable Auto-Registration:** Temporarily disabled to stop `TypeError` loop. + - [ ] **Root Cause Investigation:** Re-enable SW registration and debug script evaluation failure. +4. **Jitsi Module Updates:** Prepare for upcoming demo. Audit `video_conferences/+page.svelte`. --- ## 🛠️ DX & Tooling (MCP) -- [x] **V3 API Parameter Hardening:** Updated `search_ae_obj_v3` to correctly serialize object-type parameters (JSON strings) in URLs. (Completed 2026-01-21) -- [ ] **Enhance `ae_obj_info`**: Include field types, constraints (NOT NULL), and default values. -- [ ] **Payload Validation**: Create a dry-run tool to check payloads against Pydantic models. -- [x] **Error Transparency**: Update backend to return specific SQLAlchemy/Pydantic errors in `meta.details`. (Completed 2026-01-19) -- [ ] **Automated Source of Truth**: Generate \`V3_OBJECT_MODELS.md\` automatically in \`agents_sync/Aether/\`. -- [x] **Fix V3 Search for IDAA Recovery Meetings** (Completed 2026-01-20) -- [x] **Restore System Lookups** (Completed 2026-01-20) +- [x] **V3 API Parameter Hardening:** Updated `search_ae_obj_v3` for URL serialization. (Completed 2026-01-21) +- [ ] **Enhance `ae_obj_info`**: Include field types, constraints, and default values. +- [ ] **Payload Validation**: Create dry-run tool for Pydantic model checking. +- [x] **Error Transparency:** Return specific errors in `meta.details`. (Completed 2026-01-19) --- ## Frontier Journals Module (Vision 2026-01-08) -*Goal: Transform Journals into the platform flagship with premium UI/UX and robust security.* +- [x] **Phase 1: Codebase Audit & Schema** (Completed 2026-01-23) +- [x] Refactor `ae_comp__journal_entry_obj_id_view.svelte`. +- [x] Fix type safety in `[journal_id]/+layout.svelte`. +- [x] Stabilize Query logic and UI search behavior in `+page.svelte`. -- [ ] **Phase 1: Codebase Audit & Schema** - - [x] Audit `src/lib/ae_journals` and `src/routes/journals` for Tailwind compliance and code quality. - - [x] Refactor `ae_comp__journal_entry_obj_id_view.svelte` (Header, Editor, Settings extracted). - - [x] Fix type safety in `[journal_id]/+layout.svelte` (Recent entries history view). - - [/] Verify `db_journals.ts` schema for metadata and encryption support. - - [x] Identify and replace non-standard CSS with Tailwind utility classes. - - [x] Update `db_journals.ts` types using the new `agents_sync` exported interfaces. - -## Recent Accomplishments (Jan 21, 2026) -- [x] **API Barrel Safety Protocol:** Established rule to purge barrel files *before* source deletions. -- [x] **PWA Manifest Fix:** Corrected manifest link path in `app.html` to resolve 404s. -- [x] **Search Hardening:** Fixed `search_ae_obj_v3` to support nested object parameters in URLs. -- [x] **Redundancy Cleanup:** Removed all legacy `db_save_ae_obj_li__*` functions and barrel references. -- [x] **Business Logic Restoration:** Began restoring "sacred" search mapping logic for Event Sessions. \ No newline at end of file +## Recent Accomplishments (Jan 23, 2026) +- [x] **Journal Stability:** Resolved display issues where entries failed to show on initial load. +- [x] **Filter Hardening:** Updated LiveQuery to handle NULL/undefined for Enabled/Hidden flags. +- [x] **Config Expansion:** Added dynamic Query Limits (10-1000) to Journal module settings. diff --git a/documentation/NATIVE_APP_V3_REWRITE_PLAN.md b/documentation/NATIVE_APP_V3_REWRITE_PLAN.md index ec8dc8ad..de7fdd6a 100644 --- a/documentation/NATIVE_APP_V3_REWRITE_PLAN.md +++ b/documentation/NATIVE_APP_V3_REWRITE_PLAN.md @@ -5,26 +5,39 @@ **Development Platform:** Arch Linux **API Version:** Aether V3 (REST + JWT) +## 0. Project Purpose +The sole purpose of this Native App is to serve as the **AE Events Launcher**. It provides the SvelteKit frontend with the ability to: +- Persistently cache files in the local filesystem. +- Execute OS-level shell commands and scripts (e.g., launching presentation software). +- Provide a "Zero-Config" experience for onsite event laptops. + ## 1. Minimalist Configuration Strategy To simplify laptop deployment, we will move away from large local JSON files. ### 1.1 The "Seed" Config -Each laptop will contain a `seed.json` located in standard OS config paths (e.g., `~/.config/aether/seed.json` or `~/Library/Application Support/Aether/`). +Each laptop will contain a `seed.json`. For development, this is located at `~/seed.json`. In production, it will move to standard OS config paths (e.g., `~/.config/aether/seed.json` or `~/Library/Application Support/Aether/`). + ```json { - "event_device_id": "AE-LPT-01", - "api_base_url": "https://api.oneskyit.com" + "event_device_id": "dbgMWS3KEHE", + "primary_api_base_url": "https://dev-api.oneskyit.com", + "backup_api_base_url": null, + "onsite_api_base_url": null, + "aether_api_key": "INSdG85ANwsEIru3nUttMw" } ``` +*Note: only `event_device_id` is strictly required for the bootstrapper to start.* ### 1.2 The Bootstrap Flow 1. **Launch:** Electron reads the `seed.json`. -2. **Identity:** App calls `GET /v3/crud/event_device/{id}?view=full_config`. -3. **Hydrate:** API returns the full operational config (Account context, Event settings, File cache paths). -4. **Auth:** App uses its device-specific API key to exchange for a session JWT. +2. **Identity:** App calls `GET /v3/crud/event_device/{id}`. +3. **Hydrate:** App uses `app_base_url` from the device record to search for the corresponding `site_domain`. +4. **Target URL:** Electron constructs the launcher URL: + `http://[app_base_url]/events/[event_id]/launcher/[event_location_id]` 5. **Inject:** Config and JWT are injected into the SvelteKit frontend via the Preload script. ## 2. macOS Hardening (Permissions) +... macOS requires explicit user consent for several features. The new app will handle these during the "Splash Screen" phase. - **AV Access:** Use `systemPreferences.askForMediaAccess('camera')` and `microphone`. diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index 1ed1b6ca..80cd02ba 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -121,30 +121,66 @@ export async function load({ fetch, params, parent, route, url }) { let result: any = null; let api_error = false; - try { - if (log_lvl) console.log(`ROOT LOAD: Starting site lookup V3 for ${fqdn}...`); - - // Use dedicated Agent Key for Bootstrap and include the unauthenticated bypass header ONLY for this request - const bootstrap_api_cfg = { - ...ae_api_init, - api_secret_key: 'IDF68Em5X4HTZlswRNgepQ', - headers: { - ...ae_api_init.headers, - 'x-aether-api-key': 'IDF68Em5X4HTZlswRNgepQ', - 'x-no-account-id': 'bypass' // Force explicit bypass for bootstrap - } - }; + let is_native = false; - result = await lookup_site_domain_v3({ - api_cfg: bootstrap_api_cfg, - fqdn, - view: 'base', - log_lvl - }); - if (log_lvl) console.log(`ROOT LOAD: Site lookup result for ${fqdn}:`, result); - } catch (err) { - console.error(`ROOT LOAD: Site lookup critical failure for ${fqdn}.`, err); - api_error = true; + // Detect Aether Native Bridge (Electron) + if (typeof window !== 'undefined' && (window as any).aetherNative) { + is_native = true; + if (log_lvl) console.log('ROOT LOAD: Detected Aether Native Bridge. Requesting device config...'); + try { + const native_device_config = await (window as any).aetherNative.getDeviceConfig(); + if (native_device_config) { + if (log_lvl) console.log('ROOT LOAD: Native device config received:', native_device_config); + // Map native device config to the expected result structure + result = { + ...native_device_config, + // Ensure naming consistency + account_id: native_device_config.account_id || native_device_config.account_id_random, + site_id: native_device_config.site_id || native_device_config.site_id_random, + site_domain_id: native_device_config.site_domain_id || native_device_config.site_domain_id_random, + }; + + // Inject native device metadata into the location state + if (native_device_config.native_device) { + ae_loc_init['native_device'] = native_device_config.native_device; + // Map specific operational paths + ae_loc_init['local_file_cache_path'] = native_device_config.native_device.local_file_cache_path; + ae_loc_init['host_file_temp_path'] = native_device_config.native_device.host_file_temp_path; + ae_loc_init['recording_path'] = native_device_config.native_device.recording_path; + } + } + } catch (err) { + console.error('ROOT LOAD: Failed to fetch native device config.', err); + } + } + + // Perform standard FQDN lookup if not native or if native fetch failed + if (!result) { + try { + if (log_lvl) console.log(`ROOT LOAD: Starting site lookup V3 for ${fqdn}...`); + + // Use dedicated Agent Key for Bootstrap and include the unauthenticated bypass header ONLY for this request + const bootstrap_api_cfg = { + ...ae_api_init, + api_secret_key: 'IDF68Em5X4HTZlswRNgepQ', + headers: { + ...ae_api_init.headers, + 'x-aether-api-key': 'IDF68Em5X4HTZlswRNgepQ', + 'x-no-account-id': 'bypass' // Force explicit bypass for bootstrap + } + }; + + result = await lookup_site_domain_v3({ + api_cfg: bootstrap_api_cfg, + fqdn, + view: 'base', + log_lvl + }); + if (log_lvl) console.log(`ROOT LOAD: Site lookup result for ${fqdn}:`, result); + } catch (err) { + console.error(`ROOT LOAD: Site lookup critical failure for ${fqdn}.`, err); + api_error = true; + } } // Defensive check: if result is false (common from API helper) or null, use emergency ghost @@ -166,8 +202,7 @@ export async function load({ fetch, params, parent, route, url }) { } const json_data = result; - // CRITICAL: SvelteKit hydration can fail if these are undefined - // V3 ID Vision: Use account_id (random string) instead of account_id_random + // ... rest of the mapping logic ... account_id = json_data.account_id || json_data.account_id_random || 'ghost'; data_struct.account_id = account_id; ae_acct.account_id = account_id; @@ -178,6 +213,7 @@ export async function load({ fetch, params, parent, route, url }) { ae_acct.api.account_id = account_id; ae_acct.api.headers['x-account-id'] = account_id; + ae_loc_init['is_native'] = is_native; ae_loc_init['account_id'] = account_id; ae_loc_init['account_code'] = json_data.account_code || 'ghost'; ae_loc_init['account_name'] = json_data.account_name || 'Ghost Account'; diff --git a/src/routes/events/[event_id]/(launcher)/README.md b/src/routes/events/[event_id]/(launcher)/README.md index 43db36df..fa9a126c 100644 --- a/src/routes/events/[event_id]/(launcher)/README.md +++ b/src/routes/events/[event_id]/(launcher)/README.md @@ -1,3 +1,8 @@ # Aether (AE) Event Launcher Module (v3) This directory contains the files for the new Event Launcher module (v3). Detailed documentation to follow. + +This should be able to run in 3 modes: +* Default - What most users will see for demo purposes +* Onsite - This is what is set onsite, usually just in the Speaker Ready Room +* Native App - This is for the native app version of Aether and used on the MacBook laptops in each of the session rooms \ No newline at end of file