gigafibre-fsm/services/targo-hub/lib
louispaulb d897bcedb4 feat(campaigns): auto-clean first/last names (QC accents + compound split)
The Map CSV migrated from the legacy ERP carries names with two common
defects: missing French accents (Stephane, Andre, Frederic), and
compound first names that were typed without a separator (Marcandre,
Mariejosee, Jeanphilippe). Sending an email "Bonjour stephane," instead
of "Bonjour Stéphane," reads as sloppy automation. Fix both at parse
time so the user sees the corrected names in Step 2 and can override
inline if the auto-cleaner got it wrong.

Backend (lib/campaigns.js):

- FR_NAME_FIXES — 100+ entry dictionary mapping lowercase no-accent
  Québec first names to their canonical accented form (André, Stéphane,
  Frédéric, Geneviève, Hélène, Joséée, etc.). Sourced from MIQ baby
  names + older-generation curation.

- COMPOUND_PARTS — list of common name parts (jean, marie, anne, marc,
  philippe, françois, etc.) that combine into QC compound first names.
  When two parts appear concatenated with no separator, the cleaner
  splits and hyphenates them. Example: "Marcandre" → ["marc","andre"]
  → "Marc-André" (dictionary then applies accent).

- titleCaseToken — proper Title Case respecting apostrophes (O'Brien,
  L'Heureux) and hyphens (Marie-Ève). Uses \p{L} Unicode class so it
  works on accented chars correctly.

- cleanName(raw) — full pipeline: trim → Title Case → dictionary
  lookup per word → compound split fallback. Applied to firstname AND
  lastname in parseMapCsv.

- nameWarning(name) — heuristic flag for cases the cleaner couldn't
  confidently handle: digit in name, single letter, abnormally long
  without separator (likely two stuck names not in COMPOUND_PARTS).
  Returns a short FR description for the UI tooltip.

- parseMapCsv now returns firstname/lastname (cleaned) + firstname_raw/
  lastname_raw (original from CSV) + cleaned_changed bool + name_warnings
  per recipient. UI uses these to show before/after + flags.

UI (CampaignNewPage Step 2):

- New counter card "Noms à vérifier" — count of recipients with at least
  one nameWarning. Only renders if > 0.

- Info banner above the recipients table:
  "X nom(s) auto-corrigés (...)  Y nom(s) suspects (...)"

- Per-row icons in the firstname + lastname columns:
  • ⚠ amber WARNING — cleaner flagged this name as suspicious
    (tooltip shows the reason: "deux prénoms collés", "contient un
    chiffre", etc.)
  •  green AUTO_FIX_HIGH — auto-cleaner changed something at parse
    time (tooltip shows the original raw value)
  Both icons are tooltip-only — no action required.

- Click any name cell → q-popup-edit opens an inline input. Type the
  correction, Enter saves. ESC cancels. This is the manual override
  path for any name the auto-cleaner mishandled.

Tests (manual via end-to-end smoke against prod):
  STEPHANE TREMBLAY     → Stéphane Tremblay     ✓ accent + Title Case
  marie tremblay        → Marie Tremblay        ✓ Title Case only
  Marcandre Boileau     → Marc-André Boileau    ✓ compound + accent
  Jean Francois Lebrun  → Jean François Lebrun  ✓ accent only
  Mariejosee Lapierre   → Marie-Josée Lapierre  ✓ compound + double accent
  Andre LAPRISE         → André Laprise         ✓ both fixed
  Helene St-Pierre      → Hélène St-Pierre      ✓ accent, hyphen preserved
  Frederic O'Brien      → Frédéric O'Brien      ✓ accent, apostrophe preserved

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 21:33:10 -04:00
..
ui refactor(targo-hub): extract ui/ kit, migrate tech-mobile to it 2026-04-22 22:47:19 -04:00
acceptance.js refactor(targo-hub): add types.js, migrate acceptance+payments, drop apps/field 2026-04-22 23:18:25 -04:00
address-search.js refactor: extract composables from 5 largest files — net -1950 lines from main components 2026-04-08 17:57:24 -04:00
address-validate.js fix(ops/dispatch): /desk/<DocType>/ broken URL → /app/<slug>/ + add /address/validate hub 2026-05-08 11:01:32 -04:00
agent-flows.json refactor: major cleanup — remove dead dispatch app, commit all backend code, extract client composables 2026-04-08 17:38:38 -04:00
agent-tools.json refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
agent.js refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
ai.js refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
auth.js feat(hub+ops): user invite flow sends temp password via Mailjet + dev .env.example 2026-05-05 19:50:06 -04:00
campaigns.js feat(campaigns): auto-clean first/last names (QC accents + compound split) 2026-05-21 21:33:10 -04:00
checkout.js feat: contract → chain → subscription → prorated invoice lifecycle + tech group claim 2026-04-22 20:40:54 -04:00
config.js feat: flow editor, Gemini QR scanner with offline queue, dispatch planning v2 2026-04-22 10:44:17 -04:00
contracts.js fix(chain+subs): safe job-delete, plan_name from Quotation, bi-dir sub link 2026-04-23 10:19:56 -04:00
conversation.js refactor(targo-hub): add erp.js wrapper + migrate 7 lib files to it 2026-04-22 23:01:27 -04:00
device-extractors.js feat: flow editor, Gemini QR scanner with offline queue, dispatch planning v2 2026-04-22 10:44:17 -04:00
device-hosts.js refactor: major cleanup — remove dead dispatch app, commit all backend code, extract client composables 2026-04-08 17:38:38 -04:00
devices.js feat: contract → chain → subscription → prorated invoice lifecycle + tech group claim 2026-04-22 20:40:54 -04:00
dispatch.js fix(chain+subs): safe job-delete, plan_name from Quotation, bi-dir sub link 2026-04-23 10:19:56 -04:00
email-templates.js refactor: extract composables from 5 largest files — net -1950 lines from main components 2026-04-08 17:57:24 -04:00
email.js feat(hub): gift-campaign module — CSV parse, customer match, async send + webhook 2026-05-21 19:07:40 -04:00
erp.js refactor(targo-hub): add erp.js wrapper + migrate 7 lib files to it 2026-04-22 23:01:27 -04:00
flow-api.js feat: flow editor, Gemini QR scanner with offline queue, dispatch planning v2 2026-04-22 10:44:17 -04:00
flow-runtime.js docs: reorganize into architecture/features/reference/archive folders 2026-04-22 11:51:33 -04:00
flow-templates.js feat: flow editor, Gemini QR scanner with offline queue, dispatch planning v2 2026-04-22 10:44:17 -04:00
helpers.js feat: flow editor, Gemini QR scanner with offline queue, dispatch planning v2 2026-04-22 10:44:17 -04:00
ical.js refactor(targo-hub): add erp.js wrapper + migrate 7 lib files to it 2026-04-22 23:01:27 -04:00
magic-link.js refactor(targo-hub): add erp.js wrapper + migrate 7 lib files to it 2026-04-22 23:01:27 -04:00
modem-bridge.js feat: flow editor, Gemini QR scanner with offline queue, dispatch planning v2 2026-04-22 10:44:17 -04:00
network-intel.js refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
oktopus-mqtt.js refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
oktopus.js feat: flow editor, Gemini QR scanner with offline queue, dispatch planning v2 2026-04-22 10:44:17 -04:00
olt-snmp.js feat: contract → chain → subscription → prorated invoice lifecycle + tech group claim 2026-04-22 20:40:54 -04:00
otp.js refactor(targo-hub): add erp.js wrapper + migrate 7 lib files to it 2026-04-22 23:01:27 -04:00
outage-monitor.js refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
payments.js refactor(targo-hub): add types.js, migrate acceptance+payments, drop apps/field 2026-04-22 23:18:25 -04:00
pbx.js refactor: major cleanup — remove dead dispatch app, commit all backend code, extract client composables 2026-04-08 17:38:38 -04:00
poller-control.js feat: contract → chain → subscription → prorated invoice lifecycle + tech group claim 2026-04-22 20:40:54 -04:00
portal-auth.js feat(portal): passwordless magic-link login — retire ERPNext /login 2026-04-22 13:25:28 -04:00
project-templates.js fix(contracts): create pending Service Subscription on signing + test templates 2026-04-23 10:03:49 -04:00
provision.js chore(hub): gate Oktopus integration behind OKTOPUS_DISABLED flag 2026-05-04 10:34:36 -04:00
referral.js refactor(targo-hub): add erp.js wrapper + migrate 7 lib files to it 2026-04-22 23:01:27 -04:00
reports.js refactor: reduce token count, DRY code, consolidate docs 2026-04-13 08:39:58 -04:00
sse.js refactor: major cleanup — remove dead dispatch app, commit all backend code, extract client composables 2026-04-08 17:38:38 -04:00
tech-absence-sms.js refactor(targo-hub): add erp.js wrapper + migrate 7 lib files to it 2026-04-22 23:01:27 -04:00
tech-mobile.js refactor(targo-hub): add types.js, migrate acceptance+payments, drop apps/field 2026-04-22 23:18:25 -04:00
telephony.js refactor: major cleanup — remove dead dispatch app, commit all backend code, extract client composables 2026-04-08 17:38:38 -04:00
traccar.js feat: flow editor, Gemini QR scanner with offline queue, dispatch planning v2 2026-04-22 10:44:17 -04:00
twilio.js refactor: major cleanup — remove dead dispatch app, commit all backend code, extract client composables 2026-04-08 17:38:38 -04:00
types.js refactor(targo-hub): add types.js, migrate acceptance+payments, drop apps/field 2026-04-22 23:18:25 -04:00
vision.js feat(tech-mobile): SPA redesign with tabs, detail view, notes, photos, field-scan 2026-04-22 22:19:00 -04:00
voice-agent.js refactor: major cleanup — remove dead dispatch app, commit all backend code, extract client composables 2026-04-08 17:38:38 -04:00