diff --git a/documentation/PROJECT__AE_Events_Badges_Review_Print.md b/documentation/PROJECT__AE_Events_Badges_Review_Print.md index f744b40d..dec3f813 100644 --- a/documentation/PROJECT__AE_Events_Badges_Review_Print.md +++ b/documentation/PROJECT__AE_Events_Badges_Review_Print.md @@ -1,7 +1,7 @@ # PROJECT: AE Events Badges — Review Form & Print Font Controls **Created:** 2026-02-27 -**Last Updated:** 2026-03-02 +**Last Updated:** 2026-03-12 **Branch:** `ae_app_3x_llm` **Priority:** HIGH — first live event is Axonius, NYC, mid-April 2026 **Owner:** Scott Idem / One Sky IT @@ -9,9 +9,72 @@ --- +## Design Intent — Two Complementary Flows + +### Flow 1: Remote Badge Review (email link) +- Staff emails a review link to the attendee before the event. +- Attendee opens the link on their own device, reviews their badge info, and edits permitted fields. +- **Email address rule:** Always send to `event_badge.email` — never `email_override`. + `email_override` is a display/badge field only. It cannot be trusted as a delivery address + (attendee may have changed it to something different for badge display purposes). +- Component: `ae_comp__badge_review_form.svelte` — plain form, no badge render. +- Route: `/events/[event_id]/badges/[badge_id]/review/` + +### Flow 2: Kiosk / Onsite Badge Station (print page) +- Hardware: a laptop + badge printer (Epson fanfold or Zebra PVC card) at the check-in table. +- At the event, an attendee walks up to a badge station (check-in kiosk). +- A staff member or volunteer pulls up the attendee's badge on the print page. +- The **print page is a kiosk tool**, not just a print queue: + - Attendee reviews their badge info and can edit permitted fields **in real time**, + with the live badge render updating as they make changes. + - Staff/volunteers are present to assist with any questions. + - Once satisfied, staff prints the badge. +- The key differentiator vs the review form: **the live badge render** shows exactly how + the badge will print. Attendees and staff can see changes immediately. +- Component: `ae_comp__badge_obj_view.svelte` / `ae_comp__badge_obj_view_v2.svelte` +- Route: `/events/[event_id]/badges/[badge_id]/print/` + +### Permission Model — Same Logic, Both Flows +Both flows should respect the same permission model: +- **Attendee-level** (basic Authenticated access): can edit `pronouns_override`, + `full_name_override`, `professional_title_override`, `affiliations_override`, + `location_override`, `phone_override`, `email_override`, `allow_tracking`, `agree_to_tc`. +- **Staff-level** (trusted_access+): all attendee fields + `email`, `badge_type_code_override`, + `badge_type_override`, `hide`, `priority`, `notes`, and font size controls. +- Permissions are configured per-event in `event.mod_badges_json.edit_permissions`. + Hardcoded defaults are used until that config is implemented. + +**Current gap (TASK 4):** The print page edit button is currently gated to trusted_access only. +It needs to be accessible to attendees at the kiosk (with appropriate field-level gating), +matching the permission model already implemented in `ae_comp__badge_review_form.svelte`. + +--- + ## Next Up for Badges (TASK 4) -### 1. QR Code on Badge Front — `ae_comp__badge_obj_view.svelte` +### 0. Kiosk Editing — Print Page Permission Model Alignment +**This is the most important gap before the first live event.** + +Currently the print page edit button is staff-only (trusted_access gate). At the kiosk, +attendees need to be able to edit their own fields (same attendee-level permissions as the +review form), with staff-only fields gated appropriately. + +Work needed: +- Wire the same `can_edit_fields` / `can_edit(field)` permission logic into the print page + that `ae_comp__badge_review_form.svelte` already uses. +- The edit panel on the print page should show attendee-editable fields to all authenticated + users, and staff-only fields to trusted_access+. +- The badge render (v1 or v2) should update live as the attendee edits fields. +- Consider whether the print page needs its own inline edit panel (sidebar or overlay) + or whether it should share/reuse the review form component alongside the badge render. +- **Do NOT use `email_override` as the send-to address** — always use `event_badge.email`. + +### 1. Auto-Scaling Badge Text (v2) — In Progress +`ae_comp__badge_obj_view_v2.svelte` using `element_fit_text.svelte` (binary search auto-scale). +Toggle between v1 (heuristic) and v2 (auto-scale) on the print page via the `v1`/`v2` header button. +Heights tuned per layout in `fit_heights` derived object. Still needs visual tuning with real badges. + +### 2. QR Code on Badge Front — `ae_comp__badge_obj_view.svelte` The badge template has a `show_qr` flag (or similar). When toggled on, the QR code should appear on the front face of the printed badge. Currently QR is only shown on the review form. @@ -30,18 +93,38 @@ appear on the front face of the printed badge. Currently QR is only shown on the - Must be hidden on `ae_comp__badge_obj_view.svelte` when `show_qr` is falsy. ### 2. Badge Print Controls — UX Improvements (ae_comp__badge_print_controls.svelte) -- Scott has identified areas for improvement — TBD next session - Consider: keyboard shortcuts (+ / -) for font sizing while a field is active - Consider: "Apply to all badges" workflow for font size presets -### 3. Leads Module +### 4. Leads Module Next major work after badge polish. See `documentation/MODULE__AE_Events_Leads.md` (if it -exists) for context. Exhibitor lead scanning via QR code. +exists) for context. Exhibitor lead scanning via QR code at exhibitor booth → capture attendee +badge data, gated by `allow_tracking` on the badge. --- ## Implementation Status +### ⏳ TASK 4.0: Kiosk Editing — NOT STARTED (2026-03-12) +Print page edit access needs to be opened to attendee-level permissions, not just trusted_access. +The permission model, field list, and `can_edit()` helper from `ae_comp__badge_review_form.svelte` +should be the reference. See Design Intent section above. + +### ⏳ TASK 4.1: Auto-Scaling Badge Text v2 — IN PROGRESS (2026-03-12) +**Files created:** +- `src/lib/elements/action_fit_text.ts` — Svelte action: binary-search font scaling with + MutationObserver + ResizeObserver + requestAnimationFrame. +- `src/lib/elements/element_fit_text.svelte` — Component wrapper. Key prop: `height` (required + for binary search to work — without it, offsetHeight == scrollHeight always). +- `src/routes/events/.../ae_comp__badge_obj_view_v2.svelte` — V2 badge render using + Element_fit_text for name/title/affiliations/location in display mode. + `fit_heights` derived object provides layout-aware heights per field per badge layout. + `font_size_*` props default to `undefined` (auto-scale) rather than numeric defaults (v1 behavior). + Manual overrides from print controls still work — any number disables auto-scale for that field. + +**Toggle:** `v1`/`v2` button in print page header. V1 preserved as fallback. +**Status:** Working — heights in `fit_heights` still need visual tuning with real badge stock. + ### ✅ TASK 3: Badge Print Controls Panel — COMPLETE (2026-03-02) **Files created/modified:** diff --git a/documentation/TODO__Agents.md b/documentation/TODO__Agents.md index 16cf9d4b..bea8af95 100644 --- a/documentation/TODO__Agents.md +++ b/documentation/TODO__Agents.md @@ -2,8 +2,6 @@ > Use this file to track steps for complex features or bug fixes. > **Status:** � Stable — ongoing development. -## 📋 Open: Security -- [x] **PUBLIC_AE_API_SECRET_KEY Audit:** Completed 2026-03-11. Key is `PUBLIC_*` by design (always in client bundle). Highest-risk anonymous path now uses limited-permission `PUBLIC_AE_BOOTSTRAP_KEY`. Full server-side migration would require a major API proxy refactor — not justified given JWT + account_id auth layers. `manifest.webmanifest/+server.ts` is a minor cleanup candidate (could use bootstrap key instead), but no security urgency. Current state is acceptable. ## 🚧 Upcoming High Priority @@ -46,27 +44,10 @@ lead record look like in the DB? - **`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.) -### [UX] Session Expired & Access Denied (identified 2026-03-10) - -Two related UX gaps to handle together: - -**1. Session Expired banner (API 401/403 mid-session):** -- `flag_expired` in root `+layout.svelte` is declared but never set — it was always intended for this -- Add a small writable store or custom event (e.g., `ae_auth_error` in `ae_stores`) that API helpers (`api_get_object.ts`, `api_post_object.ts`, `api_patch_object.ts`) can fire when they get a 401 or 403 -- Root layout watches the store and sets `flag_expired = true` -- Render a non-blocking dismissible banner (not full-screen): "Session expired. Please sign in again." with a link to the sign-in control -- Especially relevant for Launcher (event staff on tablets may not notice silent failures) - -**2. Standardize Access Denied UI (non-IDAA routes only — IDAA layout is intentionally custom):** -- Currently inconsistent across the app: - - Root layout: full-screen `flag_denied` (site access key gate — keep this, it's correct) - - `/core` layout: silent redirect to home — should show a brief message instead - - `/events/[event_id]/settings`: inline raw text string — should use a consistent banner component - - `/events/.../badges/.../review`: inline `
+ Show list of fields that they can edit here. This may + need to broken down in to sections that can be + collapsed. +
++ This was allowed at the time your badge was printed. + You may opt-out at anytime. +
++ By allowing this QR code to be + scanned by an exhibitor or + staff, you understand and agree + that they may use your personal + information. +
+ {:else} ++ Tracking was not allowed at the time your badge was + printed. You may opt-in at anytime. +
++ If this QR code is scanned by an + exhibitor or staff, they will not have access to your information. +
+ {/if} +
+ {JSON.stringify($lq__event_badge_obj, null, 2)}
+
+
+
+ {JSON.stringify($lq__event_badge_template_obj, null, 2)}
+
+