Newsletter status: Draft — pending screenshots. See
README.mdfor conversion guide. Screenshots needed: see<!-- TODO -->placeholders below.
v2603.30.0 — March 30, 2026
MRs: !1945, !1944, !1942, !1941, !1939, !1938, !1937, !1936, !1935
Highlights
Schedule loads 10× faster for large franchises (!1945, !1942)
The month view for zones like YMM was taking 13+ seconds to load. We rewrote the core database queries — flipping the traversal order so Neo4j starts from the zone and finds its events directly, rather than scanning every event in the system. Combined with fixing a ~10s Redis cache write that was serialising tens of megabytes of event data, and a CPU bottleneck in availability calculations, the same view now loads in ~1 second.
Pacing vs last year — now works on future dates (!1945)
The ”% vs LY” badge on future day cards was showing 0% even when last year had data. Future dates now show a projected performance figure (projected revenue ÷ LY Final). Projections are also floored at the revenue already on the books — the forecast can never show less than what’s already confirmed.
Copy pacing breakdown to Google Sheets (!1945)
Click the copy icon on the Pacing strip in the month view to export a Google Sheets-compatible table with Current, Projected Final, LY Today, LY Final, and Performance for every day in the month.
Performance
- Fix 10s+ Redis SET latency on
availabilityV2.list— was serialising full CalendarEvent objects (tens of MB for large zones) to Redis; now uses a slim projection with only the fields needed for conflict checking (!1942, !1945, references issue #5921) - Pre-index availability conflict events by truck/user ID before the inner loop — eliminated O(trucks × days × events) CPU work that was causing ~10s of synchronous processing on large zones (!1945)
- Flip Neo4j query traversal in
find.viewDatesfrom Event→Zone to Zone→Event — Neo4j now starts from the known zone node and traverses directly to its events instead of scanning all events in the time window (!1945) - Skip the expensive franchise zone path traversal in
fetchResourceswhenincludeEvents=false(the default for month view) (!1945) - Add
SizeGuardedRedisCacher— globally skips Redis SET when the serialised payload exceeds 512 KiB, preventing any future action from re-introducing multi-second cache write latency (!1942)
Features
- Copy pacing data to clipboard in Google Sheets TSV format — monthly summary + per-day breakdown with Current, Projected Final, LY Today, LY Final, Performance (!1945)
- Pacing % vs LY now shown on future dates using projected revenue ÷ LY Final denominator (!1945)
- Projection floor: future day projections never go below already-booked revenue (!1945)
- Location details: add “Access Notes” field back to New Opportunity v3 (!1944, closes #5936)
- Location details: unit number now visible on the job page (!1944, closes #5949)
- Summary editor: add bug reporting button so users can flag issues directly from the editor (!1936)
Fixes
- Fixed
truckIdsNeo4j variable scope error introduced by query refactor (!1945) - Fixed pacing badges showing 0% on future dates instead of projected performance (!1945)
- Fixed negative discount validation — users can no longer enter negative discount values (#5810, !1939)
- Fixed VOSE booking failure when a job has a moving event with charges (!1941, closes #5952)
- Fixed AI tool execution halting when multiple tasks included a failing calculator or artifact evaluation step (!1938, closes #5873)
- Fixed quill template selector applying to the wrong editor (e.g. selecting a template in Summary applied it to the Add Comment editor) — scoped templates per-editor instance (!1936, !1935)
- Added “Exit wizard” button to the locations overview editor so users can leave without completing the wizard (!1937, closes #5945)
- Fixed access field in New Opportunity v3: elevator options now available for apartments; “Access” field now enabled for “Other” building type (!1935, closes #5939, #5940)
Other
- Downgrade oversized Redis payload log from WARN to DEBUG — expected for large zones, was polluting production logs (!1945)
- Downgrade prophet lookup zones log from INFO to DEBUG — fires on every viewDates call, too verbose (!1945)
- Prophet config fetch failure now emits a WARN log instead of silently swallowing the error (!1945)
v2603.25.0 — March 25, 2026
MRs: !1933, !1932, !1931, !1930, !1927, !1926, !1925, !1924, !1923, !1922, !1921, !1920, !1919, !1918, !1917, !1916, !1913
Highlights
Avoca multi-number call attribution (!1924, closes #5835)
When Avoca AI connects a call to a Dialpad number, Dialpad sees an inbound call from the Avoca bot’s phone number — not the customer’s. All job resolution (transcripts, hangup events, dispositions) was silently failing as a result. Move Right now detects the Avoca bot number and resolves the actual customer job correctly. Outbound call transcripts and dispositions are also now recorded.
Moverama calculator (!1925)
A new calculator added for Moverama franchise operations.
Best Moving Form — 5-way A/B experiment (!1913)
Continued improvements to the intake form A/B experiment: downstream conversion analysis (estimate → booking → invoice → converted job rates per variant), restructured consent flow, and UX fixes.
Schedule query optimisation (!1921)
Rewrote CalendarEvent Neo4j queries to use CALL subqueries instead of chained OPTIONAL MATCH, eliminating intermediate row explosion on large event sets. Composite (start, end) and status indexes added. This was the precursor to the deeper optimisation in v2603.30.0.
Features
- Avoca bot number-aware call attribution — Dialpad calls from Avoca are now correctly resolved to customer jobs (!1924)
- Record transcripts and dispositions for outbound calls (!1924)
- Moverama calculator (!1925)
- Best Moving Form 5-way A/B experiment: downstream conversion tracking (estimate/booking/invoice/converted job rates per variant) (!1913)
- AI now continues execution if a single task (calculator, artifact evaluation) fails within a multi-step chain (!1938 backport)
Performance
- Optimise CalendarEvent Neo4j queries — CALL subqueries instead of chained OPTIONAL MATCH, composite (start, end) index (!1921)
- Reduce DB load from comment queries — Thread.id index, dropped dead constraint, Comment.deletedAt index (!1920)
- Upgrade Node 18 → 20 across all packages — significant V8 and runtime improvements (!1933)
Fixes
- Fixed “Cannot coerce no value to string” error in report queries (!1932)
- Fixed lead routing: jobs now route to the correct franchise zone when only a partial postal code or city is provided (#5930, !1931)
- Fixed QuickBooks integration disconnect (!1927)
- Fixed SEO noindex propagation and deep link restoration after unauthenticated redirect (!1926)
- Fixed BOL document attachment logic — multiple edge cases in attachment evaluation and cleanup (!1919)
- Fixed AI resolving incorrect company phone/email when franchise has multiple zones (!1918)
- Fixed unsubscribe link appearing in emails sent only to internal users (!1917)
- Fixed NSC calculator update formula (hotfix series: !1916, !1922)
- Fixed report filter selector (!1899 backport)
Other
- Security:
npm audit fixacross frontend, backend, and intake — pinnedquill@2.0.2, upgraded@google-cloud/storageto v7 (!1930) - Removed unsubscribe link from document-completed emails sent to internal users only (!1917)
Earlier in March 2026 (post v2603.20.0, pre-newsletter)
These changes were shipped between the last newsletter (March 6) and the v2603.25.0 version bump. They were included in the March 6 newsletter retroactively or shipped shortly after. Included here for completeness.
MRs: !1913 (partial), !1912, !1911, !1910, !1909, !1908, !1907, !1906, !1905, !1904, !1902, !1901, !1900, !1899, !1897, !1896, !1895, !1894, !1892, !1891, !1890, !1889, !1888
See the March 6 newsletter at https://updates.moveright.app/p/see-your-busiest-days-coming-new-forecasting-pricing-tools for the user-facing summary of this period.
Newsletter draft — March 2026
Use this section as a starting point for the Beehiiv article. See
README.mdfor full conversion guide.Tone rules for Beehiiv:
- Write like you’re talking to a moving company owner, not a developer
- No MR numbers, no technical terms, no customer-specific names
- Short sentences. Simple words. Benefits first.
- “You can now…” not “We implemented…”
Subject line options
- “Your schedule is faster — and now shows how this month stacks up vs last year”
- “See how you’re tracking vs last year, right in your calendar”
- “Move Right update: faster schedule, smarter pacing, better calls”
Draft body
Your schedule loads faster
Opening the month view used to take a while if you had a lot of trucks and jobs. We fixed that. It’s much faster now — usually under a second.
[SCREENSHOT: schedule month view]
See how this month compares to last year
Turn on “Show Pacing” in the month view. Every day now shows how your bookings compare to what you had at this same point last year — including days that haven’t happened yet.
That means you can spot a slow week coming and act on it before it’s too late.
[SCREENSHOT: month view with % vs LY badges on future dates]
Export your pacing numbers to a spreadsheet
See a small copy icon on the pacing bar? Click it. You’ll get a ready-to-paste table with every day’s revenue, projections, and how you’re tracking vs last year. Open Google Sheets, paste, and you’re done.
AI calls are more reliable
If you use an AI answering service to handle and route calls, Move Right now does a better job of matching those calls to the right job and customer. Call notes and summaries are also recorded for calls your team makes outbound.
A few other things we fixed
- Unit numbers now show up on the job page
- Access notes are back in the new job form
- You can’t accidentally enter a negative discount anymore
- Selecting a note template in one place no longer changes other text boxes on the page
- Some jobs that couldn’t be booked for certain moves will now book correctly
Questions about any of these updates? Reply to this email or reach out to your Move Right contact — we’re happy to walk you through anything.