v5.2.0 was a long-running feature wave — Epic I, four native BOQ formats, one regional-exchange import surface. v5.2.2 is the opposite: a tightly-scoped bug-fix release that closes seven small issues a careful user would hit in their first half-hour with the app. Each one is a credibility bug, not a data-loss bug, but the cumulative impression is the same: things should work the way the UI implies they do.
The seven changes
/dashboard route renders the actual page
Follow-up to BUG-215: / was redirecting authenticated users to
/projects, which made DashboardPage unreachable
for everyone. /dashboard is now an explicit route that mounts
DashboardPage directly, so the rollup widgets, project list and
notifications panel show up where the sidebar shortcut promises they will.
Takeoff viewer cancels in-flight pdf.js renders
TakeoffViewerModule previously kicked off a pdf.js
RenderTask on every page change without cancelling the previous
one, so flipping pages fast could paint stale glyphs over the new page or
leave the overlay canvas filled with the previous page’s markups. The
fix mirrors the same pattern already shipped in #233 for
InlinePdfAnnotator: cancel the in-flight task, clear the
overlay, then start the new render.
Validation banner stops lying about empty runs
/validation showed a green “All passed” banner even
when the run produced zero results — e.g. a freshly imported project
before any rules had executed. v5.2.2 gates that banner on
total > 0 so a vacuous-truth zero-rule run no longer reads
as a successful validation pass.
Project widget grid stops 405-ing Change Orders
ProjectWidgets was calling /v1/changeorders/summary
without a trailing slash, and FastAPI was matching it as
{order_id}=summary — serving an HTTP 405 because no
GET handler existed for that synthetic path. Adding the trailing
slash routes the call to the real summary endpoint, and the
dashboard tile renders the change-order rollup it was meant to all along.
Safety Incident response carries the OSHA fields
The safety.IncidentResponse schema was missing six OSHA-recordable
fields that already existed on the underlying model:
osha_recordable, osha_case_number,
days_away, days_restricted,
root_cause_method, and root_cause_tags. The fields
are now exposed end-to-end so the SAF-A3 dashboard, OSHA-300 export and
downstream reporting all see the canonical incident record.
Aria-label backfill on five Page.tsx files
Carry-over from #212: AssembliesPage,
BOQListPage, ContactsPage,
ContractsPage, ProjectsPage and
TakeoffPage gain accessible labels on icon-only buttons and
row-action controls. Screen-reader users no longer hear “button”
on its own and can navigate by action verb instead of guessing what each
unlabelled icon does.
Why this matters
None of these are headline features — a v5.2.x patch never is — but
together they remove a noticeable layer of friction. A dashboard route that
doesn’t resolve to the dashboard, a takeoff page that paints stale
glyphs, a validation banner that congratulates you for doing nothing, a widget
that 405s on a missing trailing slash — each is small in isolation, each
reads as “this product is half-finished” in aggregate. The
backend-API fix on safety.IncidentResponse matters
independently: the SAF-A3 audit fields are part of the regulatory contract on
US sites, so a missing-field response is functionally a missing-record response
for any downstream consumer.
Upgrade
pip install --upgrade openconstructionerp
No Alembic migration in this release — head stays unchanged. The
safety.IncidentResponse change is additive (the columns already
exist on the model and DB), so the only consumer-visible difference is six new
keys appearing on the wire. Frontend ships the route change, the takeoff
cancel-on-unmount fix, the validation banner guard, the trailing-slash
/changeorders/summary/ call, and the aria-label backfill.
Try v5.2.2 today.
Live demo in your browser, or self-host in five minutes. AGPL-3.0, no signup required.