docs: clarify Electron scope, update badge test lessons, all badge tests passing
- AE__Architecture.md: Add section 7 -- Runtime Environment: Browser vs Electron. Electron is ONLY for Events Pres Mgmt Launcher. Badge printing (and everything else) works via standard browser window.print(), no Electron needed. - MODULE__AE_Events_Badges.md rev 3: Update print section to browser-first approach, remove Electron from print workflow, add two new test lessons (flat API URLs, CSS attribute vs DOM property), mark all tests passing. - TODO__Agents.md: Add completed data integrity test fixes item, add window.print() wiring to upcoming tasks, expand input field audit note.
This commit is contained in:
@@ -135,7 +135,34 @@ A list of potential future standard fields, often prefixed with `obj_`. These ar
|
||||
|
||||
- `obj_id`, `obj_ext_uid`, `obj_ext_id`, `obj_import_id`, `obj_code`, `obj_account_id`, `obj_passcode`, `obj_type`, `obj_type_ver_id`, `obj_name`, `obj_summary`, `obj_outline`, `obj_description`, `obj_enable`, `obj_enable_on`, `obj_archive_on`, `obj_hide`, `obj_priority`, `obj_sort`, `obj_group`, `obj_cfg_json`, `obj_notes`, `obj_created_on`, `obj_updated_on`.
|
||||
|
||||
## 7. IndexedDB LiveQuery Usage
|
||||
## 7. Runtime Environment: Browser vs Electron
|
||||
|
||||
The Aether SvelteKit frontend runs in a standard web browser in almost all cases. The Electron native app is a **very specialized exception** with a narrow, specific purpose.
|
||||
|
||||
### 7.1. Standard Browser (Default)
|
||||
|
||||
All Aether modules run in a regular browser (Chrome, Chromium, Firefox, Safari). This includes:
|
||||
- Badge printing — `window.print()` works well across Chrome, Chromium, and Firefox. Chrome is recommended for onsite badge printing stations.
|
||||
- All CRUD operations, event management, journals, IDAA, reports, etc.
|
||||
- No special browser configuration required.
|
||||
|
||||
### 7.2. Electron Native App (Specialized — Pres Mgmt Launcher Only)
|
||||
|
||||
The Electron app (`aether_app_native_electron/`) exists **solely** to support the **Events Presentation Management Launcher**. It provides OS-level capabilities that a browser sandbox cannot:
|
||||
- Control of third-party presentation software (PowerPoint, Keynote, LibreOffice Impress)
|
||||
- Local filesystem access for slide file management
|
||||
- Hardware telemetry for connected devices
|
||||
|
||||
**What Electron is NOT used for:**
|
||||
- Badge printing (browser works fine)
|
||||
- Any other Aether module
|
||||
- Any general-purpose Aether functionality
|
||||
|
||||
The bridge is exposed as `window.aetherNative` (set by Electron's preload script). All code that calls `window.aetherNative` should degrade gracefully when it is `undefined` (i.e., in a normal browser). See: `src/lib/electron/electron_relay.ts`.
|
||||
|
||||
**When to assume Electron is available:** Only inside the `/events/[event_id]/(launcher)/` route group, and only when the page was loaded from the native app.
|
||||
|
||||
## 8. IndexedDB LiveQuery Usage
|
||||
|
||||
- `lq__xyz_obj`: Used for general read-only access to liveQuery results.
|
||||
- `lqw__xyz_obj`: Used for forms and binding values, representing a writable snapshot of liveQuery results.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
**Module Path:** `src/routes/events/[event_id]/(badges)/badges/`
|
||||
**API Module:** `src/lib/ae_events/ae_events__event_badge.ts`
|
||||
**Database:** `db_events.badge` (Dexie IndexedDB table)
|
||||
**Last Updated:** 2026-02-26
|
||||
**Last Updated:** 2026-02-26 (rev 3)
|
||||
|
||||
---
|
||||
|
||||
@@ -208,6 +208,18 @@ editable_badge_type_code: string | null
|
||||
### Search Component
|
||||
**File:** `ae_comp__badge_search.svelte`
|
||||
|
||||
### Multi-Word Search Fix (2026-02-26)
|
||||
Fulltext search now correctly handles multi-word queries by splitting on whitespace and applying AND logic per word:
|
||||
```typescript
|
||||
// "scott idem" → LIKE '%scott%' AND LIKE '%idem%'
|
||||
// Previously: LIKE '%scott idem%' (failed to match)
|
||||
const words = qry.split(/\s+/).filter(w => w.length > 0);
|
||||
for (const word of words) {
|
||||
search_query.and.push({ field: 'default_qry_str', op: 'like', value: `%${word}%` });
|
||||
}
|
||||
```
|
||||
**Committed:** dc0f3066
|
||||
|
||||
### Available Filters
|
||||
|
||||
**Fulltext Search** (All Users)
|
||||
@@ -345,13 +357,34 @@ print_first_datetime: string // ISO datetime of first print
|
||||
print_last_datetime: string // ISO datetime of most recent print
|
||||
```
|
||||
|
||||
### Print Workflow (Future)
|
||||
### Print Button (Implemented 2026-02-26)
|
||||
The `handle_print_badge()` function in `ae_comp__badge_obj_view.svelte` increments the count and records timestamps:
|
||||
```typescript
|
||||
async function handle_print_badge() {
|
||||
const now = new Date().toISOString();
|
||||
const current_print_count = $lq__event_badge_obj.print_count ?? 0;
|
||||
const data_to_update = {
|
||||
print_count: current_print_count + 1,
|
||||
print_last_datetime: now
|
||||
};
|
||||
if (current_print_count === 0) {
|
||||
data_to_update.print_first_datetime = now; // Only set on first print
|
||||
}
|
||||
await events_func.update_ae_obj__event_badge({ ... });
|
||||
}
|
||||
```
|
||||
|
||||
Button has `data-testid="badge-print-btn"` and shows loading/done/error states with icon feedback.
|
||||
|
||||
### Print Workflow
|
||||
1. **Pre-Print:** Check `print_count` to warn if already printed
|
||||
2. **Print:** Send to printer via Electron native bridge or browser print
|
||||
3. **Post-Print:** Increment `print_count`, update `print_last_datetime`
|
||||
2. **Print:** `window.print()` — standard browser print dialog. Works well in Chrome, Chromium, and Firefox. Chrome is the recommended browser for onsite badge printing (most stable in production).
|
||||
3. **Post-Print:** Handled by `handle_print_badge()` — count + timestamps updated
|
||||
4. **Audit:** Print history available for staff review
|
||||
|
||||
**Current Status:** UI placeholder for print button, tracking fields exist in database, print functionality pending.
|
||||
**Browser vs Electron:** Badge printing does NOT require the Electron native app. The standard browser print dialog works well across Chrome, Chromium, and Firefox. The Electron native app is specialized for the **Events Pres Mgmt Launcher only** and should not be assumed available for badge stations.
|
||||
|
||||
**Current Status:** Button records print event and updates IDB. The `window.print()` call still needs to be wired to the button — see Future Enhancements.
|
||||
|
||||
---
|
||||
|
||||
@@ -483,32 +516,61 @@ delete_ae_obj_id__event_badge({ event_badge_id, event_id, method })
|
||||
- **Metadata:** ID, created/updated timestamps (edit mode only)
|
||||
|
||||
**Badge Detail View** (`ae_comp__badge_obj_view.svelte`)
|
||||
- **Edit Mode:** Activated by `#review` URL hash or edit button
|
||||
- **Edit Mode:** Activated by edit button (or `#review` URL hash for future self-service)
|
||||
- **Condition:** Renders only when BOTH `$lq__event_badge_obj` AND `$lq__event_badge_template_obj` are non-null
|
||||
- **Form Binding:** Direct `bind:value` on editable fields
|
||||
- **Dynamic Sizing:** Font size adjusts based on text length
|
||||
- **Print Preview:** Full badge layout with template
|
||||
- **Save Handler:** Only sends changed fields to API
|
||||
- **`data-testid` attributes:** `badge-edit-btn`, `badge-save-btn`, `badge-cancel-btn`, `badge-print-btn`, `badge-professional-title-input` — use these in tests
|
||||
|
||||
---
|
||||
|
||||
## Testing Status
|
||||
|
||||
### Current Test Coverage
|
||||
- ❌ Badge list cold-start (failing — mock API issue)
|
||||
- ❌ Badge data integrity (failing — mock API issue)
|
||||
- ❌ Badge template list (failing — route mismatch)
|
||||
- ✅ Badge list loads (all 6 data integrity tests passing)
|
||||
- ✅ Badge template list loads and displays
|
||||
- ✅ Badge template form renders and populates correctly
|
||||
- ✅ Badge template values persist in edit form
|
||||
- ✅ Electron bridge compatibility (graceful degradation in browser)
|
||||
- ✅ Badge field processor handles missing optional fields
|
||||
- ✅ Badge type filter tests
|
||||
- ✅ Badge template relationship tests
|
||||
- ✅ Electron bridge compatibility (graceful degradation)
|
||||
- ✅ **Attendee workflow test** — navigate → edit professional title → print → return (d1ded2d4)
|
||||
|
||||
### Test Issues
|
||||
**Root Cause:** Mock API routes not matching actual request patterns. Tests provide correct mock data but page shows "No badges found".
|
||||
### Key Test Lessons Learned
|
||||
|
||||
**Browser Error:** `Object is missing a valid ID for table "badge"` — Mock data reaching IDB with only `{tmp_sort_1, tmp_sort_2, event_id}`, all other fields stripped.
|
||||
**Search API path is FLAT, not nested.** `search_ae_obj_v3` builds `/v3/crud/{obj_type}/search` — always flat regardless of the parent relationship. Mocks must match this:
|
||||
```typescript
|
||||
// CORRECT — flat path
|
||||
url.includes('/v3/crud/event_badge/search') && method === 'POST'
|
||||
// WRONG — nested path, mock will never fire
|
||||
url.includes(`/v3/crud/event/${event_id}/event_badge/search`) && method === 'POST'
|
||||
```
|
||||
|
||||
**Fix Required:** Debug actual API request URLs, adjust mock route patterns.
|
||||
**List API (GET) is also FLAT with query params.** `get_ae_obj_li_v3` builds `/v3/crud/{obj_type}/?for_obj_id=...` — always flat. Mocks must check `url.includes('/v3/crud/event_badge_template/') && url.includes('for_obj_id')`.
|
||||
|
||||
**Manual Testing Recommended:** Navigate to `/events/{event_id}/badges` in browser to verify actual functionality before fixing test infrastructure.
|
||||
**CSS `input[value*=...]` selectors don't work with Svelte bind:value.** The CSS selector checks the HTML *attribute*; Svelte's `bind:value` sets the DOM *property* only. In Playwright tests, use `page.getByLabel()` or `locator.inputValue()` instead.
|
||||
|
||||
**Dexie requires `_random` ID fields.** Badge objects saved to IDB must include:
|
||||
```typescript
|
||||
event_badge_id_random: string // Must be present or Dexie skips the object
|
||||
id_random: string // Also checked
|
||||
// Error: "Object is missing a valid ID for table 'badge'"
|
||||
```
|
||||
All API mock responses in tests need these fields.
|
||||
|
||||
**Badge view requires both badge AND template.** `ae_comp__badge_obj_view.svelte` wraps everything in `{#if $lq__event_badge_obj && $lq__event_badge_template_obj}` — if the template isn't loaded, edit/print buttons and the badge itself don't render. Tests must mock the badge template endpoint.
|
||||
|
||||
**Badge GET endpoint (single object):** `/v3/crud/event_badge/{id}` (NOT nested under event). Matches `api.get_ae_obj_v3()` which uses the flat path.
|
||||
|
||||
**Badge PATCH endpoint (update):** `/v3/crud/event/${event_id}/event_badge/${badge_id}` (nested under event). Matches `api.patch_ae_obj_v3()` which uses the nested path.
|
||||
|
||||
**Use `data-testid` for test selectors.** Key buttons have targets: `badge-edit-btn`, `badge-save-btn`, `badge-cancel-btn`, `badge-print-btn`, `badge-professional-title-input`.
|
||||
|
||||
### Remaining Test Issues
|
||||
None — all current badge tests passing as of 2026-02-26 (f5e98b8c).
|
||||
|
||||
---
|
||||
|
||||
@@ -521,7 +583,7 @@ delete_ae_obj_id__event_badge({ event_badge_id, event_id, method })
|
||||
|
||||
### Future Enhancements
|
||||
1. **Access-Based Edit Permissions:** Implement JSON config for field-level access control
|
||||
2. **Print Functionality:** Wire up print button to Electron native print or browser print API
|
||||
2. **Print Functionality:** Wire up `window.print()` to the print button. Standard browser print API — works well in Chrome/Chromium/Firefox for badge label printing. Electron is NOT needed.
|
||||
3. **Batch Operations:** Bulk update, bulk print, bulk export
|
||||
4. **Audit Log:** Track who edited which fields and when
|
||||
5. **Photo Badges:** Support badge photo upload and display
|
||||
@@ -585,5 +647,5 @@ db_events.badge.toArray().then(console.log)
|
||||
---
|
||||
|
||||
**Document Status:** ✅ Complete
|
||||
**Last Verified:** 2026-02-26
|
||||
**Verified Against:** Code commit b28595da (badge data fixes)
|
||||
**Last Verified:** 2026-02-26 (rev 3 — all badge tests passing)
|
||||
**Verified Against:** Code commit f5e98b8c (all data integrity tests passing)
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
## 🚧 Upcoming High Priority
|
||||
- **CRUD v2 Refactor:** Finalize retirement of `Element_ae_crud_v2.svelte` in favor of V3 Editor.
|
||||
- **Temp Cleanup:** Auto-removal of native `.tmp` files older than 24h.
|
||||
- **`window.print()` for badge print button:** Wire the existing `handle_print_badge()` to trigger `window.print()`. Browser print works well across Chrome/Chromium/Firefox — no Electron needed.
|
||||
- **Input Field Audit:** Several input fields are missing `name`/`id` attributes or `data-testid`. Known examples: badge override fields in `ae_comp__badge_obj_view.svelte`; template name input in `ae_comp__badge_template_form.svelte`. Matters for: accessibility, autofill, label associations, and test targeting. (For tests, use `getByLabel()` rather than `input[value*=...]` which only checks the HTML attribute, not the Svelte-bound DOM property.)
|
||||
|
||||
## ✅ Completed Recently
|
||||
- [x] **[API]** **V3 Lookup System Integration:** Implemented standardized `/v3/lookup/` endpoints for Countries, Subdivisions, and Time Zones. Added support for `only_priority` filtering in IDAA editors.
|
||||
@@ -23,3 +25,8 @@
|
||||
- [x] **[API]** Unified all CRUD helpers to standard V3 `/v3/crud/...` paths.
|
||||
- [x] **[Framework]** Implemented `AE_Obj_Field_Editor_V3` with Svelte 5 Runes.
|
||||
- [x] **[IDAA]** Verify Bulletin Board and Recovery Meetings functionality.
|
||||
- [x] **[Badges]** **Multi-word fulltext search fix:** Split query on whitespace, apply AND logic per word. `"scott idem"` now matches records containing both words. (dc0f3066)
|
||||
- [x] **[Badges]** **Print button implemented:** `handle_print_badge()` increments `print_count`, records `print_first_datetime`/`print_last_datetime`. Button has loading/done/error states. (d1ded2d4)
|
||||
- [x] **[Badges]** **`data-testid` attributes added** to badge view interactive elements (`badge-edit-btn`, `badge-save-btn`, `badge-cancel-btn`, `badge-print-btn`, `badge-professional-title-input`) for reliable test targeting.
|
||||
- [x] **[Tests]** **Attendee badge workflow test passing:** `event_badge_attendee_workflow.test.ts` — navigate → edit professional title → save (verify PATCH body) → print (verify count/timestamps) → return to search. (d1ded2d4)
|
||||
- [x] **[Tests]** **All badge data integrity tests fixed:** All 6 tests in `event_badge_data_integrity.test.ts` now pass. Root causes: (1) search mock used nested URL instead of flat `/v3/crud/event_badge/search`, (2) template list mock used nested URL instead of flat with `for_obj_id`, (3) missing `_random` ID fields in mock badge objects, (4) CSS `input[value*=...]` selector doesn’t work for Svelte-bound inputs — fixed to `getByLabel()`. (f5e98b8c)
|
||||
|
||||
Reference in New Issue
Block a user