Release Notes
- Version
- 20260601.18
- Built
- 2026-06-01T13:10:44-0700
- Commit
e6abac4c08eea632004c80461b3d189bb29e887d- Commit date
- 2026-06-01T20:09:23Z
Changes in this build
- tz: fix remaining mixed-zone date comparisons (WI #1760 audit follow-up)
History
Release Notes
A running, hand-curated digest of what shipped in Client-Contracts, grouped by calendar month (newest first). Each entry links to its work item, the merging pull request, and the merge commit.
Maintenance. Once a month, an engineer sweeps the merged PRs from git log --merges --first-parent main and prepends a new section to this file. Internal-only changes (CI tweaks, dependency bumps, untracking files) are filtered out; user-visible features and bug fixes are kept. Edits to this file ride in their own PR — there's no auto-generation.
June 2026
- reports/startstop: UTC-pin window + parseDateColumn so 1st-of-month starts show (WI #1759) (PR #2242 ·
8d2421d, Jun 1) - Merge pull request 2242 from bug-1759-startstop-tz into main (PR #2244 ·
7609fcc, Jun 1) - cron: dedup monthly auto-invoice on (contract, month) not end_date (WI #1752) (PR #2234 ·
9f4ee5c, Jun 1) - Merge pull request 2234 from bug-1752-cron-dedup into main (PR #2236 ·
061db8a, Jun 1) - billing: prorate label only when workdays are actually lost (WI #1753) (PR #2230 ·
ae9f3ef, Jun 1) - Merge pull request 2230 from bug-1753-prorated-label into main (PR #2232 ·
0cf8ff0, Jun 1) - clients: degrade gracefully when intuit access is denied (WI #1730) (PR #2225 ·
7fd0676, Jun 1) - Merge pull request 2225 from bug-1730-clients-intuit-fallback into main (PR #2227 ·
42d7a0d, Jun 1) - docs: list app-owned blob containers in README (WI #969) (PR #2216 ·
77d1019, Jun 1) - tz: UTC-pin contractInterval in computeInvoiceAmount (WI #1728) (PR #2220 ·
46ed0f0, Jun 1) - Merge pull request 2220 from bug-1728-mixed-zone-interval into main (PR #2223 ·
e67247c, Jun 1) - tz: migrate date-only render + period-boundary sites to parseDateColumn (WI #1723) (PR #2208 ·
20a6ccb, Jun 1) - Merge pull request 2208 from task-1723-date-render-sweep into main (PR #2211 ·
dab69bf, Jun 1) - tz: add parseDateColumn helper for DATE columns (WI #1722) (PR #2201 ·
ef78add, Jun 1) - Merge pull request 2201 from task-1722-parse-date-column into main (PR #2204 ·
8b69c27, Jun 1) - ci: run Test stage on PRs (WI #1133) (PR #2187 ·
fa39ea2, Jun 1) - tz: pin app process timezone to America/Los_Angeles (WI #991) (PR #2189 ·
a4206d0, Jun 1) - secrets: switch plaintext app settings to @Microsoft.KeyVault refs (WI #1160) (PR #2196 ·
e18955b, Jun 1) - tz: pin date-only column parsing to UTC (WI #1720) (PR #2197 ·
ae69a7f, Jun 1) - Merge pull request 2197 from bug-1720-tz-date-render into main (PR #2200 ·
4975433, Jun 1) - session-secret: adopt portfolio standard via Bicep newGuid() (WI #1576) (PR #2166 ·
7d14428, Jun 1) - bicep: include DOCKER_REGISTRY_SERVER_* in appSettings (WI #1576 follow-up) (PR #2168 ·
0500987, Jun 1) - env: harden .gitignore + add .env.dev.example template (WI #1584) (PR #2173 ·
a3b6c50, Jun 1) - db: switch to dedicated bydrec_client_contracts PG role (WI #1425) (PR #2177 ·
b6e9fad, Jun 1) - pipeline: switch to WIF ACR auth via az acr login (WI #1443) (PR #2179 ·
dadf514, Jun 1) - Merge pull request 2179 from bug-1443-wif-sc-migration into main (PR #2180 ·
65805c6, Jun 1) - Revert "pipeline: switch to WIF ACR auth via az acr login (WI #1443)" (PR #2181 ·
e9dcd54, Jun 1) - Merge pull request 2181 from revert-1443-wif-blocked-on-pt-promote into main (PR #2182 ·
35666f6, Jun 1) - npm: enforce 7-day min-release-age supply-chain policy (WI #1103) (PR #2185 ·
5646a25, Jun 1) - Merge pull request 2185 from bug-1103-min-release-age into main (PR #2186 ·
b37d0dc, Jun 1) - Merge pull request 2186 from main into stg (PR #2188 ·
f45aa66, Jun 1) - charts: swap dead Highcharts CDN to jsdelivr; harden route (WI #1698) (PR #2160 ·
199af58, Jun 1) - Merge pull request 2160 from bug-1698-monthly-contracts-charts into main (PR #2161 ·
091d088, Jun 1) - Merge pull request 2161 from main into stg (PR #2162 ·
8bad862, Jun 1)
May 2026
- #1526 — deps: bump @bydrec/prisma-schema 1.14.0 → 1.16.0 (cosmos_id-free) (WI #1526) (PR #1999 ·
d6b1363, May 25) - Merge pull request 1999 from issue-1526-prisma-schema-1.16-cosmos-id into main (PR #2000 ·
96e8b13, May 25) - Merge pull request 2000 from main into stg (PR #2002 ·
b8cbd82, May 25) - #995 — billing: skip cancelled contracts in every invoice-generation path (WI #995) (PR #1542 ·
91b6077, May 16) - Merge pull request 1542 from issue-995-skip-cancelled-contracts into main (PR #1825 ·
4de392b, May 16) - Merge pull request 1825 from main into stg (PR #1827 ·
ae56ac3, May 16) - #1197 — helmet: set Referrer-Policy to same-origin so redirect('back') works (WI #1197) (PR #1816 ·
dd38d28, May 16) - Merge pull request 1816 from issue-1197-helmet-referrer-policy into main (PR #1817 ·
912e3d6, May 16) - Merge pull request 1817 from main into stg (PR #1819 ·
a66b44b, May 16) - #973 — contract-invoice: polish UI to match client-invoice page (WI #973) (PR #1813 ·
bbf5e14, May 16) - Merge pull request 1813 from issue-973-contract-invoice-polish into main (PR #1814 ·
a55361b, May 16) - Merge pull request 1814 from main into stg (PR #1815 ·
c1df7a1, May 16) - invoices: include adjustments + billed absences in /invoices totals (PR #1539 ·
69736a3, May 1) - Merge pull request 1539 from fix-invoices-page-total-includes-adjustments-and-absences into main (PR #1540 ·
77249db, May 1) - Merge pull request 1540 from main into stg (PR #1541 ·
b7570b8, May 1) - #990 — invoices: explain holiday/vacation deductions inline (WI #990) (PR #1536 ·
7ac03a4, May 1) - Merge pull request 1536 from issue-990-deduction-notes into main (PR #1537 ·
99ceb1f, May 1) - Merge pull request 1537 from main into stg (PR #1538 ·
1114659, May 1)
April 2026
- #987 — month selectors: include current month on the last day (WI #987) (PR #1532 ·
396ddf5, Apr 30) - Merge pull request 1532 from issue-987-current-month-selectors into main (PR #1533 ·
0e38151, Apr 30) - Merge pull request 1533 from main into stg (PR #1534 ·
9714a6c, Apr 30) - #989 — client-invoices: add Status column derived from QB + line states (WI #989) (PR #1529 ·
ccb24dc, Apr 30) - Merge pull request 1529 from issue-989-client-invoice-status-column into main (PR #1530 ·
ca14e56, Apr 30) - Merge pull request 1530 from main into stg (PR #1531 ·
0d9fefc, Apr 30) - #988 — client-invoice: sortable column headers on the invoice-line table (WI #988) (PR #1526 ·
2b4b005, Apr 30) - Merge pull request 1526 from issue-988-client-invoice-sort into main (PR #1527 ·
433f3dd, Apr 30) - Merge pull request 1527 from main into stg (PR #1528 ·
8fd9b59, Apr 30) - #987 — fix: include current month in close-out dropdown on last day of month (PR #1523 ·
505eeb2, Apr 30) - Merge pull request 1523 from issue-987 into main (PR #1524 ·
d9ca4ef, Apr 30) - Merge pull request 1524 from main into stg (PR #1525 ·
e354037, Apr 30) - #974 — ui: dynamic per-page
tags (WI #974) (PR #1496 · 396835f, Apr 28) - Merge pull request 1496 from issue-974-dynamic-page-titles into main (PR #1497 ·
798ab60, Apr 28) - Merge pull request 1497 from main into stg (PR #1498 ·
bf4f1ad, Apr 28) - Revert "Merge pull request 1490 from issue-967-wire-holiday-worked into main" (PR #1493 ·
50b7fac, Apr 28) - Merge pull request 1493 from revert-967-wrong-repo into main (PR #1494 ·
bc40d7e, Apr 28) - Merge pull request 1494 from main into stg (PR #1495 ·
faf64c2, Apr 28) - #967 — billing: wire HolidayWorked into deduction path + UI (WI #967) (PR #1490 ·
f608853, Apr 28) - Merge pull request 1490 from issue-967-wire-holiday-worked into main (PR #1491 ·
3fbb2ec, Apr 28) - Merge pull request 1491 from main into stg (PR #1492 ·
7e4c6c2, Apr 28) - client-invoice: move attachments scope from bundle → line (PR #1484 ·
706b850, Apr 27) - Merge pull request 1484 from fix-invoice-attachments-line-scope into main (PR #1485 ·
75012f2, Apr 27) - Merge pull request 1485 from main into stg (PR #1486 ·
eb5d442, Apr 27) - #942 — Bydrec-Mail MCP server (WI #942) (PR #1479 ·
2281267, Apr 26) - #942 — mcp-mail: persist finish-rbac.ps1 in the repo (WI #942) (PR #1480 ·
b8d825b, Apr 26) - #968 — client-invoice: support attachments via invoicedocs blob container (WI #968) (PR #1481 ·
b501366, Apr 27) - #946 — qbReconciliation: per-resource breakdown UI + admin recompute (WI #946 phase 2b) (PR #1478 ·
f7a58a9, Apr 26) - #946 — qbAttribution: persistence + batch recompute (WI #946 phase 2a) (PR #1477 ·
baed0c2, Apr 26) - #946 — qbAttribution: add algorithm + eval harness (WI #946 phase 1) (PR #1474 ·
151e931, Apr 26) - #937 — contracts: support per-contract billable_monthly_hours (WI #937) (PR #1472 ·
d3a088c, Apr 26) - #933 — client-invoice: support supplemental / manual line items (WI #933) (PR #1465 ·
def3d25, Apr 26) - ci: switch NodeTool@0 → UseNode@1 to clear the deprecation warning (PR #1466 ·
ac20ad1, Apr 26) A major month — billing-model overhaul, QuickBooks reconciliation, RBAC foundation, and a long tail of UI / data-quality improvements.
Billing model
- #935 — refresh
/billing-methodologyto match current logic (PR #1453 ·35dedea, Apr 24) - #934 — billing: honor
paid_holidays/paid_vacationon monthly contracts (PR #1425 ·d6a7a4d, Apr 22) - #930 — billing:
computeAbsenceCosthonorsPRORATION_CUTOFF(PR #1417 ·3fdf3f7, Apr 21) - #901 — billing: honor
paid_holidays/paid_vacationon daily / hourly contracts (PR #1395 ·da5ad44, Apr 21) - #900 — billing: apply
PRORATION_CUTOFFonly to monthly contracts (PR #1392 ·5fbc884, Apr 20) - #899 — billing: refactor daily / hourly to hours-first (PR #1389 ·
7988925, Apr 20) - #898 — fix: daily / hourly
daysWorkeduses absence / vacation hours, not row count (PR #1388 ·fc10f55, Apr 20) - #897 — billing: unify daily / hourly math (
daysWorked = weekdays − holidays − absences − vacation) (PR #1387 ·3ee7eea, Apr 20) - #896 — UI: hide
paid_holidays/paid_vacationin forms, pages, and reports while the model stabilized (PR #1386 ·94f4856, Apr 20) - #874 — billing: mirror billable
resource.InvoiceAdjustmentrows onto invoices (PR #1369 ·7d4a6ff, Apr 18) - #879 — billing: absences tracked on
resource.Absence(billed_at), not adjustments (PR #1360 ·f15e72a, Apr 18) - #863 — billing: proration formula cutoff at
2026-04-01(PR #1343 ·75c408f, Apr 17) - #847 — invoices: unified billing model — derive calculation from rate type; deprecate
proration_scheme(PR #1313 ·55218b7, Apr 16)
QuickBooks reconciliation
- #948 — QB reconciliation: per-client mismatch totals (PR #1447 ·
3cc7dba, Apr 24) - #940 — resource Gantt: link resource-contract bars to provider app (PR #1448 ·
e0e4215, Apr 24) - #938 — QB reconciliation: link Invoice # to ClientInvoice + default-sort by Invoice # (PR #1449 ·
6067c2b, Apr 24) - #943 — closeOut: number new invoices from
MAX(existing) + 1, notcount + 1(PR #1435 ·a381b81, Apr 23) - #929 — qbRecon: use
client.qb_idfor explicit client↔QB customer mapping (PR #1414 ·620fc88, Apr 21) - #927 — qbRecon: join
intuit.Customeronqb_id, notid(PR #1408 ·a7ea309, Apr 21) - #908 — qbRecon: annotate mismatches to preserve investigation findings (PR #1404 ·
827e349, Apr 21) - #906 — qbRecon: subtract billed absences when computing
dbTotal(PR #1398 ·db686a6, Apr 21) - #846 — reports: QuickBooks reconciliation report (PR #1312 ·
7c5df6f, Apr 16) - #848 — reports: import missing invoices from QuickBooks per client (PR #1316 ·
777dfe3, Apr 16) - fix: QB reconciliation
doc_numbermatching independent of customer match (PR #1321 ·2eea4e7, Apr 16) - reports: add client filter to QB reconciliation report (PR #1317 ·
c70e58c, Apr 16)
Reports & access control
- #904 — reports: add Contracts Missing SOW report (PR #1450 ·
585deac, Apr 24) - #947 — DataTables: rename
data-sortattr →data-orderand parse ISO dates so default sorting actually works (PR #1438 ·0533a3b, PR #1441 ·ed6f57d, Apr 24) - #764 — RBAC: per-user report access (admin-granted) (PR #1333 ·
bda0938, Apr 17) - #764 — RBAC: add three-tier role hierarchy (Admin > User > Commenter) (PR #1328 ·
ea826bc, Apr 16)
Invoice & contract UX
- #903 — client: allow uploading an MSA PDF (PR #1452 ·
60c94dc, Apr 24) - #902 — blobs: redirect back to parent record after upload / delete (PR #1451 ·
04d7052, Apr 24) - #931 — resource Gantt: min-width + border for very short contracts (PR #1422 ·
9eb65b3, Apr 22) - #886 — fix: contract invoice page shows Final Amount after absences (PR #1366 ·
0ca263a, Apr 18) - #885 — fix: client-invoice Details footer used wrong context for absences total (PR #1365 ·
26f5bbc, Apr 18) - #884 — fix: delete confirms prompt twice on form-based delete buttons (PR #1364 ·
1538942, Apr 18) - #883 — invoices: gate contract-invoice delete button + improve confirm message (PR #1363 ·
fa12f14, Apr 18) - #882 — invoices: add Delete invoice button on the client invoice page (PR #1362 ·
276ce78, Apr 18) - #881 — fix: store actual service period on close-out invoices (PR #1361 ·
d987230, Apr 18) - #875 — fix: contract invoice page was double-counting absence deductions (PR #1357 ·
ba59d5d, Apr 17) - #877 — fix: cascade-delete adjustments when deleting a contract invoice (PR #1356 ·
499ad46, Apr 17) - #872 — invoices: rename Comments column header "Comment" to "Details" (PR #1353 ·
b06a6d0, Apr 17) - #866 — invoices: show billable units (days / hours) for daily & hourly lines (PR #1352 ·
e5edaac, Apr 17) - #871 — invoices: add Total column to the client invoices list (PR #1351 ·
28c77d8, Apr 17) - #869 — invoices: mark prorated lines with
(prorated, date - date)note (PR #1349 ·5a75071, Apr 17) - #868 — invoices: add Comments section header on the client invoice page (PR #1348 ·
e033e9d, Apr 17) - #867 — invoices: hide Dept Code table when no lines have a dept code (PR #1347 ·
3090058, Apr 17) - #865 — invoices: surface adjustments and absences on the client invoice page (PR #1346 ·
0c51aa6, Apr 17) - #864 — invoices: itemize absences on the contract invoice page (PR #1345 ·
67307f1, Apr 17) - fix: contract invoice detail page crash on missing resource contract (PR #1344 ·
d92aede, Apr 17) - #849 — invoices: add ability to approve draft invoices (PR #1319 ·
f549c40, Apr 16) - #836 — invoices: add bulk generation for a date range per client (PR #1318 ·
8461598, Apr 16) - #150 — invoices: custom message block for client invoices (PR #1309 ·
90e1ecf, Apr 15) - #838 — invoices: split client invoices by
invoice_groupon close-out, surface group on contract detail (PR #1297, PR #1298, Apr 14) - #836 — invoices: add per-client and global monthly close-out actions (PR #1292, PR #1293, Apr 14)
- #835 — invoices: add status /
generated_byfields, monthly auto-generation cron, status & source badges (PR #1289, PR #1290, PR #1291, Apr 14) - fix: stack action buttons into rows on client-invoices page (PR #1320 ·
f46001d, Apr 16) - fix: zero-pad invoice numbers to 4 digits (e.g.
YELL-0001, notYELL-1) (PR #1322 ·d391560, Apr 16) - #281 — feat: add typeahead suggestions for contract team field (PR #1282, Apr 13)
- fix: redirect to contract page after update instead of using
back(PR #1283, Apr 13)
Security & infra
- #275 — security: obfuscate stored PDF file names with UUIDs (PR #1315 ·
e98660c, Apr 16) - #828 — security: enable Content Security Policy in report-only mode (PR #1310, Apr 15)
- #845 — CSP phase-1 follow-up (PR #1355 ·
1334665, Apr 17) - #855 — infra: derive
SESSION_SECRETfromuniqueString(resourceGroup().id)(PR #1354 ·ae2e50c, Apr 17) - #369 — fix: remove insecure TLS bypass from email transport (PR #1281, Apr 13)
- #829 — auth: redirect unauthenticated users to sign-in instead of returning 401 (PR #1277, Apr 13)
- #870 — auth: add dev-only auth bypass via
X-Dev-Userheader (PR #1350 ·50a0133, Apr 17) - #841 — cleanup: remove
cosmos_idreferences from contract renew (PR #1327, Apr 16) - #851 — contracts: add
cancelledflag, skip cancelled from billing (PR #1325, Apr 16) - fix: coerce
cancelledcheckbox value to Boolean for Prisma (PR #1330 ·a930b0a, Apr 16) - #769 — test: add Jest framework and baseline test coverage (PR #1280, Apr 13)
- #767 — reliability: add distributed lock for in-process cron jobs (PR #1247, Apr 11)
Release-notes plumbing (this page)
- #829 — release-notes: pipeline generates
build-info.jsonand applies OCI labels (PR #1254, Apr 12) - #829 — release-notes: render with layout and expose build info (PR #1253, Apr 12)
March 2026
Quiet month — branch sync to prd only, no feature merges.
October 2025
- New report: Paid Vacation (Oct 30)
July 2025
- #398 — Client Invoice List and Client Invoice Detail (PR #711, Jul 29)
May 2025
- #184 — audit logging: contract comments and discounts (PR #673, May 7)
- charts: remove decimals from y-axis (May 10)
April 2025
- Add Redis session store and logging utility (Apr 2)
December 2024
- invoices: add invoice sections (PR #596, Dec 9)
November 2024
- delivery cost: total by month (Nov 24)
- delivery cost: per-month breakdown (Nov 22)
- delivery cost: column + total in main table (Nov 18)
- add Payments section (Nov 6)
- client export to spreadsheet (Nov 1)
October 2024
- fix month charts (Oct 28)
- replace Contract Start with Margin % column (Oct 24)
- export all contracts (Oct 7)
September 2024
- #291 — margin percent column (Sep 19)
- alternative charting libraries (Sep 12)
- filter comments by service date (Sep 11)
- export to spreadsheet on additional reports (Sep 11)
- filter contracts longer than one year (Sep 11)
August 2024
- monthly contracts report fixes (Aug 7)
- rename of monthly contracts report (Aug 3)
July 2024
- set up CI with Azure Pipelines (Jul 15)
May 2024
- support daily and hourly rate types (May 4)
Earlier (2021–2022)
Project foundation: initial CI setup, admin group bootstrapping, and miscellaneous early commits. Not individually catalogued — git log --first-parent main is the source of truth for that period.