- Email template: an event can use an editable campaign-style template (Unlayer) for
its invitation instead of the built-in festive builder. Config field email_template
('' = festive default/fallback). inviteEmail() renders the named template via
campaigns.renderNamedTemplate with {{firstname}}/{{rsvp_url}} (+ event vars), else
festive. campaigns.js: add 'event-' template prefix + export renderNamedTemplate.
New GET /events/:id/invite-preview (festive | configured | override) for live preview.
Editor gains a template selector, "design in editor" link, and an inbox preview dialog.
- Audience "Tous (incl. résiliés)": filters.include_resiliated skips the résilié guard
for win-back; "Clients actifs" still excludes them.
- Manual picker: realtime fuzzy search into a results list (add per row), separate pool,
then add-batch — replaces the combobox.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ops event page overhaul (hub lib/events.js + email.js, ops EventsPage.vue + api):
- Create/edit/delete events (persisted config shadowing the seeded SEED_CONTENT);
labels factored into shared LABELS, content editable bilingual (EN falls back to FR).
- Capacity cap by headcount: public RSVP form closes with a "booking is full" message
when reached (server-enforced); existing registrants can still update.
- Email attachments (image/PDF, <=4MB, <=6), tagged per language (fr/en/both) so each
customer gets files in their account language; optional Gemini auto-detect on images.
email.sendEmail gains a generic attachments[] param.
- Additive main audience list (persisted per event): build one deduped list by appending
batches from filters, manual picks, or CSV; per-source breakdown, remove/clear.
- Filters: name-contains (customer_name like) and city (Service Location.city, resolved
accent/case-insensitively via PG with REST fallback), intersected with other criteria.
- Manual picker + fuzzy search reuse app-wide /collab/customer-search (pg_trgm), so
"repa" finds "Réparation …".
- nginx /hub/ proxy: client_max_body_size 8m for base64 attachment uploads.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>