Hey everyone! As promised, the first of our new bi-weekly updates. The past two weeks were heavy on payments, jobs, and dispatch — the day-to-day stuff you actually click on. Here’s what’s new and what we fixed.
New
Payments
- Refunded amounts and net revenue are now broken out separately on the Payments stats card, so you can see the real picture at a glance.
- When recording a payment, you can now optionally link it to an invoice on the spot.
- The Refund button is now visible directly on the invoice detail screen — no extra digging.
- Invoices now show a clean list of payments applied to them, right on the detail page.
Invoices
- Export to CSV — invoices, with your current filters applied.
- Duplicate to draft in one click.
- Attach receipts and supporting documents directly to an invoice.
- Email an invoice straight from the detail page, with a preview before you send.
- Download an invoice as a file for your accounting integrations.
Estimates
- Export to CSV with your filters applied.
- Duplicate to draft in one click.
- Estimate PDFs now include the full line items table.
Jobs, Customers & Tasks
- Export to CSV for jobs and customers, with filters applied.
- Tasks can be deleted from the app, and task history now logs who created / started / completed / cancelled it.
- Maps preview on jobs has a satellite mode toggle.
Calls & Voice
- Customer phone numbers across Jobs, Schedule, Tasks, Dispatch, and Accounts now place calls through the in-app dialer.
- The Tech Call button on the Supervisor Dashboard now connects through Twilio Voice.
Login & Sessions
- Faster app start — your user, tenant, and session info now load in a single request.
- Email verification at signup (with resend).
- Forgot password flow with a real reset link.
- Accept invite flow for invited teammates.
Dashboard & Reports
- New list of available reports — for integrations.
- The trial banner now has a distinct “trial expired” state so you’re not guessing.
Notifications
- Snooze a notification and it now sticks across devices instead of being a local-only setting.
Public site
- New SMS opt-in compliance reference page for marketing campaigns.
What’s Fixed
Payments
- Date filters and the totals pill on the Payments page now agree with each other.
- Refunds correctly cascade to the linked invoice’s paid amount and status.
- Refunds are processed as a single operation — no more “half-done” refunds.
- Future-dated payments are now blocked with a clear error.
- Recording a payment against a draft, paid, refunded, or cancelled invoice now returns a clean message instead of crashing.
- Recording a payment for the wrong customer’s invoice now returns a friendly error instead of a server crash.
- The Record Payment wizard blocks overpayments and requires a payment method before continuing.
- Payment status can no longer be sneakily flipped to “refunded” through edit.
- Header stats on the Payments page now match the actual filtered data, not just the first page.
- Every payment change is now recorded in the audit log.
Invoices
- Invoice PDFs now include the full line items table.
- Send Invoice email pre-fills “To” from the customer’s email, and lets you add a personal note.
- Cancel Invoice now requires confirmation and is more clearly labeled.
- Draft and cancelled invoices show a zero balance instead of phantom amounts owed.
- Invoices with a credit balance now display “Credit $X.XX” instead of “$0.00”.
- Invoice header math (billed = paid + outstanding) now reconciles cleanly.
- Payment history appears in the invoice detail drawer.
- Negative line items are allowed for per-line discounts.
- Zero-total or empty invoices are blocked at create time.
- Public pay-by-link page no longer breaks for some accounts.
- Missing invoices now show a clean “not found” message instead of a server error.
Estimates
- Send Estimate “To” field pre-fills from the customer’s email.
- Approving an estimate now requires a real signature and stamps an audit trail.
- Customer search and dropdown in Create Estimate handle legacy data and don’t show duplicates.
- Status tab counts reflect every estimate, not just the visible page.
- Save Draft saves immediately, no debounce surprises.
- Drafts reload reliably every time the modal opens.
- Session-expired warning is now persistent during submit so you don’t silently lose work.
- All estimate actions (approve / decline / convert) are logged in the audit log.
Billing & Subscriptions
- Stripe-paid trials now correctly convert to active paid subscriptions.
- Subscription plan and status persist correctly after checkout.
- Trial expiration no longer blocks login, billing, or payment endpoints — you can always reach the upgrade page.
- “Trial expired” state now reads from the real expiry date, not a tier filter.
- Daily trial check now properly suspends expired trials.
- Overdue and payment-failed reminders now run as scheduled.
- “Founding Member” label no longer shows when there’s no subscription.
- AI Usage tab no longer shows “NaN%” for unmeasured periods.
- Billing usage page no longer shows fake “limit -1” entries.
- Connect Payment Gateway error banner now has a Retry button.
- A clear toast with an Upgrade CTA appears when company changes are blocked by billing.
Calls & Voice
- Hold music plays in a continuous loop on cold-start (no more silence).
- The voice gateway recovers automatically when an instance gets stuck.
- Calls under 5 seconds are now correctly classified as “no answer” instead of “completed”.
- Average call-duration KPI no longer shows 17-digit decimals.
- Recording playback uses dark theme styling to match the rest of the UI.
- Voice connection status now correctly considers both assistant and phone configuration.
- Notification SMS now goes out from your own Twilio number, not a shared one.
- Call/voice status polling pauses when the tab is hidden (saves battery).
Jobs & Schedule
- Times across the schedule, dispatch, and date filters now use your company timezone instead of UTC.
- Job pipeline stages that haven’t been reached show “Pending” instead of “Skipped”.
- Job header now shows the right details: type, business unit, arrival window, tags, and balance.
- Cancelled jobs are visually muted, hide the pipeline stepper, and are excluded from busy hours, day progress, and revenue counts.
- Cancelled jobs hide Edit / Reschedule and show an “Originally scheduled” label.
- Schedule week-view header shows 12 AM correctly (was 12 PM).
- Schedule week view snaps to the visible Monday–Sunday window.
- Unassigned Jobs sidebar adds a “Tomorrow” label and dates non-today jobs.
- Dragging a card on the schedule board reliably opens the job detail.
- The Start Work button is blocked until a technician is assigned and a time is scheduled.
- Job stage transitions are guarded — invalid transitions no longer go through.
- Cleaner error message when reverting a job from “in progress” back to “scheduled”.
- The “En Route” sub-status is preserved when transitioning to “In Progress”.
- Complete Job button surfaces the real validation error instead of a generic message.
- Completing a job with auto-invoice generates the invoice synchronously (no waiting for it to “appear later”).
- Job actions no longer fire twice on rapid clicks.
- Updating a job’s status refreshes the “Last Updated” timestamp.
- “All Jobs” tab actually includes all statuses, and bulk-action toasts are honest about results.
- Edit Job dropdown shows real technician names, not template placeholders.
- Edit Job wizard step 3 renders correctly.
- Property dropdowns on jobs and work orders load all of your properties.
- Job photos with bad file types or corrupt characters are rejected with a clean error.
- Old jobs with HTML tags in their description have been retroactively cleaned up.
- Save errors appear inline in Create Job and Create Customer modals.
Work Orders
- Edit Work Order modal date/time uses the themed picker (no more bare native input).
- Status change conflicts surface a real error instead of failing silently.
- Dragging a card from Requested → Scheduled on the kanban now works.
- Kanban card click opens the detail view in all browsers.
- Detail panel auto-hides while Edit is open, so the Save button isn’t clipped.
- Cost inputs accept decimals.
- Cancelled work orders appear on the kanban (Start Work / Schedule are hidden on them).
- Filter chips and column counts on the kanban now reconcile.
- Priority and Property filters are preserved in the page address — you can share a link.
Dispatch
- Dispatch page is reachable from the sidebar at the dispatcher role.
- Dispatch board excludes draft jobs from the queue.
- All job statuses are shown with proper labels.
- Auto-assign now reports failures correctly instead of swallowing them.
- Duplicate job cards no longer appear on the board.
- Cancelled jobs are included in header stats so the queue count reconciles.
- En Route badge counts and completion-rate calculation exclude cancelled jobs.
- The map card surfaces a count of jobs missing coordinates.
- Clicking a dispatch card navigates to the job detail.
- Clicking a technician card filters the job queue with a visible chip.
- Assign dropdown is hidden on jobs that are already work-closed.
Tasks & Follow-ups
- Quick-add no longer auto-stamps a due date eight hours from now.
- On rapid clicks, start / complete / cancel actions no longer fire twice.
- Checklist items render the right title.
- Follow-up shortcuts (
a / s / c) default to the first task when nothing is selected. - Follow-up stats page works again (used to show an error).
- Stats no longer show “N/A” where a zero should be.
Customers
- Edit Customer Save button is gated until addresses finish loading.
- Customer rename propagates to the jobs list view.
- Customer phone numbers are now normalized consistently — this closes the gaps in duplicate detection.
- Adding/editing a customer now refreshes related jobs / estimates / invoices lists immediately.
- “New this month” filter excludes migrated rows.
- Customer rows reliably open from hover overlays.
- Duplicate “Edit” menu entry removed from customer detail.
- When merging customers, the second profile is locked during the operation — no data lost.
Properties
- Filters reflect real property status counts.
- Properties list pages through until everything is loaded.
- “Unknown Address” stub rows are now hidden, and new empty-address ones aren’t created.
Vendors
- Vendor website field auto-prepends
https://on bare domains. - Compliance card shows a clean empty state when there’s nothing to display.
Login & Sessions
- Sessions auto-refresh near expiry instead of crashing with an error.
- An expired session now cleanly opens the Session Expired modal instead of crashing the app.
- Login page has a logo link back to the marketing site.
- Signup form shows an inline styled error instead of a browser tooltip.
- Several signup edge cases that previously failed silently now succeed.
- Accepting an invite is now safe against double-clicks and concurrent attempts.
- “Pending” and “invited” statuses added — invited users are now visible in the team list.
- Continue Session and Sign-in buttons reliably submit on Enter.
- The login audit log now distinguishes session re-auth from a fresh login.
Audit Log
- Account create / update / delete actions now appear.
- Estimate approve / decline / convert actions now appear.
- Total Events / Today cards on the Audit page show real numbers.
- “Empty” updates where nothing actually changed no longer clutter the log.
Conversations
- Quick Replies promoted, AI Controls demoted, and the extra placeholder dropped from the chat input.
Dashboard & Reports
- Onboarding “Getting Started” rows have working links once completed.
- Saved-report card click loads the report into the builder.
- Direct links to report templates open the right template in the builder.
- Reports preview excludes cancelled jobs from totals by default.
- Export button on Reports actually downloads the CSV.
- Reports footer no longer shows “Tokens used: 0” on non-AI reports.
- Dashboard period selector triggers a refresh on click.
- Dashboard surfaces a clear error when metrics fail to compute, instead of silently showing zeros.
- Dashboard distinguishes a technical error from genuinely empty AI insights.
- Profit margin preserves “no data” instead of falsely flagging low margin.
- Funnel and Executive Metrics jobs-completed numbers now reconcile with period stats.
- AI branding on the Business Analysis panel is honest about what’s AI-generated.
Notifications
- Notification types are now translated, with a sensible fallback for unknown ones.
- Notification translations added across all 10 non-English languages.
AI
- AI prompts use the new caching layer — ~90% latency reduction on long contexts (responses feel snappy).
- AI Regenerate for estimates and job notes no longer invents services.
- “Write it for me” on Price Book now wires to the real AI.
- AI usage page reads from the proper source.
- AI SQL generator errors are shown safely.
Search & Navigation
- Cmd/Ctrl + K opens the global search modal.
- Cmd + / for AI chat (no longer conflicts with Cmd+K).
- Search results now include Invoices.
Team & Roles
- Roles list shows the right user count and is scoped to your tenant.
- Roles editor handles “all permissions” wildcards correctly and protects system-role permissions.
- Orphaned role assignments are cleaned up automatically.
Technicians
- Technician management now includes inactive role-assigned users.
- The technicians list no longer shows duplicates.
- Technician filters and the capacity widget are now consistent with each other.
- Assign Job button on the technician card wires to the Dispatch page.
Settings
- Company timezone now defaults to your browser timezone instead of hardcoded LA.
- Updating company profile name syncs back to your tenant name.
- Phone provisioning status refreshes after every save.
- Save Changes button no longer requires a no-op edit to enable.
- Calendar integration persists all 6 sync fields, not just the first 2.
- In-app Documentation links are hidden until the docs site is live.
Inventory & Maintenance
- “Add to Van” actually transfers items now.
- “Order Now” placeholder is hidden until the purchase-order flow ships.
- Maintenance schedules list refreshes immediately after creating a new schedule.
- Asset condition can be edited inline from the list.
Price Book
- Money inputs select on focus — the leading 0 gets replaced as you type.
Public site & Marketing
- Footer “About Us” routes to
/about(was a missing anchor). - Footer “AI Agents” link points to the rendered section.
- Founding-member pricing counter shows a real number.
/demono longer shows a “Video Coming Soon” placeholder.- Unknown public URLs show a real “404 not found”, not a redirect to login.
- Logo and branding fall back to your tenant name instead of “My Company”.
Translations
- “Calls” navigation label translated in all 10 non-English languages.
- Customer-import field labels translated.
- Toast messages on jobs aligned to consistent sentence case.
Integrations
- Thumbtack webhook reports the real problem on failure instead of pretending everything’s fine.
- Thumbtack OAuth failure modes are now readable.
- When QuickBooks isn’t configured, the page shows a clear message instead of a server error.
- HCP integration is now visible in the integrations catalog.
Security & Stability
A lot of behind-the-scenes work this cycle on tenant isolation, request throttling, file scoping, and background-job stability. You won’t see most of it directly — but it’s exactly what keeps your data strictly yours and the platform humming. Highlights:
- Job photos and uploads are stored in your tenant’s directory — nothing is reachable from outside.
- Remaining cross-tenant access in queries has been closed.
- Brute-force protection now works correctly behind a proxy.
- Stronger input sanitization across the app.
Next update — mid-May
This is the first of our bi-weekly posts. Next one drops around mid-May with the next two weeks of work.
As always — if you spot something broken or have an idea, just reply here.