Enhance: Integrate Aether Native Bridge and update V3 deployment plan

- Updated +layout.ts to detect window.aetherNative and prioritize hydrated config.
- Mapped native operational paths (cache, recordings) to global location store.
- Refined NATIVE_APP_V3_REWRITE_PLAN.md with Two-Step Bootstrap strategy.
- Updated TODO.md with project progress and next-gen launcher priorities.
This commit is contained in:
Scott Idem
2026-01-23 14:08:37 -05:00
parent 4d932fcd2c
commit 20b41ebaef
4 changed files with 116 additions and 77 deletions

77
TODO.md
View File

@@ -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.
## 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.

View File

@@ -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`.

View File

@@ -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';

View File

@@ -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