feat(leads): allow_tracking gate + icon bug fix + docs update

- QR scanner: after badge loads, blocks add with 'Tracking Opt-Out' warning
  card if allow_tracking !== true; replaced deprecated CheckCircle → CircleCheck
- Manual search: shows ShieldOff 'Opt-Out' label per row for blocked badges;
  add_as_lead() also guards against programmatic bypass
- Fix: ae_comp__exhibit_tracking_obj_li — Loader2 from wrong package
  @lucide/svelte → LoaderCircle from lucide-svelte
- ae_types.ts: added allow_tracking and agree_to_tc to ae_EventBadge interface
- README.md (leads): full rewrite reflecting actual current state and known gaps
- TODO__Agents.md: updated Leads entry from stale 'NEXT MAJOR FEATURE' to
  accurate in-progress status with remaining checklist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-03-16 15:59:26 -04:00
parent b8104b3ff2
commit be24cfdeb5
6 changed files with 203 additions and 79 deletions

View File

@@ -5,14 +5,12 @@
## 🚧 Upcoming High Priority
### [Stores] Refactor — ae_stores.ts and ae_events_stores.ts cleanup
Both files have grown organically and are messy. Refactor goals:
- Split into focused files per domain (core, user/auth, files, module-specific)
- Remove dead/commented-out code and stale `ver`/`ver_idb` constants from data structs (replaced by `__version` in store_versions.ts)
- Standardize field naming conventions
- Move sponsorships/stripe Stripe button IDs out of session store and into config
- Keep `ae_stores.ts` and `ae_events_stores.ts` as barrel re-exports for backwards compatibility
Related: `src/lib/stores/store_versions.ts` is the new home for version constants.
### [Stores] Refactor — Phase 2c (deferred)
Phases 1, 2a, 2b are complete (see ✅ Completed below). One phase remaining:
- [ ] **Phase 2c — Actual separate stores (`ae_auth`, `ae_app`):** Requires touching ~471
`$ae_loc.*` auth-field read sites across 150+ files. Deferred until a Svelte runes migration
of the store layer itself (touching every component anyway makes the callsite sweep cheap).
### [Backend] Join event_location_id onto event_presenter API view
The `event_presenter` object currently has `event_session_id` but not `event_location_id`.
@@ -57,11 +55,34 @@ for the full checklist and prep plan.
- [ ] **Test data set:** include edge cases — very long name, HTML markup in name/affiliations,
badge with no affiliations, badge with all ticket/option codes set.
### [Leads] Exhibitor Lead Scanning — NEXT MAJOR FEATURE
QR code scan at exhibitor booth → capture attendee badge data. Gated by `allow_tracking` on
the badge. Check if `documentation/MODULE__AE_Events_Leads.md` exists for full spec.
Key questions before starting: which routes, does the Electron app scan, what does the
lead record look like in the DB?
### [Leads] Exhibitor Lead Scanning — IN PROGRESS (demo-ready prep)
Module is substantially built as a PWA (no Electron). Core flow works end-to-end.
Spec: `documentation/PROJECT__AE_Events_Exhibitor_Leads_v3.md` and `_detail.md`.
Full audit: `src/routes/events/[event_id]/(leads)/` and `src/lib/ae_events/ae_events__exhibit*.ts`.
**What's working:**
- Exhibit search/landing (`/leads/`) — SWR, local + API search, sort
- Exhibit detail page — 4-tab layout, sticky header with Add/List toggle, auto-refresh timer
- Tab 1 (Start): sign-in via shared passcode OR licensed user (email + passcode)
- Tab 2 (Add): QR scan (rapid vs. qualify mode) + manual badge search; duplicate detection on both
- Tab 3 (List): SWR lead list, licensee filter (All / My Leads), sort options, export button
- Tab 4 (Manage): admin tools, booth profile edit, passcode, license mgmt, custom questions config, app settings (refresh interval, clear IDB/localStorage, reload)
- Lead detail page: view/edit custom question responses, exhibitor notes (TipTap), priority/enable flags
- Export wired to legacy `/event/exhibit/{id}/tracking/export` endpoint (CSV; confirm backend is live)
**Remaining before demo:**
- [ ] **Verify export endpoint**`download_export__event_exhibit_tracking` calls legacy endpoint
`/event/exhibit/{exhibit_id}/tracking/export` — confirm it's live on the backend
- [x] **`allow_tracking` gate** — implemented (2026-03-16). QR scanner shows a warning card and
blocks the add. Manual search shows a ShieldOff "Opt-Out" badge per row and guards `add_as_lead`.
Opt-in model: `allow_tracking` must be explicitly `true` on the badge. Also added `allow_tracking`
and `agree_to_tc` to `ae_EventBadge` in `ae_types.ts`.
**Demo note:** ensure test badges have `allow_tracking = true` or no one can be added.
- [ ] **Payment component**`ae_comp__exhibit_payment.svelte` is a stub (Stripe placeholder only);
omit from demo or hide the payment tab via "Show Payment Tab" toggle in Manage settings
- [ ] **End-to-end smoke test** — sign in with shared passcode, scan/search a badge, add a lead,
view detail, add notes/responses, export CSV; verify on mobile (Chrome/Safari PWA)
- [ ] **Install prompt** — spec calls for a PWA install nudge on the Start tab; not yet added
### [DevOps] Remaining deployment items
- [x] **Wire AE_APP_REPLICAS:** `docker-compose.yml` line 147 already has `scale: ${AE_APP_REPLICAS:-1}`. (verified 2026-03-11)
@@ -75,6 +96,9 @@ lead record look like in the DB?
- **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 (2026-03)
- [x] **[Stores] Phase 1 — Dead code cleanup** (`ae_stores.ts`, `ae_events_stores.ts`, `ae_idaa_stores.ts`): removed `ver_idb`, stale comments, `console.log` lines, Stripe button block (zero consumers), personal Novi UUIDs, dead alternatives. Net: 202 lines across 3 files. svelte-check: 0 errors. (2026-03-16)
- [x] **[Stores] Phase 2a — Split defaults into domain sub-files**: `ae_stores__auth_loc_defaults.ts`; `ae_events_stores__badges/launcher/leads/pres_mgmt_defaults.ts`. Spread-merged back into store structs — zero consumer changes. (2026-03-16)
- [x] **[Stores] Phase 2b — TypeScript interfaces for defaults sub-files**: `SiteCfgJson`, `AePerson`, `AeUser`, `AccessType`, `AuthLocState`; `BadgesLocState/SessState`; `SectionState`, `LauncherLocState/SessState`; `LeadsLocState/SessState`, `TmpLicense`; `PresMgmtLocState/SessState`. svelte-check: 0 errors. (2026-03-16)
- [x] **[UI]** Style Review Phase 1 & 2 complete — all non-frozen, non-IDAA routes migrated: FA→Lucide (events, pres_mgmt, core, badges, leads, hosted_files), `variant-*``preset-*` (all modules), `code_to_html` badge dict refactored to Lucide component map, FA CDN scoped to IDAA layout, global `svg.lucide { display: inline }` CSS rule added to fix icon inline flow. See `documentation/PROJECT__AE_Style_Review.md`. (2026-03-16)
- [x] **[UI]** Pres Mgmt Phase 3 — FA→Lucide icon migration across all 24 pres_mgmt files. (2026-03-16)
- [x] **[IDAA]** `ae_idaa_comp__event_obj_id_edit.svelte` — inlined Tailwind utilities, removed `<style>` block; eliminated all 23 `@apply`/`@reference` svelte-check warnings. (2026-03-16)