v5.2.8 was a polish wave on top of a one-day release. v5.3.0 is the opposite shape: six unrelated deep dives, each one its own audit and each one shipped with tests. Nothing in this release is a feature in the “new module” sense — everything closes a real bug or a real gap that was visible from a single user session. The cumulative effect is what makes this the cut we’re labelling the last stable release of the 5.x line.
The six bundles
Geo Hub round 2 — storage leaks, accuracy cap, iOS
delete_tileset deleted the DB row and left the actual
tileset bytes orphaned in MinIO. v5.3.0 calls
storage_backend.delete_prefix() first, with a new
sweep_deleted_raster_overlays(older_than_days=30) helper
for retroactive cleanup. The accuracy_m field gets a 10 km
hard cap so a stray fat-finger can’t blow up the whole map.
map_config pushes the development_id filter
into SQL instead of in-Python. And ProjectGeoPage uses
100dvh so the iOS Safari URL bar stops collapsing the map.
Brazil Tier-1 — BRL + NBR 12721 + RPS PDF
From a real user note: “there is no invoice support for BRL”.
v5.3.0 adds BRL to the finance shortlist, ships a
500-line br_invoice_pdf.py renderer with proper prestador /
tomador blocks and retenções (ISS, PIS, COFINS, CSLL, INSS, IRRF), and
two new validation rules — NBR12721ClassificationRequired
and NBR12721ValidSection covering S1–S11 cost groups.
The BOQ importer now recognises nbr and sinapi
codes; São Paulo defaults to SINAPI as its regional cost reference. 15
new tests cover the renderer and the rules.
/login dark-mode contrast
Reported as “buttons under the form are barely visible and the cell
text disappears in dark mode.” Seven scoped overrides on
LoginPage.tsx, no token-level changes: the form column
backdrop drops to dark:bg-[#070912], the demo buttons get
dark:bg-white/[0.06] with a proper hover, the
credential cards get dark:bg-white/[0.07] and
dark:border-white/15, the subtitle is promoted from
tertiary to secondary ink, and the
ArrowUpRight chrome reads at the same weight in both
themes. Light mode is untouched.
/reporting renderer + Daily Diary delete
/reporting had a list of generated reports but no way to
look at one. v5.3.0 adds a View button per row that opens
ReportViewerModal — sandboxed
<iframe srcDoc=...> for the HTML, blob URL for the
new-tab link, distinct error states for 410 (expired) / 404 / network.
Daily Diary entries finally get a Trash2 ghost button gated on
!sealed, wired through useConfirm() with a
danger-styled ConfirmDialog. Four new tests cover the
delete path.
WCAG-AA contrast pass — 51 frontend files
The top axe-core offender across the app was
text-oe-blue on top of bg-oe-blue-subtle
— 3.1:1, below the 4.5:1 AA threshold for normal text. Bulk
rewrite of 51 files and 126 lines moves those pairs to
text-oe-blue-dark, which clears AA on every co-occurrence.
Includes the global project-picker chip in Header.tsx and
the blue variant of Badge.tsx, so the fix lands site-wide,
not just on the original surfaces.
Dashboard rollup + PR #164 + back-catalogue
Dashboard reduces from 13 per-widget requests to 6 via a new
RollupRequest schema with 10 configurable widget IDs and
bounds validation (+136 LOC, 41 tests covering IDOR isolation and
rollup parity). External contribution PR #164 from
@Mourdi59 merged via author-attributed commit
(b169a687) — set_user_module_access was
silently dropping its metadata payload because
SQLAlchemy reserves the attribute name. Three v3 release announcements
backfilled and the broken og:image on
news.html repointed at an image that actually exists on
the VPS.
Why this is the last stable 5.x
The 5.x line opened with the deep-coordination initiative (v5.1.1, file versioning + notification dispatcher + audit trail), settled into a release-every-two-days cadence through v5.2.x, and ends here. None of the bundles in v5.3.0 are speculative — every one of them came out of a user report, an audit pass, or a contributor PR. The stable mark means this is the build we’d pin in production for a customer engagement while the 6.x line lands its bigger architectural moves (multi-tenant RLS, Yjs collaboration on BOQ, marketplace v1).
It also means the surface area we audited explicitly: the storage backend around Geo Hub no longer leaks bytes; the Brazil locale has a real end-to-end invoice path rather than a forced-USD workaround; the most common dark-mode reading problem is gone; the reporting module renders what it generates; the diary entries are deletable; the most-trafficked blue-on-blue contrast pair clears AA; and the dashboard fan-out is half what it was. Tests are green on the wave-touched suites. CI publishes the wheel under Trusted Publishing without manual twine.
Upgrade
pip install --upgrade openconstructionerp
No Alembic migration in this release — head stays at v3144.
Backend ships the BR invoice renderer, two new validation rules, the Geo
Hub storage-sweep helper, the dashboard rollup endpoint, and the metadata
payload fix on set_user_module_access. Frontend ships the
dark-mode LoginPage overrides, the ReportViewerModal,
the Daily Diary delete button, the 100dvh Geo viewport, and
126 lines of text-oe-blue-dark migration across 51 files.
No new modules; module count stays at 116.
Try v5.3.0 today.
Live demo in your browser, or self-host in five minutes. AGPL-3.0, no signup required.