This week
Aug 18 – Aug 22 · 11 ships- FeatureFinancialsAug 22#458
Your crew's labor finally counts as spend on the job
The Financial tab's actual column only knew about POs and invoices, so any job running its own crew read cheaper than it was and the variance beside it was wrong. Labor now joins materials and subs in one derivation, as an independent pool that sits outside the PO and invoice max(), so it adds to the actual without double counting a thing. The cell carries a Labor chip and the tooltip says where the money came from.
- FeatureJobsAug 22#467
The job Timeline keeps its dates on screen while you scroll
The date header scrolled away with everything else, so reading a bar halfway down the job meant counting rows from memory or scrolling back up to check. It pins to the viewport now. 768px and up; phone widths keep today's behavior.
- FeatureJobsAug 21#463
Photograph a document and it files itself on the job
The Documents tab took PDFs and nothing else, so anything shot on a phone had to be converted first and most of it never made it onto the job at all. Uploads now take JPG, PNG, WEBP, HEIC and HEIF alongside PDFs, with inline preview, and every file gets tagged at upload and stays editable on the row. RFI is one of those tags: they arrive as PDFs from the architect, so they are a document to file, not a form to retype.
- FeatureFieldAug 21#454
Weather reads the same no matter who logged the day
Conditions are the record you reach for when a weather day gets questioned, and they rendered three different ways across the phone composer, desktop /field-logs and the worker portal, so the same day looked different depending on who opened it. One pill covers all three now. The saved-log detail modal keeps the full breakdown and gains an Observed cell, because it is the audit surface.
- FeatureFinancialsAug 20#453
A logged day turns into labor dollars on the job
Crew hours used to sit in the field log and never reach the money. Each person's hours now price against the job's own cost codes at save, with the rate resolved server side rather than sent from the browser. Hours split with largest-remainder rounding plus a second pass over cents, so the per-line dollars sum to the total exactly.
- FixMarginAug 20#453
The Budget dashboard was reporting hours as dollars
budget_work_items_rollup multiplied logged hours by a $1/hr fallback, so a 40 hour week rendered as $40 of labor on the Budget dashboard and the CFO report. Both sum the persisted allocations now, which means labor jumps to real values on any job with logged crew hours.
- FeatureEstimatingAug 20#446
The field log now tags hours with something the budget recognizes
This is what makes the labor pricing above possible. The picker sent internal phase IDs and the budget keys on scope, so there was nothing for those hours to price against. It offers the job's own budget scopes first, with the full taxonomy behind an Other scope escape hatch, and sends canonical scope keys. The 48 taxonomy rows that shipped with no execution type are backfilled, and an old draft holding a phase ID restores as no-scope rather than leaking a bad key through.
- FeatureScheduleAug 20#447
You can still tell which week you are looking at halfway down the schedule
Scroll a long schedule and the week columns slid away, leaving a wall of bars with no dates on it and a scroll back up to work out what you were reading. The week header holds at the top now, on the schedule timeline and on the client portal milestone timeline both. 768px and up.
- FixPlatformAug 19#425
You can tell who is who on the crew roster again
The name and role column had collapsed to 41px, narrower than the avatar sitting in it, and the badges painted underneath the buttons on top of them. Four link actions were rendering as full-width brand buttons, a 572px action rail inside a row that only gets 620 to 668px at any viewport, so a 5K display broke exactly like a 13 inch laptop. This row has broken twice, so the change ships the guards, not just the fix.
- FixFieldAug 18#409
One shift stopped logging two different numbers
/field-logs subtracted the org's unpaid break. Neither worker portal had a break field at all, so an 8:00 to 3:00 shift recorded 6h 30m from the office screen and 7h from a phone. That gap fed daily_logs.hours, then tasks.actual_duration_hours through the trigger, then the budget rollup. All three capture surfaces share one break field and one derivation now, with the deduction shown on screen.
- FixMobileAug 18#417
The phone composer could file a log under a day it never showed
The date pill was computed once at mount while the save path stamps a fresh clock, so a log written at 11:50pm, or a phone backgrounded overnight in a PWA, displayed one day and filed under another. It is derived at render now, off a local Date, and never by re-parsing a YYYY-MM-DD key, which reads as UTC midnight and walks every California log back a day.
Margin math, AI rates & the Gantt
Aug 10 – Aug 14 · 13 ships- FeatureFieldAug 14#402
Field logs subtract the break, so labor actuals stop inflating
Logs recorded gross time, so an 8:00 to 4:30 day filed 8.50 hours and inflated every labor actual downstream. There is now a break field with an org default.
- FixFinancialsAug 14#404
The generated proposal shows cents too
#319 fixed the portal and the estimate table and missed the PDF the client actually receives. All six money cells route through one formatter now.
- FixMarginAug 13#366
Every job showed a $0 client price and 0.0% margin
The Profit Summary card priced off a column nothing writes, empty in all 53,032 rows. 28 jobs wrong, $377k of client price hidden. Both surfaces price through one function now.
- FixEstimatingAug 13#365
AI estimates priced labor at a twentieth of the real rate
The worker read dollars per unit straight into a dollars per hour column, so a $37/hr template priced labor at $1.85 an hour. One function does the conversion now.
- FixScheduleAug 13#356
Dragging a phase on the Gantt half-applied and wrote every task a day early
A batched upsert threw 23502 after the sort order had already committed, so the phase moved while an error fired. The date math also landed a day early west of Greenwich.
- FeatureScheduleAug 13#360
Tasks and milestones delete from the Timeline rows
Delete straight from the row, no trip back to the task list.
- FeatureEstimatingAug 13#355
Storm and site drainage is its own scope row
P-4 in the taxonomy, so drainage stops getting filed under a neighboring phase.
- FixEstimatingAug 12#344
Sending a proposal no longer wipes the estimate off the job
The workspace resolver was an allowlist over an eight-status enum, so a submitted estimate rendered as no estimate at all. Two live jobs looked empty right after being quoted.
- FixScheduleAug 12#346
Date-only math ran in local time, so dates came back a day early
addCalendarDaysToIsoDate('2026-05-04', 0) returned 2026-05-03 in California. Task starts, finishes and dependency cascades all shifted a day for every user west of Greenwich. The math runs in UTC now.
- FeatureMobileAug 11#334
The job board stops burying itself on a phone
Below tablet width the four kanban buckets stacked into one endless column. They collapse now, Active open and the rest closed. Desktop is untouched.
- FixMobileAug 11#337
Settings header buttons stay inside their card
Four Production Library buttons ran past the card edge on a phone and dragged the page sideways with them. Fixed in the shared settings header, so every section behaves.
- FeaturePlatformAug 11#336
A help guide for what each project type actually does
/help/workflows/project-types answers one question for all eight types: what changes inside Baxie when you pick it. No claims about ADU rules, those are local.
- FixAssistantAug 10#330
The assistant stopped claiming your plans were never processed
It answered 'not processed yet' on jobs that extracted fine, sending GCs off to re-upload drawings already there. It reports what it actually has now.
AI honesty, Week View & self-debugging bug reports
Aug 3 – Aug 7 · 19 ships- FeatureAIAug 7#321
Every AI surface tells you what it is actually doing
Scope extraction, estimate generation, takeoff and receipts now share one honest state machine: queued, then working with an elapsed clock, then ready or a retryable failure. The banner survives a reload, a toast finds you if the job finishes on another page, and work kicks off in seconds instead of waiting on the cron tick.
- FeaturePlatformAug 7#323
Bug reports that debug themselves
Report Issue auto-captures a page screenshot, timezone, viewport and the recent console errors, then attaches the Sentry session replay. Triage renders all of it and copies out a ready-to-paste GitHub issue, so a one-line report arrives with the repro already attached.
- SpeedJobsAug 7#310
Job detail stopped fetching the same estimate twice
Duplicate estimate queries cut and the $0 profit flicker on first paint fixed. The number you see on load is now the number, not a placeholder that corrects itself a moment later.
- SpeedJobsAug 7#325
144 dead symbols deleted from the job workspace
JobWorkspaceClient went from 3418 to 2334 lines. No behavior change, which is the point: every one of those symbols was reachable-looking code that nothing called.
- FixFinancialsAug 7#319
Client-facing prices show cents
Portal, proposals and the estimate table were rounding, so a $12,847.50 bid presented itself as $12,848 to the homeowner. Cents render everywhere a client can see a number.
- FixMobileAug 7#326
Dialogs stay inside the screen at every width
Edit dialogs poked past the viewport on phones, putting the save button somewhere you could not reach. Every dialog is now contained down to 390px.
- FeatureScheduleAug 6#318
The desktop schedule has a Week View
Timeline, Week, Month. Each day shows tasks in an all-day band with the job name, and events on an hour grid in the job's own timezone. The month view gained layer filters that persist per device, and tasks stopped hiding behind "+N more" on busy days.
- FixFieldAug 6#320
Field logs survive a deploy mid-session
Submitting a field log after a deploy landed hit Server Action version skew and failed. The submit path now recovers instead of dropping what was typed.
- FeatureJobsAug 5#315
Tasks can carry a time of day, not just a date
A "9:00 AM" chip on /tasks rows and Home tiles, same-day sorting by time, and an optional time field in quick-add and edit that unlocks once a due date is set.
- FixScheduleAug 5#303
Dates typed into the Gantt actually save now
The inline Start and End cells on the Timeline's left grid accepted an edit, rendered it, and silently discarded it. Silent write loss, the worst kind: nothing to report because the screen agreed with you.
- FixScheduleAug 5#309
Schedule dates render in local time
Every date on the Timeline rendered one day early for anyone west of Greenwich, which is every California contractor using this. Dates now render in local time and the date columns line up with the grid.
- FixScheduleAug 5#305
Task names have room to breathe in the Gantt
Hover actions moved onto an overlay, the drag grip shrank, padding tightened. Edit and Duplicate also became keyboard-reachable: they had only ever rendered while a pointer hovered the row, so they were never in the DOM for a keyboard or a screen reader.
- FixPlatformAug 5#311
Rejected emails stop reporting themselves as sent
The Resend response was never checked, so a rejected send returned success all the way up the stack. Failures are now surfaced instead of swallowed.
- FixPlatformAug 4#306
Scheduled jobs run again
Vercel Cron issues GET; the cron routes only accepted POST and answered 405. Every scheduled job had been failing silently at the edge.
- FixAIAug 4#307
A blank model env var no longer becomes an empty model id
`??` only falls back on null or undefined, never on an empty string, so a blank variable sent an empty model id straight to the provider. Blank now reads as unset and the default applies.
- FixPlatformAug 3#296
Old sign-in links work again
Bookmarks, indexed pages and links from the old marketing site still pointed at /sign-in and /sign-up. Both now permanently redirect to their /auth equivalents instead of 404ing.
- FixScheduleAug 3#291
Long task names stop painting over their neighbors
A task named something like "Permit Issuance Wait, Sonoma County" overflowed its row and rendered on top of the rows above and below it. Names truncate now, full text on hover.
- FixHomeAug 3#285
Home is the first row in the sidebar
Tasks rendered pinned above every group header, which put it above Home and left it as the only item outside a group. Home moved to the top and Tasks moved into Work, where it belongs.
- FixMobileAug 3#286
Home's tappable targets look tappable
Two controls on Home read as plain text on a phone. Every cue that marked them interactive was hover-only, and a touch device has no hover, so on mobile they were invisible affordances.
Permissions, polish & the labels rule
Jul 29 – Aug 2 · 5 ships- FixPlatformJul 31#275
Removing a team member works, for the first time
It had never worked. The code wrote a status value absent from the database enum, so Postgres rejected every removal with 22P02 and the failure surfaced as nothing at all. Removal now writes a valid status, frees the seat it was holding, and records who removed whom and when. Restore is there too.
- FeaturePlatformJul 29#244
The in-app system map is something you can click through
Four phases top to bottom across the full job lifecycle, replacing a 12-node straight line written two product generations ago. Five surfaces carry an explicit AI label, and flag-gated work is left out rather than shown as if it were live.
- FixPlatformJul 29#248
Buttons look clickable again, all 172 of them
Tailwind v4's preflight drops the pointer cursor from every button, so the whole app had been rendering interactive controls with a text caret. Scoped so disabled and aria-disabled controls keep the arrow instead of promising a click that does nothing.
- FixPlatformJul 29#246
The In Progress badge stopped impersonating a button
It shipped as solid Safety Orange with Ink text, the exact fill reserved for the primary action on a screen. Now a 20% tint with a hairline. Solid orange means one thing: the action.
- FixScheduleJul 29#256
Blocked tasks read as blocked
A blocked bar was orange, which on this schedule means in progress. It now carries the Error fill plus a diagonal hazard stripe and a hard Ink edge, so it does not rely on color alone.
Mobile web overhaul
Jul 22 – Jul 28 · 11 ships- FeatureScheduleJul 28#211
A real calendar on your phone
Shipped month and week views with a tap-to-day agenda at phone widths, so checking today's work on site takes a glance instead of pinching a Gantt chart.
- FeatureHomeJul 27#218
Your tasks for today land first on Home
A new Today's Tasks card tops the dashboard with your assigned tasks and personal to-dos due today or overdue, and it collapses away when it's empty.
- FeatureHomeJul 27#222
Job Pipeline folds into stages on your phone
Below 640px the kanban becomes a four-stage accordion with job counts, cutting roughly 3,000px of scrolling while the desktop board stays untouched.
- FeatureNotificationsJul 28#225
Tap your avatar for notifications
On phones the bell is gone and your avatar opens the notifications panel with an unread badge, freeing header width for search.
- FixMobileJul 27#217
Tapping an input stops zooming the page
Fixed the 16px font-size guard that a CSS layer had silently overridden since day one, so focusing search, a field log, or a budget cell on iPhone no longer zooms the screen.
- FixMobileJul 27#216
Drawer labels show up, tap targets hit 44px
Fixed nav labels that painted blank below desktop width, enforced 44px minimums on header icons and drawer rows, and pinned Tasks first in the drawer.
- FixHomeJul 27#219
Home fits your phone, 751px less scrolling
Compact 2x2 KPI tiles, one-line empty states, and a collapsed blocked panel take about 751px of dead space off the dashboard at phone width.
- FixHeaderJul 27#220
One-row header, search results you can read
The phone header collapses to a single row and the search dropdown widens to near full screen, so results stop truncating after a few characters.
- FixMobileJul 27#221
The app shell stops vanishing between pages
Tasks, Clients, Field Logs, and Schedule now render the header and bottom tabs server-side while the page body fills in, instead of blanking the whole shell on every navigation.
- FixScheduleJul 28#224
Gantt week labels you can actually read
Week labels now stride from the measured track width instead of smearing into each other, fixing long schedules on phones and in the client portal alike.
- FixPlatformJul 28#228
Authenticated e2e runs are back
The new bottom tab bar broke every authenticated Playwright run at setup with a strict-mode violation. Fixture selectors are now strict-mode safe.
Walkthroughs, receipts & plan chat
Jul 15 – Jul 21 · 8 ships- FeatureScheduleJul 18#151
Site walkthroughs with calendar invites
Schedule a timed job event or a site walkthrough and Baxie fires an ICS email invite to every attendee, so it drops into their real calendar.
- FeatureMaterialsJul 19#157
Material list with receipt capture
Build a per-job material list, then photograph a supplier receipt and the AI extractor reads the line items and quantities straight into it.
- FeatureAssistantJul 19#155
Plan-aware chat, every answer cites its source
The in-app assistant now reasons across your whole plan and returns inline citations to the exact records it pulled from, so every answer is checkable.
- FeaturePlatformJul 17#132
Add Baxie to your iPhone home screen
Shipped a PWA manifest, a bottom tab bar, and an AI chat sheet, and killed horizontal panning, so Baxie installs and behaves like a native iPhone app.
- FeatureWalkthroughJul 19#158
Job templates + California deposit cap
New jobs auto-populate from a walkthrough template, blocking to-dos surface before they gate progress, and the estimate enforces California's statutory deposit cap.
- SpeedAIJul 18#156
Durable rate limits on every AI workflow
Every AI workflow now enforces a monthly cap through Postgres RPC counters with provider-side backoff, so one heavy tenant can't starve the rest or blow the budget.
- FixDashboardJul 18#152
Today's Schedule stops going blank
Guarded the dashboard against an unmapped task status that threw and blanked the Today's Schedule card.
- FixJobsJul 21#163
Smoother drag on the job board
Rebuilt the pipeline-stage drag on a fixed optimistic cache key so it repaints instantly, and restored the closeout nudge when a job hits the final column.
Bids, materials & schedule polish
Jul 14 – Jul 15 · 4 ships- FeatureMaterialsJul 15#112
Material orders flow into your margin
Create a material PO, receive it, and reconcile it, and committed plus actual cost propagate through to the job's margin with no double entry.
- FixBidsJul 14#113
Awarding a bid works again
Fixed a P0 that blocked awarding a bid, then added manual bid entry, side-by-side leveling, and a transparent writeback into the budget.
- FixScheduleJul 14#109
Reorder your schedule phases and it sticks
Replaced a failing batched upsert (Postgres 23502) with per-row UPDATEs, so dragging phases into a new order persists every time.
- FixJobsJul 14#108
New Job window fits on small laptops
Pinned the New Job modal footer above the fold at 640px and up, so the submit button stays reachable on small laptops.
Draws, budget & mobile
Jul 4 – Jul 11 · 9 ships- FeatureFinancialsJul 4#96
Bills turn into live job costs
Accounts-payable entries now derive per-job actual costs at read time, so the actuals feed updates with no manual reconciliation step.
- FeaturePlatformJul 4#97
Phone experience cleaned up
Reworked the tab strip, action row, and portals so the crew's phone experience holds up on site.
- FeatureScheduleJul 4#95
Draw milestones show on the timeline
Draw milestones now render inline on the Gantt as read-only diamonds, alongside phases and tasks.
- FeatureFinancialsJul 4#94
Delivered POs update the budget
Committed and actual cost from delivered purchase orders wire directly into each job's budget.
- FeatureFinancialsJul 4#92
Draws stay linked to schedule phases
Draws bind to schedule phases through a durable ledger-link UI that survives edits on either side.
- FeatureFinancialsJul 4#90
Attach signed lien waivers to draws
Attach and store executed lien-waiver documents directly against each draw request.
- FeatureMarginJul 4#98
Margin tips shared across your team
Margin-learning card dismissals now sync org-wide through the server, with a recall shelf to bring cards back.
- FeatureEstimatingJul 3#87
Takeoff in one table, approve line by line
Collapsed the takeoff flow into a single table where each line approves independently.
- FeaturePortalJul 3#82
Clients view and sign proposals in their portal
Clients view the proposal inline and e-sign in place, with a fix for the double-sign race condition.
Financials & speed
Jun 28 – Jul 3 · 5 ships- FeatureScheduleJul 3#86
Cleaner schedule drag and instant task add
Drag-to-move snaps to the grid, and new tasks and phases paint instantly via a fixed optimistic cache key.
- FixPlatformJul 3#85
Fits a 13-inch laptop, everywhere
Zero horizontal overflow at 1280×800 across every route, now guarded by an end-to-end test.
- FeatureFinancialsJul 3#83
Financial tab declutter, totals you can trust
Estimate-table polish, ledger totals, column filters, and one consolidated proposal flow.
- FixFieldJul 2#80
On-site weather shows up again
Normalized Open-Meteo geocode queries so on-site weather in field logs stops coming back empty.
- SpeedPlatformJun 28#77
App-wide speed pass
orgContext prefetch, query parallelization, an N+1 kill, and optimistic rendering across the board.