• v0.4.0 5375b6661a

    v0.4.0
    All checks were successful
    Build OCI container / Build and push mokosh-www image (push) Successful in 3m4s
    Stable

    David released this 2026-06-30 16:07:36 +02:00 | 336 commits to main since this release

    Changelog

    0bb25c7 Merge pull request 'Release v0.4.0' (#386) from release/v0.4.0 into main
    bb7498b Release v0.4.0
    6bc1e5c Merge pull request 'fix(auth): revoke refresh token on logout + strip code/state from URL on callback' (#385) from fix/MAPPS-336-spa-logout-revoke-url-strip into main
    a90175f Merge pull request 'fix(spa): SPA hardening cluster (state/nonce, dev-bypass feature, pending TTL, CSP, doc)' (#384) from fix/MAPPS-338-spa-hardening-cluster into main
    80726af fix(spa): SPA hardening cluster (state/nonce, dev-bypass feature, pending TTL, CSP, doc)
    69d9847 Merge pull request 'feat(status): app-wide server-unreachable banner with recovery poll (MAPPS-333)' (#383) from feat/MAPPS-333-server-unreachable-banner into main
    4599b20 Merge branch 'main' into feat/MAPPS-333-server-unreachable-banner
    f162160 feat(status): app-wide server-unreachable banner with recovery poll
    464d60b fix(auth): revoke refresh token on logout + strip code/state from URL on callback
    71e475c Merge pull request 'fix(dev): point SPA API proxy at server:8080 not 4301' (#382) from fix/dev-server-proxy-port into main
    8525a42 fix(dev): point SPA API proxy at server:8080 not 4301
    2fff3db Merge pull request 'fix(time): make the Billable checkbox toggle reliably (PMS-571)' (#381) from fix/PMS-571-checkbox-toggle into main
    6004f95 fix(time): make the Billable checkbox toggle reliably (PMS-571)
    a913a29 Merge pull request 'fix(profile): surface the real /auth/me failure mode in the error banner' (#380) from fix/MAPPS-331-profile-load-error into main
    5f9b94c fix(profile): surface the real /auth/me failure mode in the error banner
    1d17a82 Merge pull request 'fix(dev): bind dx serve to a private LAN IP only' (#378) from fix/MAPPS-dev-bind-private-ip into main
    32a1021 fix(dev): bind dx serve to a private LAN IP only
    b3be9b8 Merge pull request 'fix(billing): constrain New Tax Rate Rate (%) and Name inputs (MAPPS-220)' (#375) from fix/MAPPS-220-tax-rate-input-constraints into main
    1ce3a52 Merge pull request 'fix(ci): derive publish mode from trigger to kill latest overwrite race' (#373) from fix/GOV-15-twin-trigger-publish-mode into main
    2d6eaba fix(billing): constrain New Tax Rate Rate (%) and Name inputs (MAPPS-220)
    8b55697 Merge branch 'main' into fix/GOV-15-twin-trigger-publish-mode
    30032b0 Merge pull request 'Revamp the Mokosh landing page with the mascot hero + tagline' (#364) from feat/MAPPS-327-landing-revamp into main
    657d49a Merge branch 'main' into feat/MAPPS-327-landing-revamp
    b9f885f Merge branch 'main' into fix/GOV-15-twin-trigger-publish-mode
    20c3418 Merge pull request 'fix(security): triage mokosh-apps audit roll-up findings (MAPPS-308)' (#374) from security/MAPPS-308-audit-rollup-triage into main
    ef4cdae fix(security): triage mokosh-apps audit roll-up findings (MAPPS-308)
    9e5f9a5 fix(ci): derive publish mode from trigger to kill latest overwrite race
    fcb986a Merge pull request 'fix(tickets): enforce required Company/Description inline on ticket forms (MAPPS-322)' (#372) from fix/MAPPS-322-enforce-required-ticket-fields into main
    f111ea0 fix(tickets): enforce required Company/Description inline on ticket forms (MAPPS-322)
    97db4d6 Merge pull request 'fix(ci): route dispatcher pr_number through env in remaining run steps (MAPPS-306)' (#371) from fix/MAPPS-306-pr-number-injection into main
    3db1424 fix(ci): route dispatcher pr_number through env in remaining run steps (MAPPS-306)
    117d01e Merge pull request 'fix(ci): pass untrusted PR data via env to block shell injection (MAPPS-307)' (#370) from fix/MAPPS-307-shell-injection-pr-title into main
    ecf1076 fix(ci): pass untrusted PR data via env to block shell injection (MAPPS-307)
    b58d469 Merge pull request 'docs(rollout): add SPA-rollout runbook to prevent two-build LB skew (MAPPS-315)' (#369) from docs/MAPPS-315-spa-rollout-runbook into main
    d0c8498 docs(rollout): add SPA-rollout runbook to prevent two-build LB skew (MAPPS-315)
    e06874a Merge pull request 'feat(profile,nav): Mokosh Role label + Team nav behind runtime feature flag (MAPPS-329)' (#368) from feat/MAPPS-329-mokosh-role-label-team-flag into main
    c7f28c6 feat(profile,nav): Mokosh Role label + Team nav behind runtime feature flag (MAPPS-329)
    a0ea058 Merge pull request 'fix(pickers): set off '+ Create' row in its own band (MAPPS-320)' (#367) from fix/MAPPS-320-create-row-visual-separation into main
    5861521 fix(pickers): set off '+ Create' row in its own band (MAPPS-320)
    69aaa1c Merge pull request 'feat(calendar): click an empty day cell to open New Appointment pre-filled (MAPPS-319)' (#365) from feat/MAPPS-319-calendar-cell-click into main
    f021b14 Merge pull request 'feat(routes): wrap Outlet in ErrorBoundary with recoverable fallback (MAPPS-318)' (#363) from feat/MAPPS-318-route-error-boundary into main
    b8c7180 Merge pull request 'fix(auth): gate AuthGuard onboarding redirect on /me reconcile (MAPPS-317)' (#362) from fix/MAPPS-317-calendar-bounce-router-guard into main
    8fb08d1 feat(landing): revamp the Mokosh landing with the mascot hero
    f83f524 feat(calendar): click an empty day cell to open New Appointment pre-filled (MAPPS-319)
    c08209c feat(routes): wrap Outlet in ErrorBoundary with recoverable fallback (MAPPS-318)
    4c4cd3d fix(auth): gate AuthGuard onboarding redirect on /me reconcile (MAPPS-317)
    cab4b6d Merge pull request 'Remove the Apps launcher link from the user-menu dropdown' (#360) from feat/MAPPS-324-remove-apps-button into main
    c091cf1 Merge branch 'main' into feat/MAPPS-324-remove-apps-button
    2bce2f3 Merge pull request 'ci(oci): switch build cache from registry to runner gha cache' (#361) from feat/MAPPS-326-oci-gha-build-cache into main
    0665fb4 ci(oci): switch build cache from registry to runner gha cache
    d459f16 Merge pull request 'feat(lists): visible company-scope chip on every list page (MAPPS-321)' (#346) from fix/MAPPS-321-context-filter-banner into main
    9c18c51 Merge branch 'main' into fix/MAPPS-321-context-filter-banner
    58e0291 Merge pull request 'feat(settings): consistent card sizing and section color-coding' (#279) from feat/MAPPS-257-settings-card-consistency-color-coding into main
    a9a14f4 Merge branch 'main' into feat/MAPPS-257-settings-card-consistency-color-coding
    f1fa0a5 feat(layout): hide the Apps launcher link in the user menu
    d4a2740 Merge pull request 'feat(dashboard): full-screen team-scoped TV-view dashboard mode' (#280) from feat/MAPPS-256-tv-view-dashboard into main
    ebe9696 fix(merge): restore TV-view content dropped by the main merge
    9f24883 Merge branch 'main' into feat/MAPPS-256-tv-view-dashboard
    e751b56 Merge branch 'main' into fix/MAPPS-321-context-filter-banner
    0cc56cc Merge pull request 'fix(auth): preserve deep-link route across cold-load re-auth (MAPPS-323)' (#359) from fix/MAPPS-323-deeplink-return-to into main
    20dc5ab fix(auth): keep /dashboard soft on re-auth + unit-test return_to (MAPPS-323)
    221191e fix(auth): preserve deep-link route across cold-load re-auth (MAPPS-323)
    ccb3f40 Merge pull request 'docs(forms): mark PMS-518 migration complete in the audit doc' (#358) from docs/PMS-518-audit-progress into main
    43d0381 Merge pull request 'refactor(forms): report-all errors on contacts + asset-edit forms (PMS-518)' (#357) from feat/PMS-518-report-all-polish into main
    dd70e55 docs(forms): mark the PMS-518 migration complete in the audit doc
    f5ccf55 Merge pull request 'feat(contracts): focus-first-invalid on the contract form via FormGuard (PMS-518)' (#355) from feat/PMS-518-migrate-contracts-form into main
    402d0ff refactor(forms): make contacts + asset-edit forms report all errors at once (PMS-518)
    baf92f4 Merge pull request 'feat(billing): migrate New Invoice form to FormGuard (PMS-518)' (#354) from feat/PMS-518-migrate-billing-form into main
    b28b8bd Merge pull request 'feat(forms): migrate remaining create/edit forms to FormGuard (PMS-518)' (#356) from feat/PMS-518-remaining-forms into main
    cc705c4 feat(contracts): migrate the contract modals to FormGuard (PMS-518)
    f770dc0 feat(billing): migrate the billing modals to FormGuard (PMS-518)
    f9c3720 feat(forms): migrate the remaining create/edit forms to FormGuard (PMS-518)
    64d94b5 Merge pull request 'feat(kb): migrate KB article + category forms to FormGuard (PMS-518)' (#353) from feat/PMS-518-migrate-kb-forms into main
    59d080e feat(contracts): add focus-first-invalid to the contract form via FormGuard (PMS-518)
    0083a28 feat(billing): migrate New Invoice form to FormGuard (PMS-518)
    a4be7c8 Merge pull request 'feat(tickets): migrate new-ticket form to FormGuard, enforce Description (PMS-518)' (#352) from feat/PMS-518-migrate-ticket-time-forms into main
    41375fb feat(kb): migrate KB article + category forms to FormGuard (PMS-518)
    815c4f8 feat(time): migrate log-time form to FormGuard, enforce Description (PMS-518)
    9eaf450 feat(tickets): migrate new-ticket form to FormGuard, enforce Description (PMS-518)
    64d9de9 Merge pull request 'feat(forms): shared FormGuard submit guard (PMS-517)' (#351) from feat/PMS-517-form-submit-guard into main
    39c1210 feat(forms): shared FormGuard submit guard (PMS-517)
    748d401 Merge pull request 'feat(forms): component-owned field validation + shared validator set (PMS-516)' (#350) from feat/PMS-516-form-validation-layer into main
    55d7c5e feat(forms): component-owned field validation + shared validator set (PMS-516)
    b015412 Merge pull request 'docs(forms): PMS-515 form-validation audit and decomposition' (#349) from docs/PMS-515-form-validation-audit into main
    9cf48d2 docs(forms): add PMS-515 form-validation audit and decomposition
    0ae342e Merge pull request 'fix(tickets): flag every missing required field on new-ticket submit (PMS-514)' (#348) from fix/PMS-514-ticket-form-validate-all-required into main
    5c5e8fd fix(tickets): flag every missing required field on new-ticket submit
    079f7de Merge pull request 'fix(team): hide invite role picker until RBAC is complete (PMS-513)' (#347) from fix/PMS-513-disable-role-assignment-ui into main
    c7e0581 fix(team): hide invite role picker until RBAC is complete
    b534782 Merge pull request 'fix(companies): render every site on the company detail Sites card (MAPPS-316)' (#345) from fix/MAPPS-316-sites-card-show-all into main
    7d05c7a feat(lists): visible company-scope chip on every list page (MAPPS-321)
    4eb31a4 fix(companies): render every site on the company detail Sites card (MAPPS-316)
    e5712d9 Merge pull request 'feat(a11y): GlobalSearch aria-label + theme button aria-expanded (MAPPS-314)' (#344) from fix/MAPPS-314-a11y-polish into main
    4b98b05 Merge pull request 'feat(toasts): auto-dismiss Success/Info after 5s; keep Warning/Error sticky (MAPPS-312)' (#343) from fix/MAPPS-312-toast-auto-dismiss into main
    bc76fbd Merge pull request 'feat(kb): article delete UI on the detail page (MAPPS-309)' (#342) from fix/MAPPS-309-kb-article-delete into main
    a9e3ba3 Merge pull request 'feat(consistency): ticket-detail Delete + assets bulk-delete (MAPPS-313)' (#341) from fix/MAPPS-313-delete-affordances into main
    0c75ffb Merge pull request 'fix(tickets): bulk-delete now confirms via ConfirmDialog (MAPPS-310)' (#340) from fix/MAPPS-310-ticket-bulk-delete-confirm into main
    0d362bb Merge pull request 'fix(calendar): hoist timezone reads out of use_signal initialisers (MAPPS-299)' (#339) from fix/MAPPS-299-calendar-hook-violation into main
    9a2cac8 feat(a11y): GlobalSearch aria-label + theme button aria-expanded (MAPPS-314)
    9297e2f feat(toasts): auto-dismiss Success/Info after 5s; keep Warning/Error sticky (MAPPS-312)
    1bf7460 feat(consistency): ticket-detail Delete + assets bulk-delete (MAPPS-313)
    97821f6 feat(kb): article delete UI on the detail page (MAPPS-309)
    e00902d fix(tickets): bulk-delete now confirms via ConfirmDialog (MAPPS-310)
    2371173 fix(calendar): hoist timezone reads out of use_signal initialisers (MAPPS-299)
    656f357 Merge pull request 'feat(timesheets): admin status filter + multi-week range + history rows (PMS-506)' (#338) from feat/PMS-506-timesheet-history-client into main
    a665a7a feat(timesheets): admin status filter + multi-week range + history rows (PMS-506)
    9160fa7 Merge pull request 'feat(oidc): runtime MOKOSH_OIDC_SCOPES override for SPA scope query (BUNYIP-142)' (#337) from feat/BUNYIP-142-runtime-oidc-scopes into main
    a7a6e38 Merge pull request 'feat(reports): SVG bar chart on every report detail page (MAPPS-297)' (#336) from feat/MAPPS-297-report-charts into main
    51ffb57 Merge pull request 'fix/MAPPS-304-asset-save-spurious-error' (#335) from fix/MAPPS-304-asset-save-spurious-error into main
    2990f4d Merge pull request 'feat(approvals): ticket-detail Approvals section + top-bar badge (PMS-486)' (#334) from feat/PMS-486-approvals-tab-and-badge into main
    6bcfb19 Merge pull request 'feat(kb): Top ticket-driving articles widget on landing page (PMS-485)' (#333) from feat/PMS-485-kb-top-driving into main
    f628aaf Merge pull request 'feat(dashboards): SPA widget view surface for saved layouts (PMS-472)' (#331) from feat/PMS-472-dashboard-view-surface into main
    612fc25 feat(oidc): runtime MOKOSH_OIDC_SCOPES override for SPA scope query (BUNYIP-142)
    a8da01f Merge pull request 'feat(dashboards): editor + per-widget data fetches (PMS-487)' (#332) from feat/PMS-487-dashboard-editor into feat/PMS-472-dashboard-view-surface
    f10dc81 feat(reports): SVG bar chart on every report detail page (MAPPS-297)
    1cfb097 fix(assets): treat post-save decode quirks as success on the edit modal (MAPPS-304)
    dabbe6b feat(approvals): ticket-detail Approvals section + top-bar badge (PMS-486)
    e8fc481 feat(kb): Top ticket-driving articles widget on landing page (PMS-485)
    a3a06f5 feat(dashboards): editor + per-widget data fetches (PMS-487)
    44bb5de feat(dashboards): SPA widget view surface for saved layouts (PMS-472)
    5749c70 Merge pull request 'feat(assets): edit-modal write surface for CMDB expansion fields (PMS-473)' (#328) from feat/PMS-473-cmdb-asset-edit-fields into main
    1126d34 feat(assets): edit-modal write surface for CMDB expansion fields (PMS-473)
    d8b75f1 Merge pull request 'feat(approvals): My Approvals page with inline approve/reject (PMS-481)' (#329) from feat/PMS-481-approvals-page into main
    fb9fd56 Merge pull request 'feat(assets): ITIL category + lifecycle stage pickers on asset forms (PMS-476)' (#325) from feat/PMS-476-itil-pickers into main
    4bc07fc Merge pull request 'feat(audit-log): dated filename on CSV download button (PMS-474)' (#324) from feat/PMS-474-audit-log-csv-download into main
    16165ef Merge pull request 'feat(portal): render ticket comment thread + send-reply form (PMS-480)' (#327) from feat/PMS-480-portal-comment-thread into main
    a623735 Merge pull request 'feat/PMS-482-kb-open-ticket' (#326) from feat/PMS-482-kb-open-ticket into main
    58f17ed feat(approvals): My Approvals page with inline approve/reject (PMS-481)
    dd39bf4 feat(portal): render ticket comment thread + send-reply form (PMS-480)
    0ffe20b chore: cargo fmt (PMS-482 follow-up)
    b6f71a2 feat(kb): Open ticket about this article + source_kb_article_id stamp (PMS-482)
    c7107fd feat(assets): ITIL category + lifecycle stage pickers on asset forms (PMS-476)
    5829d0c feat(audit-log): dated filename on CSV download button (PMS-474)
    fd480a7 Merge pull request 'feat(assets): surface CMDB expansion fields on the detail panel (PMS-454)' (#323) from feat/PMS-454-cmdb-asset-fields into main
    efcdf80 Merge pull request 'feat(dashboards): management page for saved dashboards (PMS-453 phase 1 client)' (#322) from feat/PMS-453-saved-dashboards-client into main
    2313f2c Merge pull request 'fix(ci): pre-stage wasm-opt in the WASM builder image (CI flake)' (#321) from fix/dx-build-wasm-opt-preinstall into main
    3efbc8a fix(ci): pre-stage wasm-opt in the WASM builder image (CI flake)
    e8b8fbf feat(dashboards): management page for saved dashboards (PMS-453 phase 1 client)
    34e74e9 feat(assets): surface CMDB expansion fields on the detail panel (PMS-454)
    73de63e Merge pull request 'feat(audit): Download CSV button on /admin/audit-log (PMS-455)' (#320) from feat/PMS-455-audit-log-export-button into main
    a1b9104 Merge pull request 'feat(topbar): GlobalSearch component wired to /api/v1/search (MAPPS-298)' (#319) from feat/MAPPS-298-global-search-client into main
    a0ca848 Merge pull request 'fix(layout): stack 2-column form / detail grids on narrow viewports (MAPPS-279)' (#315) from fix/MAPPS-279-mobile-responsive into main
    890cd0b Merge pull request 'feat(tickets): capture Type / Category / Assignee / Due Date at create (MAPPS-296)' (#318) from feat/MAPPS-296-richer-ticket-create into main
    440ef29 Merge pull request 'feat(noc): Big View routes for kiosk-mounted ops-center screens (MAPPS-302)' (#316) from feat/MAPPS-302-noc-big-view into main
    22bb8b2 feat(audit): Download CSV button on /admin/audit-log (PMS-455)
    c49701f feat(topbar): GlobalSearch component wired to /api/v1/search (MAPPS-298)
    421a7d6 Merge pull request 'feat(dispatch): Day / Week / Month view toggle on the Dispatch board (MAPPS-280)' (#317) from feat/MAPPS-280-dispatch-week-month into main
    07a7f38 Merge pull request 'fix(billing): standardised 403 permission-required UI on Contracts + Rate Cards (MAPPS-271)' (#314) from fix/MAPPS-271-standardize-403-permission-ui into main
    bf1c5f0 feat(tickets): capture Type / Category / Assignee / Due Date at create (MAPPS-296)
    751c817 feat(dispatch): Day / Week / Month view toggle on the Dispatch board (MAPPS-280)
    4196548 feat(noc): Big View routes for kiosk-mounted ops-center screens (MAPPS-302)
    56d50d4 fix(layout): stack 2-column form / detail grids on narrow viewports (MAPPS-279)
    6efd489 fix(billing): standardised 403 permission-required UI on Contracts + Rate Cards (MAPPS-271)
    8aeddcc Merge pull request 'chore: Sync the checks and justfile recipes' (#313) from chore/sync-checks-justfile into main
    c7d0cdc Merge branch 'main' into chore/sync-checks-justfile
    194d49e chore: Sync the checks and justfile recipes
    3c19676 Merge pull request 'feat(picker): inline '+ Create new contact' on ContactPicker (MAPPS-276)' (#312) from feat/MAPPS-276-picker-inline-create into main
    523b7d6 Merge pull request 'feat(assets): bulk-edit modal for Status / Company over N selected assets (MAPPS-303)' (#311) from feat/MAPPS-303-bulk-asset-edit into main
    533e1da Merge pull request 'feat(lists): bulk-actions primitive + Tickets bulk-delete opt-in (MAPPS-290)' (#310) from feat/MAPPS-290-bulk-actions-primitive into main
    22c8572 feat(picker): inline '+ Create new contact' on ContactPicker (MAPPS-276)
    c50bd0a feat(assets): bulk-edit modal for Status / Company over N selected assets (MAPPS-303)
    89a2183 feat(lists): bulk-actions primitive + Tickets bulk-delete opt-in (MAPPS-290)
    d75137e Merge pull request 'feat(assets): warranty-expiry 'Needs refresh' / 'Expires soon' badge (MAPPS-305)' (#309) from feat/MAPPS-305-warranty-needs-refresh-tag into main
    dbb6408 Merge pull request 'feat(forms): breadcrumbs on Project / Contract / Asset create pages (MAPPS-294)' (#308) from feat/MAPPS-294-breadcrumbs-consistency into main
    edf9ab3 Merge pull request 'feat(toasts): success toast on Ticket / Company / Contact create + save (MAPPS-293)' (#307) from feat/MAPPS-293-success-toasts into main
    de686f3 Merge pull request 'feat(tickets): sortable list columns (MAPPS-289)' (#306) from feat/MAPPS-289-sortable-list-columns into main
    1cbf750 Merge pull request 'feat(theme): surface contrast ratio on accent hover (MAPPS-288)' (#305) from feat/MAPPS-288-wcag-contrast-guard into main
    224168f Merge pull request 'fix(forms): collect every validation error on submit instead of one at a time (MAPPS-284)' (#304) from fix/MAPPS-284-show-all-validation-errors into main
    14e5480 Merge pull request 'feat(phone): render stored phone numbers with separators (MAPPS-283)' (#303) from feat/MAPPS-283-phone-format into main
    848d884 Merge pull request 'feat(time): honour ?project_id= prefill on Log Time link (MAPPS-275)' (#302) from feat/MAPPS-275-parent-context-nav into main
    c328442 Merge pull request 'fix(forms): drop HTML5 required on shared inputs; styled inline errors only (MAPPS-277)' (#301) from fix/MAPPS-277-styled-required-error into main
    7b9cc90 Merge pull request 'fix(detail-pages): replace generic header flash with honest loading state (MAPPS-278)' (#300) from fix/MAPPS-278-detail-header-flash into main
    d66343f Merge pull request 'feat(lists): one-click 'Clear filters' on filtered-empty list states (MAPPS-291)' (#299) from feat/MAPPS-291-clear-filters-affordance into main
    7e08a3e Merge pull request 'fix(a11y): set document.title from the page title every route hands AppLayout (MAPPS-287)' (#298) from fix/MAPPS-287-per-route-doc-titles into main
    0e07ca8 Merge pull request 'fix(assets): distinguish loading / empty / failed in Change History panel (MAPPS-304)' (#297) from fix/MAPPS-304-asset-change-history-states into main
    542a2b3 feat(theme): surface contrast ratio on accent hover (MAPPS-288)
    e56bf0c feat(assets): warranty-expiry 'Needs refresh' / 'Expires soon' badge (MAPPS-305)
    526e5cc fix(forms): collect every validation error on submit instead of one at a time (MAPPS-284)
    62ad8c7 feat(time): honour ?project_id= prefill on Log Time link (MAPPS-275)
    d32a77b feat(forms): breadcrumbs on Project / Contract / Asset create pages (MAPPS-294)
    6e3f15f feat(tickets): sortable list columns (MAPPS-289)
    3530223 feat(toasts): success toast on Ticket / Company / Contact create + save (MAPPS-293)
    f80ea24 feat(phone): render stored phone numbers with separators (MAPPS-283)
    c697940 fix(forms): drop HTML5 required on shared inputs; styled inline errors only (MAPPS-277)
    1da8f4f fix(detail-pages): replace generic header flash with honest loading state (MAPPS-278)
    3511db0 feat(lists): one-click 'Clear filters' on filtered-empty list states (MAPPS-291)
    9817c14 fix(a11y): set document.title from the page title every route hands AppLayout (MAPPS-287)
    e3137d4 Merge pull request 'fix(calendar): today-cell highlight uses theme-aware accent + ring (MAPPS-301)' (#296) from fix/MAPPS-301-calendar-today-cell-contrast into main
    dea4121 Merge pull request 'feat(company): New Contract / Project / Invoice / Asset CTAs on Company detail (MAPPS-300)' (#295) from feat/MAPPS-300-company-detail-ctas into main
    9ef8c06 Merge pull request 'feat(forms): browser-level unsaved-changes guard for the Company form (MAPPS-292)' (#293) from feat/MAPPS-292-unsaved-changes-guard into main
    51b8a1d Merge pull request 'fix(tickets): source list status filter from tenant ticket_statuses (MAPPS-295)' (#294) from fix/MAPPS-295-ticket-status-enum into main
    56d6a63 Merge pull request 'fix(a11y): label + aria-expanded on every collapsible toggle (MAPPS-286)' (#292) from fix/MAPPS-286-collapsible-aria into main
    11ce65e Merge pull request 'fix(time): drop duplicate placeholder in Log Time Work Item dropdown (MAPPS-274)' (#288) from fix/MAPPS-274-dup-log-time-placeholder into main
    99c7d27 Merge pull request 'fix(pickers): stop rendering raw UUIDs in selected-chip state (MAPPS-273)' (#287) from fix/MAPPS-273-contact-company-uuid-leak into main
    529738a Merge pull request 'fix(portal): route portal invoice amounts through format_money_str (MAPPS-272)' (#286) from fix/MAPPS-272-currency-format into main
    c04aa13 Merge pull request 'fix(diag): forward wasm panics to console.error with a readable trace (MAPPS-299)' (#284) from fix/MAPPS-299-wasm-panic-hook into main
    aa3a324 Merge pull request 'fix(forms): reject whitespace-only required fields client-side (MAPPS-281)' (#289) from fix/MAPPS-281-whitespace-required-trim into main
    0d275f7 Merge pull request 'fix(a11y): hide mobile sidebar drawer from AT when closed (MAPPS-285)' (#291) from fix/MAPPS-285-duplicate-sidebar-nav into main
    a7f9a2a Merge pull request 'fix(forms): replace developer-facing status strings with user messages (MAPPS-282)' (#290) from fix/MAPPS-282-422-inline-field-errors into main
    9e71bb5 Merge pull request 'fix(form): bind controlled value on the Select element itself (MAPPS-270)' (#285) from fix/MAPPS-270-inline-edit-refresh into main
    0042625 feat(forms): browser-level unsaved-changes guard for the Company form (MAPPS-292)
    b783430 feat(company): New Contract / Project / Invoice / Asset CTAs on Company detail (MAPPS-300)
    979afbb fix(portal): route portal invoice amounts through format_money_str (MAPPS-272)
    dfbcbac fix(a11y): label + aria-expanded on every collapsible toggle (MAPPS-286)
    1fc7a36 fix(a11y): hide mobile sidebar drawer from AT when closed (MAPPS-285)
    bc15234 fix(forms): replace developer-facing status strings with user messages (MAPPS-282)
    b1ca568 fix(forms): reject whitespace-only required fields client-side (MAPPS-281)
    b377f31 fix(form): bind controlled value on the Select element itself (MAPPS-270)
    0e35352 fix(tickets): source list status filter from tenant ticket_statuses (MAPPS-295)
    c89f5bb fix(calendar): today-cell highlight uses theme-aware accent + ring (MAPPS-301)
    1dab445 fix(time): drop duplicate placeholder in Log Time Work Item dropdown (MAPPS-274)
    64039cc fix(pickers): stop rendering raw UUIDs in selected-chip state (MAPPS-273)
    e460ff8 fix(assets): distinguish loading / empty / failed in Change History panel (MAPPS-304)
    5f4e258 fix(diag): forward wasm panics to console.error with a readable trace (MAPPS-299)
    0842f91 Merge pull request 'feat(contacts): scope company context cards with capped preview, scoped View All, and per-row edit/delete' (#278) from feat/MAPPS-249-scope-company-context-cards into main
    30c3926 Merge branch 'main' into feat/MAPPS-249-scope-company-context-cards
    8a763ff Merge pull request 'feat(settings): nest groups, add breadcrumbs, search, basic/advanced toggle' (#281) from feat/MAPPS-258-settings-nesting-breadcrumbs-search into main
    62513bd Merge branch 'main' into feat/MAPPS-257-settings-card-consistency-color-coding
    8e5d0bf Merge branch 'main' into feat/MAPPS-258-settings-nesting-breadcrumbs-search
    2eece0e Merge pull request 'feat(ci): cap native check.yml parallelism at nproc/2' (#283) from feat/GOV-10-native-check-nproc-cap into main
    65e1195 feat(ci): cap native check.yml parallelism at nproc/2
    5d9b02a Merge branch 'main' into feat/MAPPS-258-settings-nesting-breadcrumbs-search
    471736c Merge pull request 'fix(hooks): keep pre-commit working tree host-owned' (#282) from fix/dev-371-precommit-host-owned-target into main
    c204e32 fix(hooks): keep pre-commit working tree host-owned
    3058003 feat(settings): nest groups, add breadcrumbs, search, basic/advanced toggle
    b2efe1b feat(dashboard): full-screen team-scoped TV-view dashboard mode
    7b7b1d1 feat(settings): consistent card sizing and section color-coding
    f52a763 feat(contacts): scope company context cards with capped preview, scoped View All, and per-row edit/delete
    74981ad Merge pull request 'feat(time): General/ticketless time logging with own-company attribution (MAPPS-243)' (#277) from feat/MAPPS-243-general-ticketless-time-logging into main
    0403ad0 feat(time): add General work item for ticketless time logging
    ed01b62 Merge pull request 'feat(calendar): appointment templates + dispatch discoverability + in-screen help (MAPPS-253)' (#276) from feat/MAPPS-253-appointment-templates into main
    0cdd2b0 feat(calendar): appointment templates, dispatch discoverability, and in-screen help (MAPPS-253)
    0b86d2c Merge pull request 'fix(hooks): build css before pre-commit checks' (#272) from fix/pre-commit-clean-clone into main
    afb6ac6 Merge branch 'main' into fix/pre-commit-clean-clone
    a8770ce Merge pull request 'feat(calendar): start-time + duration appointment form with all-day span (MAPPS-252)' (#275) from feat/MAPPS-252-appointment-start-duration into main
    6f0d1e0 feat(calendar): adopt start-time plus duration model in appointment form
    93478ba Merge pull request 'feat(layout): collapsible desktop sidebar rail (MAPPS-250)' (#274) from feat/MAPPS-250-collapsible-desktop-sidebar into main
    8cb27c2 feat(layout): collapsible desktop sidebar rail (MAPPS-250)
    1a08dc8 Merge pull request 'feat(contacts): inline company name validation + duplicate-name feedback (MAPPS-246)' (#273) from feat/MAPPS-246-company-name-inline-validation into main
    c3bb132 feat(contacts): inline company name validation + duplicate-name feedback (MAPPS-246)
    3b6cadf Merge pull request 'feat(contacts): freeform company entry on contact form (+ Add Company)' (#258) from feat/mapps-251-freeform-company-contact into main
    005739d feat(contacts): freeform company entry on contact form (+ Add Company)
    b076170 Merge pull request 'refactor(badges): centralize status->BadgeVariant mapping per domain' (#264) from refactor/MAPPS-268-centralize-status-badges into main
    b02dd2e fix(hooks): build css before pre-commit checks
    929eb34 Merge pull request 'fix(calendar): bucket dates/times in the user's profile timezone (PMS-360)' (#271) from fix/PMS-360-calendar-profile-tz into main
    fd7eb28 fix(calendar): bucket dates and times in the user's profile timezone (PMS-360)
    a0b4a3a refactor(badges): centralize status->BadgeVariant mapping per domain
    0bef2e8 Merge pull request 'feat(table): all-row hover, opt-in zebra striping, always-visible sort affordance' (#270) from feat/mapps-263-table-polish into main
    224d9cf Merge pull request 'feat(forms): consistent help/error spacing + persistent inline server errors' (#265) from feat/MAPPS-265-form-help-error-spacing-inline-validation into main
    4c5d2e8 Merge pull request 'feat(empty-states): use three-part EmptyState for filtered-empty lists' (#266) from feat/mapps-266-standardize-list-empty-states into main
    194bcb5 Merge pull request 'feat(modal): cap mobile height, pin chrome, restore focus to trigger' (#268) from feat/mapps-264-modal-mobile-height-focus-restore into main
    8fe184d Merge pull request 'feat(a11y): surface disabled-action reasons via Button title + aria-disabled' (#269) from feat/mapps-262-disabled-reason-titles into main
    a214a4f Merge pull request 'feat(ui): adopt shared StatCard tone, OverflowActions, PageHeader long-title guard' (#267) from feat/mapps-267-shared-ui-primitives into main
    fe37ebc Merge pull request 'fix(billing): add an edit path for recorded payments' (#246) from fix/MAPPS-235-payment-edit-path into main
    470483f feat(table): all-row hover, opt-in zebra striping, always-visible sort affordance
    d875d08 fix(billing): add an edit path for recorded payments
    6f53aa8 feat(a11y): surface disabled-action reasons via Button title + aria-disabled
    ca37aa3 feat(modal): cap mobile height, pin chrome, restore focus to trigger
    9375c9c Merge pull request 'feat(a11y): IconButton primitive + aria-label/title on icon-only buttons; non-color unread status' (#263) from feat/mapps-261-a11y-icon-buttons-status into main
    bc247dd Merge pull request 'feat(time): max-hours-per-day settings page + inline day-cap error on log-time' (#256) from feat/mapps-244-max-hours-per-day into main
    3667835 feat(a11y): IconButton primitive + aria-label/title on icon-only buttons; non-color unread status
    d5d4ada feat(ui): adopt shared StatCard tone, OverflowActions, PageHeader long-title guard
    2934c93 feat(time): max-hours-per-day settings page + inline day-cap error on log-time
    113b7d2 feat(empty-states): use three-part EmptyState for filtered-empty lists
    09fd5ad feat(forms): consistent help/error spacing + persistent inline server errors
    8d13277 Merge pull request 'fix(calendar): allow editing and clearing appointment recurrence' (#248) from fix/MAPPS-236-edit-recurrence-rule into main
    269049e Merge pull request 'feat(projects): disable Add Task on cancelled project with messaging' (#254) from feat/mapps-245-disable-add-task-cancelled into main
    c5eabf7 Merge pull request 'feat(contracts): show allotment headline and edit allotted hours from detail view' (#257) from feat/mapps-255-contract-allotment-edit into main
    93ed62f Merge pull request 'feat(contracts): surface Weekly and Bi-weekly billing cycles' (#260) from feat/mapps-254-weekly-biweekly-billing-cycle into main
    6df067c Merge pull request 'feat(contacts): collapsible company-detail sections (MAPPS-247)' (#261) from feat/mapps-247-collapsible-company-detail-sections into main
    8115a31 Merge pull request 'feat(theme): two-layer theme + accent picker, app-wide (MAPPS-259)' (#262) from feat/MAPPS-259-theme-picker into main
    80737c7 feat(theme): sync per-user theme + accent to the account (MAPPS-259)
    a6a3a09 feat(theme): migrate the app to semantic tokens + token lint guard (MAPPS-259)
    ff13957 feat(theme): two-layer theme + accent picker foundation (MAPPS-259)
    1da4cc3 feat(contacts): collapsible company-detail sections (MAPPS-247)
    6ee6ee6 feat(contracts): surface Weekly and Bi-weekly billing cycles
    0d5bf5d Merge pull request 'feat(ux): Esc-to-cancel + type-to-confirm for destructive actions (PMS-369)' (#259) from feat/pms-369-confirm-esc-type-to-confirm into main
    c5cd70b feat(ux): Esc-to-cancel + type-to-confirm for destructive actions (PMS-369)
    c95d5b4 feat(contracts): show allotment headline and edit allotted hours from detail view
    71f155b Merge pull request 'feat(forms): autocomplete CompanyPicker on Project + billing forms + conventions doc (PMS-367)' (#255) from feat/pms-367-company-picker-and-form-conventions into main
    bf7c126 feat(forms): autocomplete CompanyPicker on Project + billing forms, form-conventions doc (PMS-367)
    8fbcc4e feat(projects): disable Add Task on cancelled project with messaging
    90af980 Merge pull request 'feat(time): prefill work-item from ?ticket_id on Log Time (PMS-362)' (#253) from feat/pms-362-log-time-ticket-prefill into main
    e52924c feat(time): prefill work-item from ?ticket_id on Log Time (PMS-362 AC2)
    df91523 Merge pull request 'docs(ui): canonical Button variant reference + showcase page (PMS-357)' (#252) from feat/pms-357-button-variant-doc into main
    3ffd62d docs(ui): canonical Button variant reference + showcase page (PMS-357 AC4)
    4333fc2 Merge pull request 'feat(ux): helpful empty states with CTAs across list pages (PMS-354)' (#251) from feat/pms-354-empty-state-cta into main
    6a4b468 feat(ux): helpful empty states with CTAs across list pages (PMS-354)
    6d19118 Merge pull request 'feat(ux): consistent skeleton loaders across list and detail pages (PMS-353)' (#250) from feat/pms-353-skeleton-loaders into main
    cbb2009 feat(ux): consistent skeleton loaders across list and detail pages (PMS-353)
    f89736d Merge pull request 'feat(forms): inline create-company on contact, contract, and asset forms (PMS-352 AC3)' (#249) from feat/pms-352-inline-create-remaining-pickers into main
    9e084d4 feat(forms): inline create-company on contact, contract, and asset forms (PMS-352 AC3)
    0be92be Merge pull request 'docs(assets): document config items as intentionally reveal-only' (#247) from fix/MAPPS-232-config-items-reveal-only-doc into main
    7fb19ff Merge branch 'main' into fix/MAPPS-232-config-items-reveal-only-doc
    1bef587 Merge pull request 'feat(assets): add add/delete credential UI to asset detail' (#245) from feat/MAPPS-231-asset-credential-add-delete into main
    0880c6a Merge branch 'main' into feat/MAPPS-231-asset-credential-add-delete
    2515af4 Merge pull request 'feat(kb): add category create/edit/delete UI' (#244) from feat/MAPPS-230-kb-category-crud-ui into main
    6805af0 Merge branch 'main' into feat/MAPPS-230-kb-category-crud-ui
    0abf4e3 Merge pull request 'fix(billing): edit invoice line items in the edit modal' (#243) from fix/MAPPS-234-invoice-edit-line-items into main
    b851695 Merge branch 'main' into fix/MAPPS-234-invoice-edit-line-items
    aef1ad4 Merge pull request 'fix(projects): add delete affordance to project tasks' (#242) from fix/MAPPS-237-task-delete-affordance into main
    8c98bac Merge branch 'main' into fix/MAPPS-237-task-delete-affordance
    3cce25f Merge pull request 'feat(billing): replace Record Payment UUID field with an invoice picker' (#218) from feat/MAPPS-191-record-payment-invoice-picker into main
    0f5392f Merge branch 'main' into feat/MAPPS-191-record-payment-invoice-picker
    f4e36e9 Merge pull request 'feat(contracts): manage line items from the contract detail page' (#209) from feat/mapps-196-contract-line-item-management into main
    ce2a058 Merge branch 'main' into feat/mapps-196-contract-line-item-management
    3d3b3ac Merge pull request 'feat(contacts): attach existing contacts, new-ticket from company, breadcrumbs' (#204) from feat/mapps-207-relational-gaps into main
    b18abad Merge branch 'main' into feat/mapps-207-relational-gaps
    7253225 fix(calendar): allow editing and clearing appointment recurrence
    07901b6 docs(assets): document config items as intentionally reveal-only
    c34130f feat(assets): add add/delete credential UI to asset detail
    98c1580 feat(kb): add category create/edit/delete UI
    6e6e379 fix(billing): edit invoice line items in the edit modal
    8512732 fix(projects): add delete affordance to project tasks
    93b60e0 Merge pull request 'fix(home): derive footer year and drop the dead footer links (MAPPS-229)' (#241) from fix/MAPPS-229-footer-year-and-links into main
    da421f2 Merge branch 'main' into fix/MAPPS-229-footer-year-and-links
    c72ad0c Merge pull request 'fix(assets): validate the asset Edit modal like the create form (MAPPS-238)' (#240) from fix/MAPPS-238-asset-edit-modal-validation into main
    ef3f206 Merge branch 'main' into fix/MAPPS-238-asset-edit-modal-validation
    69a129f Merge pull request 'fix(sla): validate Business Hours timezone as an IANA name (MAPPS-240)' (#239) from fix/MAPPS-240-business-hours-timezone-validation into main
    afe9d4d fix(home): derive footer year and drop the dead footer links
    34017cf fix(assets): validate the asset Edit modal like the create form
    47c141d fix(sla): validate Business Hours timezone as an IANA name
    de0e270 Merge pull request 'fix(sla): validate target hours, rejecting negatives and junk (MAPPS-239)' (#238) from fix/MAPPS-239-sla-target-hours-validation into main
    184f90d style(sla): rustfmt block-wrap the long validate_hours error arm
    7b2e502 fix(sla): validate target hours, rejecting negatives and junk
    4c5f016 Merge pull request 'fix(settings): drop stale 3rd arg from RMM delete_lookup calls (MAPPS-224)' (#237) from fix/mapps-rmm-delete-lookup-arity into main
    e385741 fix(settings): drop stale 3rd arg from RMM delete_lookup calls
    31b1188 Merge main into feat/mapps-196-contract-line-item-management
    e8f434f Merge main into feat/mapps-207-relational-gaps
    4d9d4bf Merge pull request 'feat(timesheets): add manager UI to approve/reject submitted timesheets' (#207) from feat/mapps-194-timesheet-approvals-ui into main
    750e519 Merge pull request 'feat(rmm): add admin UI for RMM connections, device mappings, alert rules' (#211) from feat/mapps-199-rmm-admin-ui into main
    081bfd6 Merge pull request 'fix(tickets): show "Ticket not found" instead of infinite loading on 404' (#210) from fix/mapps-198-ticket-detail-not-found into main
    bd628d1 Merge pull request 'feat(contacts): surface company contracts, projects, invoices, assets on detail page' (#208) from feat/mapps-195-company-detail-relationships into main
    9edc419 Merge pull request 'feat(kb): filter article list by category from category cards' (#206) from feat/MAPPS-193-kb-category-card-filter into main
    a99f49f Merge pull request 'feat(datetime): render timestamps in the user's profile timezone' (#205) from feat/mapps-208-display-profile-timezone into main
    215808e Merge pull request 'feat(billing): wire invoice tax and discount into the create and edit UI' (#200) from feat/mapps-192-invoice-tax-discount-ui into main
    57b40dc Merge pull request 'fix(layout): preserve sidebar scroll position across nav re-mount' (#199) from fix/mapps-203-sidebar-scroll-preserve into main
    3c4de56 Merge pull request 'fix(ui): replace native window.confirm() with styled ConfirmDialog for destructive actions' (#198) from feat/MAPPS-189-confirm-dialog-replace-native-confirm into main
    cf5c120 Merge pull request 'feat(projects): New Project form exposes status / dates / manager (PMS-361)' (#231) from fix/pms-361-new-project-form-exposes-edit-fields into main
    877f18d feat(projects): New Project form exposes status / dates / manager (PMS-361)
    054f6f2 Merge pull request 'fix(contacts): bind list Role column to contact_type, not title' (#230) from fix/PMS-368-contact-role-column-rebind into main
    f54de81 fix(contacts): bind list Role column to contact_type, not title
    8df739c Merge pull request 'fix(display): uniform currency, billing-cycle label, resolved audit-log diff' (#229) from fix/PMS-365-display-formatting-sweep into main
    1cbc34d fix(display): uniform currency formatting, billing-cycle label, resolved audit-log diff
    6e4663d Merge pull request 'fix(contracts): surface server-side end_date field errors inline' (#228) from fix/PMS-364-inline-cross-field-errors into main
    a83b5ab fix(contracts): surface server-side end_date field errors inline
    7c09928 Merge pull request 'fix(companies): refresh Statistics counts after adding a site' (#227) from fix/PMS-363-company-sites-counter-reactive into main
    8e5ed7a fix(companies): refresh Statistics counts after adding a site
    61f593f Merge pull request 'fix(reports): drop 'charts coming soon' placeholder from report views' (#226) from fix/PMS-356-remove-revenue-chart-placeholder into main
    ae6c754 fix(reports): drop "charts coming soon" placeholder from report views
    bffe49e Merge pull request 'docs(qa): add technique-rich field and button audit prompt' (#225) from docs/MAPPS-221-qa-field-button-audit-prompt into main
    52014ef docs(qa): index the three QA prompts in the dev-docs README
    204aef7 Merge pull request 'feat(kb): validate slug/tags and cap text fields on article form' (#224) from feat/mapps-218-kb-article-form-validation into main
    3af4ba4 fix(kb): pass Body maxlength as i64 after the Textarea unify
    e356c05 Merge remote-tracking branch 'origin/main' into feat/mapps-218-kb-article-form-validation
    b79446b Merge pull request 'fix(rate-cards): wire /rate-cards/new to create form and explain disabled Add Rate' (#223) from fix/mapps-217-rate-card-create-route-disabled-styling into main
    702f103 fix(rate-cards): show the disabled Add Rate reason as visible helper text
    bda15de Merge pull request 'fix(assets): field-level validation on the New Asset form' (#222) from fix/mapps-216-new-asset-form-field-validation into main
    22fba2c Merge pull request 'fix(billing): validate Record Payment Amount and Invoice ID fields' (#221) from fix/mapps-215-record-payment-field-validation into main
    045ccb4 fix(billing): pass payment Notes maxlength as i64 after the Textarea unify
    009325d Merge remote-tracking branch 'origin/main' into fix/mapps-215-record-payment-field-validation
    47e68a2 Merge pull request 'feat(calendar): validate appointment RRULE and cap text field lengths' (#219) from feat/MAPPS-219-appointment-rrule-validation-maxlength into main
    baf80f1 refactor(form): unify Textarea maxlength on i64 to match Input
    3adffec docs(qa): add technique-rich field and button audit prompt
    cc7f104 Merge remote-tracking branch 'origin/main' into feat/MAPPS-219-appointment-rrule-validation-maxlength
    51a9f18 feat(kb): validate slug/tags and cap text fields on article form
    46941f3 Merge pull request 'fix(billing): validate New Invoice fields client-side' (#217) from fix/MAPPS-214-invoice-form-validation into main
    84d0c03 Merge remote-tracking branch 'origin/main' into fix/MAPPS-214-invoice-form-validation
    1318bf6 fix(rate-cards): wire /rate-cards/new to create form and explain disabled Add Rate
    97fd09a Merge pull request 'feat(contacts): validate Website field and cap text fields on company form' (#216) from feat/mapps-213-company-form-website-validation into main
    75d6dfd Merge remote-tracking branch 'origin/main' into feat/mapps-213-company-form-website-validation
    0ea7c78 fix(assets): field-level validation on the New Asset form
    980f153 fix(billing): validate Record Payment Amount and Invoice ID fields
    ff447c8 Merge pull request 'fix(projects): bound budget amount, fix hours message, cap description' (#214) from fix/mapps-212-new-project-form-validation into main
    a9f9201 Merge remote-tracking branch 'origin/main' into fix/mapps-212-new-project-form-validation
    a956d55 feat(calendar): validate appointment RRULE and cap text field lengths
    32466fb Merge pull request 'feat(contracts): field-level validation on the New Contract form' (#215) from feat/mapps-211-contract-form-field-validation into main
    c54d02d Merge remote-tracking branch 'origin/main' into feat/mapps-211-contract-form-field-validation
    6ad02f5 feat(billing): replace Record Payment UUID field with an invoice picker
    347369e fix(billing): validate New Invoice fields client-side
    8df2747 Merge pull request 'fix(forms): surface server field validation errors in shared fetch hook' (#201) from fix/MAPPS-210-surface-server-validation-errors into main
    81f5fe5 fix(forms): surface server validation message on the string-error helpers too
    eb66616 feat(contacts): validate Website field and cap text fields on company form
    226acda Merge pull request 'feat(projects): show task logged/approved/estimated hours on project detail' (#202) from feat/MAPPS-205-task-hours-on-project-detail into main
    8b95992 Merge pull request 'feat(time): show work type name in the time entry list' (#213) from feat/mapps-202-work-type-name-in-time-list into main
    88736f5 style(time): wrap the work-types fetch call to satisfy rustfmt
    33bb6bf fix(time): fetch work types with per_page=100 in the edit modal
    f51da80 Merge pull request 'fix(version): source displayed version from CARGO_PKG_VERSION' (#212) from fix/mapps-200-version-source into main
    e1f9e84 feat(contracts): field-level validation on the New Contract form
    62947a1 fix(version): declare CARGO_PKG_VERSION as an explicit build rerun trigger
    436283c fix(projects): bound budget amount, fix hours message, cap description
    f0d81b2 feat(time): show work type name in the time entry list
    fb9d9a9 fix(version): source displayed version from CARGO_PKG_VERSION
    7268a92 feat(rmm): add admin UI for RMM connections, device mappings, alert rules
    f3529e2 fix(tickets): show "Ticket not found" instead of infinite loading on 404
    f1df205 Merge pull request 'docs(qa): add reusable QA prompts for E2E testing and input validation' (#195) from docs/mapps-209-qa-prompts into main
    2687bb3 Merge branch 'main' into docs/mapps-209-qa-prompts
    7d55c75 feat(contracts): manage line items from the contract detail page
    60161e6 feat(contacts): surface company contracts, projects, invoices, assets on detail page
    fba3675 feat(timesheets): add manager UI to approve/reject submitted timesheets
    8d60c50 feat(kb): filter article list by category from category cards
    91c9db2 feat(datetime): render timestamps in the user's profile timezone
    584173c feat(contacts): attach existing contacts, new-ticket from company, breadcrumbs
    cc37ac5 feat(projects): show task logged/approved/estimated hours on project detail
    e0366d3 fix(forms): surface server field validation errors in shared fetch hook
    0791032 feat(billing): wire invoice tax and discount into the create and edit UI
    8ea32b5 fix(layout): preserve sidebar scroll position across nav re-mount
    dd3485f fix(ui): replace native window.confirm() with styled ConfirmDialog for destructive actions
    5c9c442 Merge pull request 'feat(tickets): make ticket title editable from the detail edit modal' (#197) from feat/mapps-188-editable-ticket-title into main
    14d2c5a Merge branch 'main' into feat/mapps-188-editable-ticket-title
    6a02ec3 feat(tickets): make ticket title editable from the detail edit modal
    e05dc51 Merge pull request 'fix(justfile): supply MOKOSH_OIDC_CLIENT_ID placeholder in down teardown (MAPPS-159)' (#146) from fix/MAPPS-159-down-oidc-client-id-placeholder into main
    9a4140b Merge branch 'main' into fix/MAPPS-159-down-oidc-client-id-placeholder
    e7e1b0c Merge pull request 'fix(tickets): AssetPicker inline-edit chip fits inside DetailItem row, no duplicate label (PMS-344 follow-up)' (#196) from fix/pms-344-asset-picker-detailitem-layout into main
    f10aefb fix(tickets): AssetPicker inline-edit chip fits inside DetailItem row, no duplicate label (PMS-344 follow-up)
    8957ba0 docs(qa): add reusable QA prompts for E2E testing and input validation
    9c4353b Merge pull request 'fix(tickets): asset inline-edit Change opens search picker without server roundtrip (PMS-344 follow-up)' (#194) from fix/pms-344-asset-inline-change-opens-search into main
    98ff84c fix(tickets): asset inline-edit Change opens search picker without server roundtrip (PMS-344 follow-up)
    ccbfcb8 Merge pull request 'fix(ui): strip trailing _id suffix from history field labels (PMS-370)' (#193) from fix/pms-370-strip-id-suffix-in-history-labels into main
    ba953a3 Merge pull request 'fix(pickers): use_resource subscribes to query signal, populated-list affordance label echoes typed text' (#192) from fix/pms-371-company-picker-filter-and-affordance-label into main
    470de0f fix(ui): strip trailing _id suffix from history field labels (PMS-370)
    0300247 fix(pickers): use_resource subscribes to query signal, populated-list affordance label echoes typed text
    ad40f4c Merge pull request 'fix(layout): UpdateBanner re-mount on nav causes the 'page jump' MAPPS-203 reports' (#191) from fix/mapps-203-update-banner-no-shift-on-nav into main
    dbe13d2 Merge pull request 'feat(tickets,assets): bidirectional asset/ticket link (PMS-344)' (#190) from feat/pms-344-asset-picker-and-related-tickets into main
    b8cf377 feat(tickets,assets): bidirectional asset/ticket link (PMS-344)
    8b5fe3a fix(layout): UpdateBanner re-mount on nav causes the 'page jump' MAPPS-203 reports
    b34e54d Merge pull request 'chore(ci): trigger image rebuild + :latest retag after Tier S merges' (#189) from chore/trigger-ci-rebuild-tier-s into main
    d43a173 chore(ci): trigger image rebuild + :latest retag after Tier S merges
    7191f06 Merge pull request 'feat(tickets): inline 'Create new company' affordance in CompanyPicker on New Ticket' (#188) from feat/pms-352-inline-create-company-on-ticket-form into main
    44e2e0a Merge pull request 'fix(ux): confirm destructive actions on Team Revoke and SLA Remove' (#187) from fix/pms-369-confirm-destructive-actions into main
    220cdcc Merge pull request 'feat(tickets): inline-edit status/priority/assignee on ticket detail' (#186) from feat/pms-359-ticket-inline-edit into main
    da022d0 feat(tickets): inline-edit status/priority/assignee on ticket detail
    d7e9132 Merge pull request 'fix(tickets): send priority_id on New Ticket create (was dropped silently)' (#185) from fix/pms-358-ticket-priority-not-sent into main
    4b2a7c8 feat(tickets): inline 'Create new company' affordance in CompanyPicker on New Ticket
    ed93f3c fix(ux): confirm destructive actions on Team Revoke and SLA Remove
    9e9d199 fix(tickets): send priority_id on New Ticket create (was dropped silently)
    287dcc4 Merge pull request 'feat(time): link work items in the timesheet grid (MAPPS-206)' (#184) from feat/MAPPS-206-link-projects-everywhere into main
    3eb4a83 feat(time): link work items in the timesheet grid (MAPPS-206)
    10e60c2 Merge pull request 'feat(ui): standardize date selection behind one DateField component (MAPPS-204)' (#183) from feat/MAPPS-204-standardize-date-inputs into main
    0e5afd4 feat(ui): standardize date selection behind one DateField component (MAPPS-204)
    2fcb0f5 Merge pull request 'feat(settings): add Scheduling page to edit the standard due date' (#182) from feat/MAPPS-345-scheduling-due-date-setting into main
    0cb3918 Merge branch 'main' into feat/MAPPS-345-scheduling-due-date-setting
    424e9f6 feat(settings): add Scheduling page to edit the standard due date
    64219ae Merge pull request 'feat(time): empty-week timesheet prompt + Log Time shortcut (MAPPS-201)' (#181) from feat/MAPPS-201-timesheet-empty-log-time-cta into main
    c5406f9 feat(time): empty-week timesheet prompt + Log Time shortcut (MAPPS-201)
    8dab207 Merge pull request 'fix(update-banner): fetch /version once by keying on a memoized admin flag (MAPPS-187)' (#180) from fix/MAPPS-187-version-dedup into main
    cf929bf fix(update-banner): fetch /version once by keying the check on a memoized admin flag (MAPPS-187)
    21e8bf5 Merge pull request 'feat(ui): clickable, persisting Markdown task-list checkboxes (PMS-348)' (#179) from feat/PMS-348-interactive-task-checkboxes into main
    f2d4bfc feat(ui): make Markdown task-list checkboxes clickable and persist the toggle (PMS-348)
    00e23fd Merge pull request 'fix(contracts): align contract dropdown values with backend CHECK constraints (MAPPS-190)' (#178) from fix/MAPPS-190-contract-dropdown-values into main
    ab7056e fix(contracts): align contract dropdown values with backend CHECK constraints (MAPPS-190)
    4178769 Merge pull request 'fix(fetch): bump tenant generation only when the access token changes (MAPPS-187)' (#176) from fix/MAPPS-187-double-fetch into main
    54931e8 Merge branch 'main' into fix/MAPPS-187-double-fetch
    c1f27ca Merge pull request 'refactor(ui): consolidate money formatting into one shared helper (MAPPS-197)' (#175) from fix/MAPPS-197-money-format into main
    d4045e5 Merge branch 'main' into fix/MAPPS-197-money-format
    5dbaec6 Merge pull request 'fix(ui): render task-list checkboxes in Markdown descriptions (PMS-347)' (#177) from fix/PMS-309-followup-tasklist-checkboxes into main
    824e44b fix(ui): render task-list checkboxes in Markdown descriptions (PMS-347)
    5fadac7 fix(fetch): bump tenant generation only when the access token changes (MAPPS-187)
    3005299 refactor(ui): consolidate money formatting into one shared helper (MAPPS-197)
    3d7f14b Merge pull request 'feat(ui): render Markdown in ticket and project descriptions (PMS-309)' (#174) from feat/PMS-309-render-markdown-descriptions into main
    1a94c15 feat(ui): render Markdown in ticket and project descriptions (PMS-309)
    b8d146a Merge pull request 'feat(nav): detail-page nav highlight + breadcrumbs for rate cards/contracts (PMS-312)' (#173) from feat/PMS-312-detail-nav-highlight-breadcrumb into main
    4c40233 feat(nav): keep parent nav highlighted on detail pages + breadcrumbs for rate cards/contracts (PMS-312)
    34528a9 Merge pull request 'fix(time,projects,sla): clearer hours placeholder + bound task due-date range (PMS-346)' (#172) from fix/PMS-317-followup-placeholder-and-date-bounds into main
    d56d86a fix(time,projects,sla): clearer hours placeholder + bound task due-date range (PMS-346)
    844340d Merge pull request 'feat(projects,sla): accept H:MM / fractional hours in Budget Hours and SLA times (PMS-340)' (#171) from feat/PMS-340-duration-fields-hhmm into main
    ff30f58 feat(projects,sla): accept H:MM / fractional hours in Budget Hours and SLA times (PMS-340)
    3048790 Merge pull request 'fix(projects): validate task due-date input and standardize change-history dates (PMS-317)' (#170) from fix/PMS-317-task-date-validation-and-history-format into main
    4409388 fix(projects): validate task due-date input and standardize change-history dates (PMS-317)
    b15448d Merge pull request 'feat(projects): accept H:MM for the task estimated-hours field (PMS-319)' (#169) from feat/PMS-319-task-estimate-hhmm into main
    294a3ef feat(projects): accept H:MM for the task estimated-hours field (PMS-319)
    60f3dac Merge pull request 'fix(time): link the project work-item in the time-entries list (PMS-320)' (#168) from fix/PMS-320-link-project-work-item into main
    dd90f6b fix(time): link the project work-item in the time-entries list (PMS-320)
    5f3c9f6 Merge pull request 'fix(layout): reserve UpdateBanner height to kill admin login layout shift' (#167) from fix/PMS-313-update-banner-layout-shift into main
    da0e809 fix(layout): reserve UpdateBanner height to kill admin login layout shift
    682e628 Merge pull request 'feat(time): explain disabled timesheet Submit + add jump-to-current-week (PMS-310)' (#166) from feat/PMS-310-timesheet-empty-week-affordances into main
    1c04965 feat(time): explain the disabled timesheet Submit and add jump-to-current-week (PMS-310)
    77a608d Merge pull request 'feat(billing): payment terms as a settings-managed dropdown (MAPPS-170)' (#165) from feat/mapps-170-payment-terms into main
    1788773 fix(billing): drop the no-op "no payment term" clear option
    98d9de6 feat(billing): payment terms as a settings-managed dropdown
    19ea8e1 Merge pull request 'feat(time): accept H:MM input in the Log Time hours field (PMS-314)' (#164) from feat/PMS-314-time-hhmm-input into main
    9986017 feat(time): accept H:MM input in the Log Time hours field (PMS-314)
    87c2c3c Merge pull request 'feat(time): show work-item and task names in the time-entries list (MAPPS-168)' (#163) from feat/mapps-168-time-entry-names into main
    c8c69c3 docs(time): refresh RemoteTimeEntry comment now that names are joined
    06877ae feat(time): show work-item and task names in the time-entries list
    02ac258 Merge pull request 'feat(projects): show task logged vs approved hours (MAPPS-167)' (#162) from feat/mapps-167-task-logged-hours into main
    ddd221c feat(projects): show task logged vs approved hours
    70d9947 Merge pull request 'style(time): rustfmt work_type use_signal closure' (#161) from fix/mapps-184-rustfmt-time into main
    1e2a354 Merge pull request 'style(time): apply rustfmt to TimeEntryEditModal work_type signal' (#160) from fix/mapps-183-time-rustfmt into main
    1ef30a1 Merge pull request 'feat(time): editable time entries (MAPPS-166)' (#159) from feat/mapps-166-editable-time-entries into main
    4971e94 style(time): rustfmt work_type use_signal closure
    e0abe32 fix(time): stop the edit modal from wiping task_id; UX tweaks
    544f864 style(time): apply rustfmt to TimeEntryEditModal work_type signal
    7e1279b feat(time): editable time entries (click-to-edit modal)
    32e8144 Merge pull request 'feat(projects): more intuitive task add/edit and back nav (MAPPS-165)' (#158) from feat/mapps-165-task-edit-ux into main
    ea858f4 Merge remote-tracking branch 'origin/feat/mapps-165-task-edit-ux' into feat/mapps-165-task-edit-ux
    51ce7e9 fix(projects): hold the selected task by value, not by id
    7bbd772 style(projects): apply rustfmt to task edit signals and history
    117ed9c feat(projects): more intuitive task add/edit and back nav
    4ab3a1a Merge pull request 'fix(contacts): client-side inline validation for contact/company/site forms [MAPPS-177]' (#157) from fix/MAPPS-177-contact-form-validation into main
    c6803a2 Merge branch 'main' into fix/MAPPS-177-contact-form-validation
    1dea92f Merge pull request 'fix(projects): client-side inline validation on project forms [MAPPS-176]' (#154) from fix/MAPPS-176-project-form-validation into main
    302dfec Merge branch 'main' into fix/MAPPS-176-project-form-validation
    7934772 fix(contacts): inline validation on contact, company, and site forms
    9873999 Merge pull request 'fix(contracts): wrap conditional Card actions in Some/None' (#156) from chore/checks-workflow-24ff62c7 into main
    230c89b Merge pull request 'fix(contracts): apply rustfmt and fix conditional rsx actions' (#155) from fix/mapps-179-contracts-fmt into main
    eb4b2c8 fix(contracts): wrap conditional Card actions in Some/None
    26cf915 Merge pull request 'fix(contracts): rustfmt diffs and conditional rsx actions in rate cards' (#153) from fix/mapps-178-contracts-fmt into main
    c774b0d Merge main into fix/mapps-178-contracts-fmt
    609e2cf fix(contracts): apply rustfmt and fix conditional rsx actions
    f2bfc41 fix(projects): inline validation on project create and edit forms
    24ff62c Merge pull request 'feat(contracts): editable rate cards and line items (MAPPS-160)' (#152) from feat/mapps-160-editable-rate-cards into main
    dadd3d5 fix(contracts): rustfmt diffs and conditional rsx actions in rate cards
    4d32e34 refactor(components): promote SettingFormModal to a shared component
    e835447 fix(contracts): rate-card editor review fixes
    f06b1c9 feat(contracts): editable rate cards and line items
    562067a Merge pull request 'feat(settings): project type editor in the Settings hub (MAPPS-173)' (#151) from feat/mapps-173-project-type-editor into main
    623f1b4 fix(settings): stop showing the empty-state message when a list fetch fails
    267414e feat(settings): project type editor in the Settings hub
    81fd9dc Merge pull request 'feat(settings): ticket lookup editors in the Settings hub (MAPPS-172)' (#150) from feat/mapps-172-ticket-lookup-editors into main
    1f72bed refactor(settings): address code-review findings on the ticket editors
    a594723 style(settings): apply cargo fmt to satisfy CI check
    6832e60 docs(settings): refresh module comment now that ticket editors exist
    6dd11f1 feat(settings): ticket status/type/priority/queue/category editors
    be48198 Merge pull request 'feat(settings): centralized Settings hub with standard-type editors (MAPPS-169)' (#148) from feat/mapps-169-settings-hub into main
    7ae3ae5 fix(settings): correct modal prop types and admin-check borrow
    80f008f feat(settings): centralized Settings hub with standard-type editors
    77b319f fix(justfile): supply MOKOSH_OIDC_CLIENT_ID placeholder in down teardown

    Downloads