All releases
April 2026

April 2026 Updates

Send Schedule to Crew redesign, crew performance scoring, location details improvements, AI autodial error recovery, and more.

This is a technical changelog intended for developers and the Move Right team. For customer-friendly release highlights, subscribe to our newsletter.

Newsletter status: In progress. See README.md for conversion guide.


v2604.22.0 — April 22, 2026

MRs: !2030, !2029, !2028, !2027, !2026, !2025, !2024, !2023, !2020, !2019, !2018, !2017, !2015, !2014, !2013, !2012, !2011, !2010, !2009, !2008, !2007, !2006

Highlights

History search powered by Elasticsearch (!2007 et al.)

The job history feed is now backed by Elasticsearch, enabling faster full-text search, more reliable filtering, and real-time indexing as changes happen. History retrieval is significantly faster on large accounts, and the new search filters work correctly across all history types.

OTR Calculator — Job Breakdown section (!2019, closes #6048)

The OTR calculator has a new “Job Breakdown” tab that aggregates values from the other tabs into a single summary view. This reduces manual cross-referencing and calculation errors when preparing OTR estimates.

Movers Assistance Supplies Calculator (!2007)

A new calculator for movers assistance supplies is now available, helping crews and estimators accurately price packing and supply costs.

Timeline booking validation improvements (!2027, closes #6021, #6071, #6095)

Booking validation on the timeline now uses an overwrite-selection approach instead of disabling inputs, making it clearer when a conflict exists and easier to resolve it. The 30-day range validation has also been moved from the component into the reducer for consistency.

Performance

  • CallRail precall webhook now responds 200 OK immediately and processes all logic (phone lookup, intake, sourcing, comment) asynchronously, preventing webhook timeouts (!2030)
  • OTR event default location times are now configurable per-zone via config, improving auto-generation accuracy (!2020, closes #6049)

Features

  • New Movers Assistance Supplies Calculator (!2007)
  • New RPG Calculator updates (!2006)
  • OTR Calculator: new Job Breakdown section aggregating fields from other tabs (!2019, closes #6048)
  • Inventory actions panel: fixed permanent disabled state caused by route-checking loading state (!2026, closes #6077)
  • MCP create_report_export_link tool: improved security warnings and full query param documentation (!2023)

Fixes

  • Fixed crash when saving charges created from a price whose attributes contain empty strings ([""]) (!2029, closes #6102)
  • Fixed MCP token creation failure due to invalid provider validation (!2028, closes #6106)
  • Fixed “Book” menu item remaining enabled when job is missing a required area (!2024, closes #6071)
  • Fixed dynamic report preview failing to load (!2025, closes #6093)
  • Fixed silent job creation failure when pasting customer info via right-click (!2012, closes #6065)
  • Fixed confirmed events not being cancellable (!2010, closes #6062, #6053)
  • Fixed inventory actions permanently disabled in the right-hand panel (!2026, closes #6077)
  • Intake: fixed upload token rendered as static ref instead of state, causing hidden input not to render (!2017)
  • Intake: removed slow orphaned artifact metadata scan that caused session timeouts (!2015)
  • Intake: fixed lead routing when origin address contains only a city (!2018, closes #6043)
  • Fixed url null check in job loading observable to prevent silent errors (!2024)
  • Improved US zip code detection to avoid mistaking building numbers for zip codes (!2011, closes #6067)
  • Fixed Datadog session recording: initialize earlier and remove no-op beforeSend (!2014)
  • Improved display of long job titles in headers to prevent overflow (!2009, !2003)
  • Added total drive time summary at bottom of locations overview (!2008)

Other

  • Expanded iOS supported version coverage (!2013, closes #6069)
  • History service: added standalone ES load CLI, Dockerfile.dev for Node 20, bulk indexing, retry/backoff for ES connectivity, and zone security hardening

v2604.15.0 — April 15, 2026

MRs: !2007, !2006, !2005, !2004, !2003, !2002, !2001, !2000, !1999, !1998, !1997, !1996, !1995, !1994, !1993

Highlights

File attachments in job comments (!1999, !2000, !2001, !2002)

You can now attach files, photos, and images directly to job comments. The comment editor gains a paperclip button for file uploads, a camera button for direct photo capture (mobile-friendly), and supports pasting or drag-dropping images inline. Attachments appear as tappable chips in the comment feed, and attached images are included as links in outbound SMS and email dispatches so the crew and customer both see them.

Drive time and distance summary for multi-location jobs (!1994)

Jobs with multiple stops now display a total drive time and total distance line in the job overview. This gives dispatchers an at-a-glance summary of the full trip without needing to open each leg individually.

Packing materials in job totals (!2003)

Packing materials (wrap, boxes, etc.) now appear in the job totals section and are included in calculator outputs. Stretch wrap is calculated per weight, and CP packing items are resolved from inventory automatically.

Performance

  • Improved jobs.updateTotals query performance and added retry logic for Neo4j deadlocks during concurrent job updates
  • Optimized intake artifact claim: single Cypher query replaces slow callListArtifacts scan; bulk parallel edits avoid session timeouts
  • Parallelize artifact claim edits in intake to avoid Neo4j session timeout on large file sets

Features

  • Dialpad outbound call info (duration, outcome) is now recorded in Move Right when an agent completes a call, with tests covering webhook parsing edge cases
  • Share Events dialog (opened from the calendar view) now correctly lists all events on the job, not just events visible on the current calendar day
  • Dock locations are now backfilled into event itineraries when required by zone configuration but missing — prevents missing-leg errors on routed jobs
  • Intake form now supports variant and disableskip as HTML embed attributes, enabling per-embed configuration without code changes
  • Intake uploads now start eagerly (before form submission) for leadsource tokens, with server-side artifact discovery and localStorage persistence across sessions
  • Signed estimate requirement is now configurable per event type (previously a single global flag), allowing estimating events to be excluded from the requirement
  • mr-cli zones list default max-depth increased from 2 to 4

Fixes

  • Fixed confirmed events being excluded from cancellation and closing logic — they are now correctly included
  • Fixed long job titles overflowing the job header on narrow screens — text now truncates with ellipsis and uses responsive font sizing
  • Fixed paragraph wrapper appearing in calendar asset descriptions when using the rich-text editor
  • Fixed FullCalendar event layout and spacing issues (overlapping events, incorrect column widths)
  • Fixed race condition in Share Events dialog where zone selector opened with no zone preselected for shared events
  • Fixed comment mode not being preserved when resetting job activity state after a remote update
  • Fixed duplicate file attachments being added when rapidly clicking the attach button
  • Fixed a missing null guard for dock end location that caused itinerary calculation errors on some job configurations
  • Fixed intake move date normalization to handle non-string inputs and edge-case date formats robustly
  • Fixed artifact upload linking for virtual estimates; disabled virtual estimates by default
  • Fixed normalizeMoveDate to use native date input handling, preventing timezone-offset drift

Other

  • Moverama and RPG calculator logic added (junk removal, labor-only, peak season pricing, move size definitions)
  • Added .codex to .gitignore
  • Mock Redis added for backend integration tests

v2604.09.0 — April 9, 2026

MRs: !1992, !1991, !1990, !1989, !1987, !1986

Highlights

Marketing pages now open inside the app shell (!1987)

When a logged-in user navigates to a Move Right marketing URL (like /pricing, /resources, /features/*) directly inside the app, the page now loads seamlessly inside the app shell via an embedded iframe. Previously these URLs either 404’d or bounced the user out of the app. Navigation back into the app works via postMessage-based routing. The PWA service worker and manifest are updated to exclude these paths so the Angular shell never intercepts them.

Pricing page embedded inside the app shell

Unshare event — remove a shared event from a zone (!1992)

You can now unshare an event that was previously shared with another zone. The share panel on an event now shows an active share with an option to remove it, giving dispatchers full control over cross-zone event visibility.

Quo missed call/SMS → auto-create job configs (!1991)

New zone-level configuration options let you control whether a missed call or unanswered SMS received through Quo automatically creates a new lead/job. Configure it per zone under Settings → Zone → Automations.

Fixes

  • Fixed cached job fetches not dispatching jobLoaded action, causing stale UI state in some views (!1990, fixes regression from !1988)
  • Removed the floor range step from the location details wizard — it was surfacing prematurely for job types that don’t require it (!1989)
  • Fixed duplicate job creation in New Opportunity flow when the user submitted rapidly or navigated away mid-request (!1986)
  • Fixed PWA manifest scope, iframe routing sync, postMessage origin guard, and trailing-slash normalisation for Astro embed (!1987)
  • Fixed additional stop addresses not rendering correctly in PandaDoc documents when address lines were empty (!1982)

Features

  • Additional job location addresses (stops) now included as variables in PandaDoc document generation, sorted by location type (!1982)

v2604.08.0 — April 8, 2026

MRs: !1985, !1984, !1983, !1981, !1980, !1977, !1976, !1975, !1974, !1973, !1972, !1971, !1970, !1969, !1968, !1967, !1966, !1964, !1963, !1961, !1960, !1958

Highlights

Dynamic pricing tiers — schedule page, calculator, and New Opportunity (!1984, closes internal)

The prophet forecasting system now stores forecasts in Neo4j (instead of Redis) and drives a new zone-level pricing tier system. Tiers are shown as coloured badges on the schedule month view, day view forecast card, and New Opportunity date cards. The NSC Quick Estimate panel gains an Ask for Discount button that simulates a brief hold and steps through discount tiers (0% / -3% / -6% / -9% / -12%), presenting the result as a suggestion dialog with clickable date cards.

Ask for Discount button in Quick Estimate

Cancel & Close dialog — unified event cancellation and job closure (!1966, closes #5701, #5611)

Cancelling an event or closing a job with pending bookings now opens a single unified dialog. You can select which events to cancel, optionally provide a closure reason, and submit both actions atomically in one call. The dialog is reachable from work orders, event details, the job header, and the job status dropdown.

Cancel Events dialog showing pre-selected booked event

21-second auth fix — purge of 1.3M stale refresh tokens (!1985)

Production APM traces showed auth.authenticate occasionally taking 21+ seconds. Root cause: one user had accumulated 1,079,789 stale refresh tokens that were deactivated but never deleted. A new migration (runs on next deploy) batch-deletes all inactive/expired tokens, and expireExtraRefreshTokens now DETACH DELETEs excess tokens instead of setting active = false.

Google Ads offline conversion tracking endpoint + CLI wizard (!1977)

New GET /api/gads/offline_conversion_tracking endpoint returns a CSV of jobs with GCLIDs, conversion stages, and SHA256-hashed email/phone columns for Enhanced Conversions. Auth is scoped per zone. A new mr integrations gads ecs CLI wizard creates the API token and prints setup docs in-terminal.

Performance

  • Delete 1.3M stale refresh tokens on deploy; expireExtraRefreshTokens now hard-deletes instead of deactivating (!1985)
  • Add composite Neo4j LIMIT to active-token lookup so auth is O(maxSessions) regardless of historical token count (!1985)

Features

  • Dynamic pricing tiers: zone-level tier editor in prophet settings; tiers inherit to child zones (!1984)
  • Dynamic pricing tiers: tier badge on schedule month view, day view forecast card, and New Opportunity date cards (!1984)
  • Dynamic pricing tiers: tier drives hourly rate in calculator date card; NSC “Ask for Discount” hold button with suggestion dialog (!1984)
  • Prophet forecasts migrated from Redis to Neo4j; historical forecasts shown on schedule page with past/future labelling (!1984)
  • Cancel & Close dialog: cancel any subset of events and optionally close job in one atomic mutation (!1966, closes #5701, #5611)
  • Google Ads offline conversion tracking endpoint with per-zone token auth and SHA256 Enhanced Conversions columns (!1977)
  • mr integrations gads ecs CLI wizard: creates API token, prints curl examples and in-terminal setup docs (!1977)
  • mr auth replaces mr config; multi-profile support with --profile flag and auto-naming by gateway host (!1977)
  • Require signed estimate before booking: new zone config jobs.requireSignedEstimate; booking UI shows tooltip when blocked (!1983, closes #5516)
  • Intake: new expanded variant (manual-only via ?expanded) mirrors jobs v4 location-details wizard with access/elevator/floor steps (!1976)
  • Intake: disableSkip prop blocks advancing past new access/elevator/floor steps without a selection (!1976)
  • Intake: disable contact-info-first-slim A/B arm for new users — traffic redistributed to 25% per active arm (!1976)
  • Movers Assistance (TMM) calculator: local / intrastate / interstate move classification; minimum 3,000 lb weight for intrastate+; U-Haul one-way pricing for interstate (!1974)
  • Trigger rules: new system-rules flag field for zone-level rule configuration (#6011, !1980)
  • Dynamic Reports: expose additional data columns for Claude API reporting (!1969)

Fixes

  • Calculator: fix Total Hours Per Man division-by-zero in FP labor; correct interstate section visibility to use sessionZone (!1984)
  • Calculator: inline availability calendar replaces dropdown stub for date picker (!1984)
  • Schedules: cancel/close dialog — responsive width, filtering, auto-focus, submit split into explicit cancel/close actions (!1966)
  • Mandatory location details: enforce dwelling type and bedroom fields; fix selector priority for locked/invoiced status (!1975)
  • Documents: allow sending multiple documents; require email or phone before enabling send (!1973)
  • Reports: allow null sort in dynamic reports to support column removal (!1972)
  • Billing: allow editing customer when billing address is set (!1963, closes #5975)
  • Invoice: save job changes before creating invoice; move invoice-open logic to dedicated effect (!1971)
  • Scribe: extract rule-1 to .ts, tighten conditions, fix run-script dns import (!1961)
  • Valuation email: fix mobile layout, rule-2 scriptUrl, single HTML source of truth (!1964)
  • Reverse-typing issue in editors (!1960)
  • Scroll position reset on all page-level route changes (!1981)
  • Accounting lock: rename payroll lock to accounting lock in job update validation (!1967)
  • Intake: correct floor_info skip logic — stairs users see flight count step; fix disableSkip default and stale state (!1976)
  • Gads endpoint: harden CSV escaping against formula injection; correct Neo4j variable name in customer collect query (!1977)
  • Token auth: use token ID as Basic Auth username to eliminate timing side-channel (!1977)

Other

  • Conventions reviewer subagent and formatting hook for NgRx patterns (!1970)
  • NSC calculator versioned as ymm-nsc-calculator-2603.30.0.ts (!1984)
  • Docs: Google Ads offline conversion tracking setup guide (!1977)

v2604.01.0 — April 1, 2026

MRs: !1958, !1956, !1955, !1954, !1953, !1952, !1951, !1950, !1949, !1948, !1947, !1946, !1945, !1944, !1942, !1941, !1940, !1939, !1938, !1937, !1936, !1935, !1933, !1932, !1931, !1930, !1929, !1928, !1927, !1926

Highlights

Send Schedule to Crew — full redesign (!1945, !1937, !1936, !1935, !1944)

The crew schedule email has been completely rebuilt. It now includes You Move Me branding, Google Maps links for each location, an iCal attachment, the customer’s name as a clickable phone link, and a formatted ops report card layout. The dialog that lets you select which crew members to send to has been redesigned with a preview pane showing exactly what each person will receive — before you send.

Crew performance scoring + event performance requirements (!1945, !1949, !1947)

Dispatch now tracks a performance score for each crew member, displayed in their hover tooltip alongside their effective hourly rate. Each calendar event can have a performance requirement — when the optimizer assigns crew, it applies a cost penalty for crew who fall below the requirement. Ops managers can be designated for the day directly from the dispatch view.

Location details — floor, elevator type, and access inputs (!1953, !1944, !1935, !1937)

The job creation wizard and location editor now have dedicated fields for floor number, elevator type (no elevator / service elevator / passenger elevator), and access notes. These replace the old free-text “access” label. The wizard opens automatically when an address is selected, and a manual trigger button lets you re-open it at any time.

SendGrid email click/open rule triggers + valuation coverage flow (!1929)

Rules can now fire on email-opened and email-clicked SendGrid events. This is used by the new Valuation Coverage flow: when a customer clicks the valuation email, a rule automatically adds a charge and sends a confirmation. Machine-click detection prevents false positives from email scanners.

Performance

  • Fix 16-second refresh token query by adding composite Neo4j index on (active, expiration, createdAt) (!1954)
  • Aggregate pacing events by day in Neo4j — returns ~60 rows instead of 4,300 (!1949)
  • Eliminate dayjs hot-loop overhead and pre-filter events per day in availabilityV2 (!1947)
  • Fix 10-second Redis SET latency in find.viewDates / availabilityV2.list (!1942, !1945)

Features

  • Dispatch: total labour hours, revenue/labour hr, and cost permission gates (!1945)
  • Dispatch: ops manager for the day — designate from the dispatch view (!1945)
  • Dispatch: customer name in email is a tel: link to their phone (!1945)
  • Dispatch: scroll bar in email/SMS preview panel (!1945)
  • Rules: run-script action supports scriptUrl — load scripts from functions.moveright.app (!1929)
  • Rules: add-charge-to-event action for automating charge creation from rule scripts (!1929)
  • Rules: email click/open triggers with machine-click guard (!1929)
  • New Opportunity v4: show saving state on “Go to Job” button; save on navigate (!1953)
  • Location editor: manual trigger button to re-open location details wizard (!1953)
  • MCP: add Hey Patrick as a provider option with email setup instructions (!1952)
  • Allow area change when job has charges; add per-event Share Events dialog (!1928)
  • Allow crew/attendee changes on invoiced events until accounting lock date (!1945)
  • Script execution: fetch() in scripting sandbox, sendEmail/sendSMS via comment modes (!1929)
  • Changelog infrastructure + /release skill (!1946)

Fixes

  • AI: autodial errors (call center closed, provider failures) now surface back to the Ask Bee thread so Bee can react and schedule a callback (!1956)
  • AI: prevent premature task_completed exits — model no longer exits without executing actions (!1955)
  • AI: normalize email formatting from AI-generated content (!1958)
  • Locations: trigger recalculations and refine floor parsing logic (!1953)
  • Locations: add floor and elevator type fields to job creation wizard (!1953)
  • Quill: provide category-specific templates for job summaries (!1951)
  • Quill: support multiple template locations for job summaries (!1951)
  • Dispatch: fix infeasible optimizer bug + performance label display (!1945)
  • Dispatch: fix performance requirement metadata save (!1945)
  • Dispatch: fix effective rate formula — linear inverse of score (!1945)
  • Dispatch: fix perf req label stale update (!1945)
  • Dispatch: navigate to v3 job tool on double-click instead of old route (!1945)
  • Dispatch: fix select changed/unsent — move logic to effects (!1945)
  • Rules: fix event-status-changed trigger passing newStatus not originalStatus (!1929)
  • Rules: add _CONTAINS condition for string substring matching (!1929)
  • Fix configByObjectId Map preserves first-wins semantics for duplicate objectIds (!1945)
  • Franchise routing: fix KC leads being routed to KW (!1931)
  • VOSE: fix booking if job has a moving event with charges (!1941)
  • Autodial: skip recent-autodial check if autodial was requested by an employee (!1940)
  • Negative discounts: add validation to block entry (!1939)
  • AI execution: ensure chain continues when AI needs to perform multiple tasks (!1938)
  • Locations: add “Exit wizard” button to location overview editor (!1937)
  • Hotfix: fix “Cannot coerce no value to string” (!1932)
  • Quickbooks: fix disconnect flow (!1927)
  • SEO: fix noindex + deep link restoration after unauthenticated redirect (!1926)

Other

  • Tests: 34 unit tests for availabilityV2 helpers — getFilteredBlocks, buildAvailabilityContext, calculateDayAvailability (!1948)
  • Node 18 → 20 upgrade across all packages (!1933)
  • Security: npm audit fix — frontend, backend, intake (!1930)
  • Patch axios DoS vulnerability (GHSA-43fc-jf86-j433) (!1930)