v35.0
The-Vibe-Company/megaparsev35.0Jul 8, 2026by pierre-b
AI Summary
This release focuses on performance optimizations for email rendering and AI features, alongside stability fixes for automation workflows and database reliability. It introduces per-link click tracking for broadcasts and improves the handling of concurrent template edits.
Key Highlights
- Broadcast reports now show per-link click breakdowns with total and unique clicker counts, stored in a new database column.
- Email rendering is significantly faster (~3x) by reusing Liquid engine pools and compiling regexes once.
- The AI Email Designer now offers better reliability with reasoning models, including streaming thinking and MJML error display.
- Template editors now prevent silent overwrites by rejecting saves based on stale revisions with a 409 Conflict error.
- The console's echarts dependency was updated to version 6.1.0 to resolve a cross-site scripting (XSS) vulnerability.
New Features
- Per-link click breakdown in broadcast reports with UTM parameter support.
- Template search functionality by name on the templates list.
- AI Email Designer improvements for reasoning models (DeepSeek, OpenAI) including streaming and error handling.
- Tri-state tracking mode for transactional notifications (inherit/disabled).
Full Release Notes
- **Feature**: Broadcast reports now show a per-link click breakdown — total clicks and unique clickers per destination URL (UTM parameters kept, since they are commonly used to tell links apart). Clicks are recorded per URL in a new `message_history.clicked_links` JSONB column added by workspace migration v35; recording starts immediately after the upgrade, including for emails already sent (the destination URL is embedded in their tracking tokens), so the breakdown only covers post-upgrade clicks and legacy `/visit` links remain aggregate-only (#339, #311).
- **Feature**: Search templates by name on the templates list — a debounced name search beside the category filter, persisted in the URL, mirroring the broadcasts search (the already-loaded list is filtered client-side).
<img width="1160" height="743" alt="Capture d’écran 2026-07-08 à 11 40 58" src="https://github.com/user-attachments/assets/402c9329-cfba-41b1-bf15-2e7d9f42d171" />
- **Improvement**: Faster email rendering — Liquid engines are now reused across blocks via a pool instead of being rebuilt for every block, and constant regexes are compiled once, cutting per-block Liquid processing time by ~3× (~8× under concurrent sends) during broadcasts (#381).
- **Improvement**: AI Email Designer reliability with reasoning models (e.g. DeepSeek) — thinking now streams into a collapsible panel, the preview refreshes immediately after AI edits, a generated email that doesn't compile surfaces the MJML error instead of silently looking successful, hitting the token limit shows a non-destructive warning instead of wiping the answer, and OpenAI-compatible integrations gain a reasoning-effort selector (#363).
- **Fix**: The contacts multi-select no longer gets out of sync when deleting via the row's ⋯ menu — clicking a dropdown item invisibly toggled the row's selection (the click bubbles through the React portal to the row's select-on-click handler), and a deleted contact was never removed from the selection, leaving a phantom "N contacts selected" bar whose stale emails a later bulk *Add to list* would even re-create via upsert (#374).
- **Fix**: One-time authentication emails (the built-in Supabase notifications: magic link, signup confirmation, invite, recovery, email change) are no longer rewritten through the click-tracking redirect — their links previously depended on the API being up and could be consumed by mailbox link scanners before the user clicked. Transactional notifications gain a tri-state `tracking_mode` (inherit the workspace setting, or disabled — which also suppresses UTM rewriting); an absent field on update keeps the stored value so partial edits cannot wipe an opt-out, and migration v35 sets `disabled` on existing Supabase notifications.
- **Fix**: A/B-test broadcasts no longer attribute most recipients' link clicks and `{{ utm_content }}` values to the wrong variant. When no explicit `utm_content` was set, the first processed recipient's template ID was written back onto the shared broadcast object and frozen for every later recipient — and in batch sends the template data even lagged one recipient behind the rewritten links. `utm_content` is now computed per recipient from the variant actually chosen for them, and `utm_term` is applied consistently across both send paths.
- **Fix**: The automation *Add to List* node no longer fails silently. Its "Subscribed" option stored an invalid `subscribed` status that the backend rejected (only `active`/`pending` are valid), so contact journeys stalled at that node with no visible error. The editor now stores `active`, node configurations are validated when the automation is saved so an invalid status is caught immediately, and a data migration repairs existing automations, contact lists, and timeline entries that still carry `subscribed` (#376).
- **Improvement**: Concurrent template edits no longer silently overwrite each other. Template saves were last-writer-wins, so a save based on a stale revision clobbered newer changes. The editor now sends the revision it was based on and the server rejects a stale-base save with `409 Conflict`, prompting to reload the latest or overwrite. Covers the email template, blog post, and transactional-notification editors (#378).
- **Security**: Bumped the console's `echarts` dependency to 6.1.0 to resolve a cross-site scripting (XSS) advisory (GHSA-fgmj-fm8m-jvvx) flagged by Dependabot.
- **Fix**: Resolved intermittent `pq: password authentication failed` / "failed to get workspace connection" errors under load. The workspace connection manager health-check-pinged the cached pool on every query and evicted, closed, and rebuilt it (re-hitting the `postgres` admin database) on any slow ping or transient blip; it now reuses cached pools and creates them without a global lock (#380).
- **Fix**: Adding a contact (or adding a contact to a list from the details drawer) now refreshes the contacts list immediately instead of requiring a hard page reload. The "Add" contact drawer never invalidated the React Query cache on success, and the "add to list" action only refreshed the contact details — both now invalidate the contacts list (and total count) so the new contact appears right away (#364).