-
v0.11.0
StableAll checks were successfulreleased this
2026-08-07 19:08:18 +02:00 | 42 commits to main since this releaseChangelog
4066c70Merge pull request 'Release v0.11.0' (#501) from release/v0.11.0 into main
5a4b68fRelease v0.11.0
520f333Merge pull request 'fix(ci): name the disk-exhaustion failure instead of crashing in the linker' (#500) from fix/PMS-740-ci-disk-headroom into main
d2d836cfix(ci): check disk headroom before restoring the cargo cache
a64de44fix(ci): name the disk-exhaustion failure instead of crashing in the linker
aed8ce0Merge pull request 'feat(reports): measured duration per client-request type' (#499) from feat/PMS-732-request-type-durations into main
4bdd790test(reports): cover period boundaries and the no-data case
074e5f6feat(kb): surface the measured duration on the article
d908b79feat(reports): aggregate tracked time by client-request type
45c1a62Merge pull request 'feat(forms): client request forms (MACD) by magic link' (#498) from feat/PMS-730-client-request-forms into main
679edebtest(forms): cover the request-link flow end to end
ee7676dfeat(forms): mount the public request-form surface
8fe96affeat(forms): issue, resolve and redeem a client request link
2ca1ef2fix(tenants): copy the request-link template to new tenants
cda8354feat(forms): add request-link tokens and the request-link email
a91713aMerge pull request 'feat(forms): form definitions with per-field validation' (#497) from feat/PMS-731-form-definitions into main
f733192fix(forms): reject an update that strands a rule on a removed field
34d6c29test(forms): cover the definition round trip and per-field rejection
c06f370feat(forms): serve form definition CRUD and validated submissions
fdba879feat(forms): add the runtime submission validator
e961c65feat(forms): add form definition, field and submission tables
3fab8b7Merge pull request 'feat(tickets): attach the procedure KB article to a ticket' (#495) from feat/PMS-730-ticket-procedure-kb-article into main
e5b4fa0Merge pull request 'fix(just): run the integration suites as the superuser role' (#496) from fix/test-integration-createdb-role into main
955283bfix(just): run the integration suites as the superuser role
f0645e8test(kb): pin the procedure-article round trip and widget exclusion
0f597e7feat(tickets): accept and return the procedure KB article
a111402feat(tickets): add procedure_kb_article_id for the MACD request flow
4a35f7eMerge pull request 'fix(auth): repair the JIT placeholder email once bunyip verifies it' (#494) from fix/PMS-635-repair-jit-placeholder-email into main
f647e52fix(auth): repair the JIT placeholder email once bunyip verifies it
6db29e8Merge pull request 'feat(ip-enrich): consume dunite-ipenrich for advisory ASN/VPN lookup (BUNYIP-475)' (#493) from feat/BUNYIP-475-consume-ipenrich into main
90aada9feat(ip-enrich): consume dunite-ipenrich for advisory ASN/VPN lookup (BUNYIP-475)
675fa35Merge pull request 'chore(ci): guard the OCI build type=gha cache pattern' (#483) from chore/PMS-720-oci-gha-cache-guard into main
b17b515Merge branch 'main' into chore/PMS-720-oci-gha-cache-guard
c083244Merge pull request 'chore(deps): re-pin dunite-stripe-core to the merged rev (DEV-495)' (#492) from chore/DEV-495-repin-dunite-merged-rev into main
b0f8e4cchore(deps): re-pin dunite-stripe-core to the merged rev (DEV-495)
cb578bachore(ci): guard the OCI build type=gha cache patternDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)
-
v0.10.0
StableSome checks failedreleased this
2026-08-04 14:09:16 +02:00 | 78 commits to main since this releaseChangelog
6206452Merge pull request 'Release v0.10.0' (#482) from release/v0.10.0 into main
2dfc2e2Merge branch 'main' into release/v0.10.0
5866bd1Merge pull request 'refactor(billing): consume dunite-stripe-core (DEV-514)' (#491) from feat/DEV-514-consume-stripe-core into main
32fb7derefactor(billing): consume dunite-stripe-core for Stripe primitives (DEV-514)
6613acabuild: depend on shared dunite-stripe-core crate (DEV-514)
962cda3Merge pull request 'docs: name .env.example, not .env.dev, as the source of .env (PMS-708)' (#490) from docs/PMS-708-env-example-not-env-dev into main
53aa1b6docs: refresh quickstart staleness beyond the .env sweep (PMS-708)
0200532docs: sweep remaining .env.dev references to .env.example (PMS-708)
3b47317docs: correct .env provenance in CLAUDE.md + compose guards (PMS-708)
756a083Merge pull request 'feat(billing): payment provider integration for invoice Pay Now (PMS-711)' (#489) from feat/PMS-711-stripe-pay-now into main
b35e23fdocs(billing): record the Pay Now surface + scope boundaries (PMS-711)
c7ee972test(billing): Stripe Pay Now webhook paid/refund/abandoned/bad-sig (PMS-711)
cd50467feat(billing): wire Stripe webhook + portal Pay Now + invoice email (PMS-711)
305c8b2feat(billing): payment-provider trait + Stripe reconciliation core (PMS-711)
59ffee7feat(billing): add payment_refunds + payments.currency migration (PMS-711)
7d8164dMerge pull request 'fix(rls): set the tenant GUC on serving reads of RLS-covered tables (PMS-692)' (#488) from fix/PMS-692-tenant-guc-rls-reads into main
4a93717test(rls): serving reads resolve through the tenant GUC under NOBYPASSRLS (PMS-692)
d54256cci(rls): gate new bare .pool() serving calls without a SAFETY note (PMS-692)
dd55704fix(rls): scope email_intake + SLA-worker reads; drop dead pool accessor (PMS-692)
ceb759cfix(rls): scope portal/auth/tickets/tenants reads by the tenant GUC (PMS-692)
16a069dfix(rls): route Search + Attachment services through the tenant GUC (PMS-692)
38f1870Merge pull request 'fix(auth): skip the per-request bunyip userinfo round-trip (PMS-723)' (#487) from fix/PMS-713-skip-userinfo-per-request into main
61f3b5atest(auth): cover the userinfo short-circuit gate (PMS-723)
914b7fbfix(auth): skip the per-request bunyip userinfo round-trip (PMS-723)
c147687Merge pull request 'feat(seed): production per-account PSA demo, gated to production (PMS-710)' (#485) from feat/PMS-710-per-account-psa-seed into main
383332dMerge branch 'main' into feat/PMS-710-per-account-psa-seed
3a16f32Merge pull request 'fix(e2e): make the TOTP 2fa step window-safe to stop /login/2fa stalls' (#486) from fix/e2e-totp-window-race into main
6748170fix(e2e): make the TOTP 2fa step window-safe to stop /login/2fa stalls
2d44993test(seed): cover the PMS-710 production profile and the gate (PMS-710)
dcdb64efeat(seed): production per-account PSA demo, gated to production (PMS-710)
b1ff76bMerge pull request 'style(e2e): separate the login retry comment blocks' (#484) from fix/PMS-721-e2e-login-response-diagnostics into main
4fad0e7style(e2e): separate the login retry comment blocks
b4111edfix(e2e): log main-frame responses and classify a missing login form
790a925Release v0.10.0
968e7a4Merge pull request 'feat(auth): make profile names Bunyip-owned and read-only' (#481) from feat/PMS-512-bunyip-owned-profile-names into main
aee1f64feat(auth): make profile names Bunyip-owned and read-only
ff38144Merge pull request 'chore(ci): run the compiling jobs on the dev runner label' (#480) from chore/PMS-719-ci-dev-runner-label into main
b098f82chore(ci): run the compiling jobs on the dev runner label
38c8945Merge pull request 'fix(auth): give the OAuth popup a nonce CSP so its script runs' (#479) from fix/PMS-691-oauth-popup-csp-nonce into main
d17051cfix(auth): give the OAuth popup a nonce CSP so its script runs
955e151Merge pull request 'fix(auth): count a failed recovery code against MFA lockout' (#478) from fix/PMS-694-recovery-code-mfa-lockout into main
54ba114fix(auth): count a failed recovery code against MFA lockout
324d3b7Merge pull request 'fix(billing): lock the invoice row before recomputing amount_paid' (#477) from fix/PMS-695-lock-invoice-on-payment into main
34548fffix(billing): lock the invoice row before recomputing amount_paid
2367217Merge pull request 'fix(auth): gate the bunyip path on user and tenant status' (#476) from fix/PMS-698-bunyip-principal-gate into main
12db844fix(auth): gate the bunyip path on user and tenant status
3bcfa97Merge pull request 'fix(notifications): deliver the authored body_html' (#475) from fix/PMS-700-dispatch-body-html into main
f1a45c9fix(notifications): deliver the authored body_html
b68cd71Merge pull request 'fix(auth): increment attempt counters atomically' (#474) from fix/PMS-693-atomic-mfa-attempt-counter into main
caeba42fix(auth): increment attempt counters atomically
378950dMerge pull request 'fix(notifications): skip dispatch when no template matches' (#473) from fix/PMS-701-drop-context-dump-fallback into main
9e17079fix(notifications): skip dispatch when no template matches
9c68160Merge pull request 'fix(reports): derive report SELECT aliases from the whitelist' (#472) from fix/PMS-690-report-alias-injection into main
6773722fix(reports): derive report SELECT aliases from the whitelist
8666db4Merge pull request 'fix(dev): stop the dev stack /ready 503 from Infisical' (#471) from fix/PMS-707-dev-ready-infisical-probe into main
8fc4606fix(dev): stop the dev stack /ready 503 from Infisical
6e0ae4fMerge pull request 'fix(notifications): reseed the 023 templates and report unresolved keys' (#470) from fix/PMS-702-reseed-notification-templates into main
f646985fix(notifications): reseed the 023 templates and report unresolved keys
30cde30Merge pull request 'fix(rls): complete the fail-closed backstop on 11 deferred tables (PMS-683)' (#467) from fix/PMS-683-rls-tail into main
be81c4cMerge branch 'main' into fix/PMS-683-rls-tail
6dce6abMerge pull request 'fix(ready): bound the readiness DB ping at 3s' (#469) from fix/pms-685-readiness-db-ping-timeout into main
6bbda8efix(ready): bound the readiness DB ping at 3s
e4e8a79fix(rls): complete the fail-closed backstop on 11 deferred tablesDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)
-
v0.9.0
StableAll checks were successfulreleased this
2026-07-30 20:26:10 +02:00 | 141 commits to main since this releaseChangelog
43587d2Merge pull request 'Release v0.9.0' (#468) from release/v0.9.0 into main
4903595ci: install gcc + libopenssl-devel on the trimmed openSUSE runner
fa78132Release v0.9.0Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)
-
v0.8.0
StableAll checks were successfulreleased this
2026-07-24 20:19:51 +02:00 | 144 commits to main since this releaseChangelog
a317a14Merge pull request 'Release v0.8.0' (#465) from release/v0.8.0 into main
80fcb02Release v0.8.0
34750f7Merge pull request 'feat(db): fail-closed RLS backstop on quote tables and tenant-RLS coverage guard (PMS-683)' (#464) from fix/PMS-683-rls-backstop into main
f9f98a0Merge pull request 'fix(cleanup): pagination offset overflow, constant-time code check, module docs (PMS-684)' (#463) from fix/PMS-684-cleanup into main
0c22cc0feat(db): enable RLS on quote tables and add tenant-RLS coverage guard
9381130fix(cleanup): offset overflow, constant-time code check, module docs
f2dd3a9Merge pull request 'test(auth): lock in bootstrap-admin login without email verification (PMS-676)' (#462) from feat/PMS-676-bootstrap-admin-unverified-login into main
7f371b4test(auth): lock in bootstrap-admin login without email verification (PMS-676)
25cb584Merge pull request 'chore(config): reconcile OAUTH_SUPER_ADMIN env var name with the code (PMS-682)' (#461) from chore/PMS-682-oauth-super-admin-env-drift into main
006bd81chore(config): reconcile OAUTH_SUPER_ADMIN env var name with the code (PMS-682)
7f62826Merge pull request 'feat(auth): invalidate access tokens on password reset/change (PMS-681)' (#460) from feat/PMS-681-invalidate-tokens-on-password-change into main
c28dff4refactor(auth): address PMS-681 review (fold password_changed_at into the user load, atomic revoke)
acd0b58feat(auth): invalidate access tokens on password reset/change (PMS-681)
80c261fMerge pull request 'feat(auth): rate-limit /forgot-password per (IP, email) (PMS-680)' (#459) from feat/PMS-680-forgot-password-rate-limit into main
f6b9a77feat(auth): rate-limit /forgot-password per (IP, email) (PMS-680)
ad6e4ebMerge pull request 'test(auth): password-reset redeem coverage (PMS-659)' (#458) from test/PMS-659-password-reset-coverage into main
066e3f7test(auth): cover the password-reset redeem flow (PMS-659)
d2cbd64Merge pull request 'feat(data): add admin Load demo data endpoint (PMS-679)' (#457) from feat/PMS-679-load-demo-data-button into main
67c16d4feat(data): add admin "Load demo data" endpoint (PMS-679)
3ea1df7Merge pull request 'feat(dev): just verify-demo for the demo seed + import/export path (PMS-677)' (#456) from feat/PMS-677-verify-demo-recipe into main
5713f70feat(dev): addjust verify-demofor the demo-critical seed + import/export path (PMS-677)
9420509Merge pull request 'feat(quotes): convert an accepted quote into a Project (PMS-674)' (#455) from feat/PMS-674-convert-quote-to-project into main
bb2e456test(quotes): integration coverage for quote-to-project conversion (PMS-674)
302bcd0feat(quotes): mount POST /quotes/{id}/convert (PMS-674)
a61298dfeat(quotes): convert an accepted quote into a Project (PMS-674)
b5c11a0Merge pull request 'feat(quotes): send to client + portal accept/decline sign-off (PMS-673)' (#454) from feat/PMS-673-quote-send-and-portal-signoff into main
d6b241fMerge pull request 'feat(quotes): quotes module CRUD with server-computed totals (PMS-672)' (#453) from feat/PMS-672-quotes-module-crud into main
1142548test(quotes): integration coverage for send and client sign-off (PMS-673)
fd88bdefeat(quotes): send route plus the portal sign-off routes (PMS-673)
7ff7d54feat(quotes): issue to the client and record their sign-off (PMS-673)
f657485feat(portal): rate limiter for the quote decision routes (PMS-673)
ece3d9afeat(email): quote-ready template for the client sign-off link (PMS-673)
9196a2btest(quotes): integration coverage for CRUD, totals, freezing, tenancy (PMS-672)
b630b68feat(quotes): mount the quotes routes under /api/v1 (PMS-672)
2bcc117feat(quotes): quotes service with server-computed totals (PMS-672)
5955c86feat(quotes): quote + line DTOs and the lifecycle status model (PMS-672)
438c84dMerge pull request 'feat(quotes): promote the quote stub to a real entity + quote_lines (PMS-671)' (#452) from feat/PMS-671-quotes-entity-schema into main
2b97c45test(approvals): seed a company for the quote fixture (PMS-671)
e233923feat(quotes): promote the quote stub to a real entity + quote_lines (PMS-671)
7b4d1faMerge pull request 'feat(auth): suspicious-login notify-and-approve gate for password login (PMS-658)' (#451) from feat/PMS-658-suspicious-login-approval into main
5d9a6e0feat(auth): suspicious-login notify-and-approve gate for password loginDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)
-
v0.7.0
StableAll checks were successfulreleased this
2026-07-15 14:18:47 +02:00 | 185 commits to main since this releaseChangelog
2d3f589Merge pull request 'Release v0.7.0' (#450) from release/v0.7.0 into main
b8a52cbRelease v0.7.0
3aeaac9Merge pull request 'feat(auth): alert users on a new-country login (PMS-657)' (#449) from feat/PMS-657-login-location-alerts into main
e778b46feat(auth): user-settable login-location opt-out, non-blocking alert (PMS-657)
100ade1feat(auth): alert users on a new-country login (PMS-657)
fe5d511Merge pull request 'feat(seed): load first-visit demo data from a committed bundle, not hardcoded Rust (PMS-651)' (#448) from feat/PMS-651-data-driven-seed into main
1c0c120feat(seed): load first-visit demo data from a committed bundle, not hardcoded Rust (PMS-651)
40a8b83Merge pull request 'test(seed): assert demo seed is the clean baseline with no zQA/QA prefix (PMS-629)' (#447) from fix/PMS-629-demo-seed-no-zqa into main
2da0a7etest(seed): assert demo seed is the clean baseline with no zQA/QA prefix (PMS-629)
dd5e390Merge pull request 'fix(e2e): correct stale provisioning docs + cli.rs drift, skip suite when staging unseeded' (#446) from fix/PMS-656-e2e-provisioning-cleanups into main
abbe8c7fix(e2e): correct stale provisioning docs + cli.rs drift, skip suite when staging unseeded
fc82ffeMerge pull request 'fix(audit): record real client IP behind Traefik' (#444) from fix/PMS-587-audit-client-ip into main
af6f8d9Merge remote-tracking branch 'origin/main' into fix/PMS-587-audit-client-ip
b321f82Merge pull request 'fix(e2e): submit login once with rate-limit backoff, surface the hub banner' (#445) from fix/PMS-654-e2e-login-backoff into main
c0721b4Merge pull request 'fix(data): defer FK checks so tenant import survives cyclic schema' (#442) from feat/PMS-648-deferrable-fk-import into main
4f62cc0fix(e2e): submit login once with rate-limit backoff, surface the hub banner
6de4363Merge remote-tracking branch 'origin/main' into feat/PMS-648-deferrable-fk-import
b3954a1fix(audit): record real client IP behind Traefik
bfd56b9Merge pull request 'feat(data): include tenant_name in the export envelope (PMS-647)' (#443) from feat/PMS-647-export-tenant-name into main
74b50a6ci: re-trigger checks (E2E flake on shared staging account)
d12beadfeat(data): include tenant_name in the export envelope (PMS-647)
86ae88bfix(data): defer FK checks so tenant import survives cyclic schema
f2de869Merge pull request 'fix(data): break tenants->company FK before import wipe (un-red main, PMS-648)' (#441) from feat/PMS-648-data-import into main
8cde8b3test(data): quarantine import round-trip until deferrable-FK redesign
7380d40fix(data): break tenants->company FK before the import wipe
9880f2eMerge pull request 'test(data): fix red integration round-trip (robust to pre-seeded data, PMS-648)' (#440) from feat/PMS-648-data-import into main
07fdd05test(data): make export/import round-trip robust to pre-seeded tenant data
8f01cb1Merge pull request 'feat(data): tenant data import - envelope validation + id-remap core (PMS-648)' (#439) from feat/PMS-648-data-import into main
575bd33Merge pull request 'feat(data): admin-only tenant data export endpoint (PMS-647)' (#438) from feat/PMS-647-data-export into main
88df505feat(data): tenant data import wipe-and-replace load + round-trip test
d193e46feat(data): tenant data import - envelope validation + id-remap core
25a583efeat(data): admin-only tenant data export endpoint
a9f0f4dMerge pull request 'fix(e2e): make the setup onboarding PUT best-effort, not fatal (PMS-645)' (#437) from fix/PMS-645-onboard-best-effort into main
3c42e55fix(e2e): make the setup onboarding PUT best-effort, not fatal
a89cf26Merge pull request 'fix(release): sync Cargo.lock on release and correct main's drift (PMS-642)' (#435) from fix/PMS-642-release-syncs-cargo-lock into main
64717d5Merge pull request 'fix(dev): mount ./tests so pre-commit compiles integration tests (PMS-640)' (#434) from fix/PMS-640-precommit-compile-integration-tests into main
54920a7Merge pull request 'feat(settings): DB-backed SMTP email config with live mailer swap (PMS-638)' (#433) from feat/PMS-638-email-db-settings into main
7663cb3Merge branch 'main' into fix/PMS-642-release-syncs-cargo-lock
15d3141Merge branch 'main' into fix/PMS-640-precommit-compile-integration-tests
dba0e5dMerge branch 'main' into feat/PMS-638-email-db-settings
db11e3dMerge pull request 'fix(e2e): onboard the E2E fixture account so specs are not bounced to onboarding (PMS-641)' (#436) from fix/PMS-641-onboard-e2e-account into main
b777e41fix(e2e): onboard the E2E fixture account so specs are not bounced to onboarding
afec11echore(release): drop no-op SQLX_OFFLINE from the cargo update step
e09f70dfix(release): sync Cargo.lock on release and correct main's drift
9375020fix(dev): mount ./tests so pre-commit compiles the integration tests
e9e19b8fix(test): wrap LogMailer in SharedMailer for create_api_router
3cc8a96fix(settings): build-validate email config before persisting it
9040a0bfeat(settings): DB-backed SMTP email config with live mailer swapDownloads
-
Source code (ZIP)
2 downloads
-
Source code (TAR.GZ)
1 download
-
Source code (ZIP)
-
v0.6.0
StableAll checks were successfulreleased this
2026-07-07 15:56:59 +02:00 | 233 commits to main since this releaseChangelog
c43bd44Merge pull request 'Release v0.6.0' (#432) from release/v0.6.0 into main
dc4436fRelease v0.6.0
2afc571Merge pull request 'feat(seed): extend qa-seed with assets, KB, SLA, and appointments (PSA-55)' (#431) from feat/PSA-55-qa-seed-demo-gaps into main
10bb709Merge remote-tracking branch 'origin/main' into feat/PSA-55-qa-seed-demo-gaps
9e27995fix(e2e): tolerate bunyip 2FA auto-submit in the login helper
4b8d73dfeat(seed): give the QA SLA policy a response/resolution target (PSA-55)
1568eecfeat(seed): extend qa-seed with assets, KB, SLA, and appointments (PSA-55)
66d74f0Merge pull request 'feat(seed): add richer showcase demo dataset with create/refresh' (#430) from feat/PMS-620-showcase-seed-dataset into main
0fbbf13feat(seed): add richer showcase demo dataset with create/refresh
fd9c86eMerge pull request 'fix(email): set Message-ID header on every outbound message' (#428) from fix/PMS-624-outbound-message-id into main
10bfc58fix(email): set Message-ID header on every outbound message
dc3c254Merge pull request 'feat(e2e): exclude external-service flows from production E2E runs' (#427) from feat/PMS-608-exclude-external-from-prod-e2e into main
83a5963feat(e2e): exclude external-service flows from production E2E runs
0424c83Merge pull request 'fix(auth): enforce role ceiling on user update and fix OAuth callback XSS' (#426) from fix/PMS-625-auth-audit-privesc-xss into main
8fe83cdfix(auth): enforce role ceiling on user update and fix OAuth callback XSS
8d4b241Merge pull request 'feat(auth): return 410 Gone (ACCOUNT_DELETED) for tombstoned users on the API surface' (#421) from feat/MAPPS-348-410-gone-account-deleted into main
a01c616Merge pull request 'test(e2e): un-fixme form-validation now that MAPPS-347 SPA fix has merged' (#422) from test/MAPPS-347-unfixme-form-validation into main
05fdfc7feat(auth): return 410 Gone (ACCOUNT_DELETED) for tombstoned users on the API surface
c1b50fdtest(e2e): un-fixme form-validation now that MAPPS-347 SPA fix has merged
58cd083Merge pull request 'docs(webhook): describe BUNYIP_WEBHOOK_SECRET as service-wide, not per-Application' (#424) from docs/BUNYIP-332-correct-webhook-secret-comment into main
629c4e7ci: retrigger against rebased tip (post-BUNYIP-331 e2e fix)
6a8037adocs(webhook): describe BUNYIP_WEBHOOK_SECRET as service-wide, not per-Application
59aa239Merge pull request 'test(e2e): make fillTotpStep + setInputValue aware of the BUNYIP-331 auto-submit' (#425) from test/BUNYIP-331-autosubmit-aware-fillTotpStep into main
da283a6test(e2e): make fillTotpStep + setInputValue aware of the BUNYIP-331 auto-submit
bb55f38Merge pull request 'feat(auth): receive Bunyip account_deleted webhook and soft-delete the mokosh user' (#416) from feat/PMS-591-bunyip-account-deleted-receiver into main
0a29847test(e2e): fixme form-validation spec on MAPPS-347 SPA regression
a86d8e2Merge pull request 'feat(sla): validate schedule/holiday JSON on write (reject malformed, 422)' (#420) from feat/PMS-604-sla-json-validation into main
774cc38test(sla): cover accept/reject cases for schedule and holiday JSON
f6c3ad8feat(sla): reject malformed holiday-calendar JSON on write (422)
838306cfeat(sla): reject malformed business-hours schedule JSON on write (422)
e66e7b0refactor(sla): expose clock weekday/time parsers to the module
1741855Merge remote-tracking branch 'origin/main' into feat/PMS-591-bunyip-account-deleted-receiver
6c2c6catest(auth): match synthetic-name expectations to titlecased output
d0ec426feat(auth): receive Bunyip account_deleted webhook and soft-delete the mokosh userDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)
-
v0.5.0
StableAll checks were successfulE2E / Playwright against staging (push) Successful in 1m13sCheck / fmt + clippy + build + tests (push) Successful in 1m29sBuild OCI container / Build and push mokosh-server image (push) Successful in 10m20sIntegration / integration tests (push) Successful in 11m13sreleased this
2026-07-01 19:02:59 +02:00 | 267 commits to main since this releaseChangelog
85a0bdeMerge pull request 'Release v0.5.0' (#418) from release/v0.5.0 into main
46b6a89fix(e2e): run setup in firefox so bearer capture stops flaking on chromium
4bca793Merge branch 'main' into release/v0.5.0
ef22f82Merge pull request 'fix(e2e): DOM-set login inputs so headless chromium submits credentials (PMS-592)' (#419) from fix/PMS-592-login-fill into main
943e28bfix(e2e): survive the post-login chromium crash so the api suite runs
d4c03ecfix(e2e): --disable-dev-shm-usage so chromium stops crashing in CI
1ab473efix(e2e): capture bearer via in-app nav so the WASM token survives
8ede68efix(e2e): DOM-set login inputs so headless chromium submits credentials
a4eb28dRelease v0.5.0
bd2b2fdMerge pull request 'chore(docs): consolidate markdown under docs/ + distill audits into changelog (PSA-48)' (#417) from chore/PSA-48-docs-sanitize into main
6b2bcc3revert(migrations): restore immutable applied migrations
569c014chore(docs): consolidate markdown under docs/, distill audits + handoff into changelog
70bccc2Merge pull request 'ci(migrations): guard against editing already-committed migrations' (#415) from feat/DEV-395-migration-immutability-guard into main
5f16f44Merge branch 'main' into feat/DEV-395-migration-immutability-guard
18cf5beMerge pull request 'docs(sla): JSONB-vs-normalized decision for schedule/holidays (PMS-585)' (#414) from docs/PMS-585-sla-jsonb-decision into main
9fb95e2ci(migrations): guard against editing already-committed migrations
87ea7b6docs(sla): record JSONB-vs-normalized decision for schedule/holidays (PMS-585)
ffc296eMerge pull request 'feat(contacts): backfill existing company industries to canonical set (PMS-602)' (#413) from feat/PMS-602-backfill-company-industries into main
3ada191style(contacts): wrap long macro calls to satisfy CI rustfmt (PMS-602)
8202739feat(bootstrap): normalize-company-industries subcommand (PMS-602)
3b32f6dtest(contacts): industry backfill map integrity (PMS-602)
a5b9223feat(contacts): company-industry backfill normalizer (PMS-602)
9e69653Merge pull request 'feat(contacts): company-industries settings lookup (PMS-601)' (#412) from feat/PMS-601-company-industries-lookup into main
0478ecafeat(contacts): company-industry lookup endpoints (PMS-601)
bc5ed67feat(contacts): company-industry lookup CRUD service (PMS-601)
7e01291feat(types): CompanyIndustry lookup DTOs (PMS-601)
acf9280feat(tenants): seed company_industries for new tenants (PMS-601)
26de04dfeat(billing): add company_industries lookup table (PMS-601)
b09fdd2Merge pull request 'feat(contacts): distinct title/department values endpoint for autocomplete (PMS-583)' (#411) from feat/PMS-583-contact-field-suggestions into main
0727b16feat(contacts): distinct title/department values endpoint for autocomplete (PMS-583)
f778898Merge pull request 'docs(billing): document invoice lifecycle and void-vs-cancel (PMS-580)' (#410) from docs/PMS-580-invoice-lifecycle into main
bf0c976docs(billing): document invoice lifecycle and void-vs-cancel (PMS-580)Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)
-
v0.4.0
StableAll checks were successfulBuild OCI container / Build and push mokosh-server image (push) Successful in 5m12sreleased this
2026-06-30 17:33:32 +02:00 | 299 commits to main since this releaseChangelog
2e6ba89Merge pull request 'Release v0.4.0' (#407) from release/v0.4.0 into main
4119b20Merge branch 'main' into release/v0.4.0
9f5e7fcMerge pull request 'fix(e2e): settle hub login form before fill + URL-based 2FA advance signal' (#409) from fix/PMS-595-chromium-credential-resubmit-settle into main
4cf23bdfix(e2e): settle hub login form before fill + URL-based 2FA advance signal
026120bfix(e2e): recover chromium SPA login from credential-form re-render race
60d9b9cRelease v0.4.0
3bafb3cMerge pull request 'fix(auth): explicit Validation::new(Algorithm::HS256) + mint iss/aud/nbf claims' (#406) from fix/MAPPS-334-explicit-validation-secret-floor-v2 into main
92ed8c1fix(auth): disable validate_aud until strict iss/aud flip lands
a6db9f5Merge pull request 'fix(auth): bind userinfo.sub == claims.sub; truthful email_verified_at' (#404) from fix/MAPPS-335-sub-binding-and-email-verified-truth into main
d387ebdMerge pull request 'fix(auth): kid-aware JWKS refresh + cap force-refresh cadence + active checks on legacy fallback' (#405) from fix/MAPPS-337-jwks-kid-aware-redirect-cap-active-checks into main
5722869fix(auth): kid-aware JWKS refresh + cap force-refresh cadence + active checks on legacy fallback
9e70eccfix(auth): bind userinfo.sub == claims.sub; truthful email_verified_at
ab59925fix(auth): explicit Validation::new(Algorithm::HS256) + mint iss/aud/nbf claims
4a857d2Merge pull request 'fix(config): refuse to boot with a dev-default JWT_SECRET outside dev/test (PMS-497)' (#370) from fix/PMS-497-jwt-secret-production-guard into main
19dc713Merge pull request 'feat(api): emit security response headers on every response (PMS-388)' (#367) from feat/PMS-388-app-level-security-headers into main
102b80bMerge pull request 'fix(dev): bind dev Postgres to loopback and reject public LAN IP' (#399) from fix/dev-db-loopback-bind-on-main into main
7aa5e68Merge branch 'main' into fix/PMS-497-jwt-secret-production-guard
1854d64Merge pull request 'feat(roles): every mokosh user is an admin of their own instance' (#401) from feat/MAPPS-330-everyone-is-mokosh-admin into main
39395edMerge branch 'main' into feat/PMS-388-app-level-security-headers
7da858bMerge pull request 'fix(auth): cap + anti-replay TOTP verification on agent login' (#400) from fix/PMS-502-mfa-totp-attempt-cap-anti-replay into main
7fe6aeaMerge branch 'main' into feat/PMS-388-app-level-security-headers
1c9c4faMerge main: drop superseded postgres-loopback hunk, keep justfile RFC1918 filter
0fb2d21chore(migrations): renumber MAPPS-330 backfill 084 -> 085
0ac0b6fMerge pull request 'fix(e2e): deflake firefox form-validation by waiting for nav links to be visible' (#402) from fix/PMS-543-firefox-nav-visible-wait into main
f3f1e49fix(e2e): wait for nav links to be visible to deflake firefox form-validation
9c49820fix(migration): drop nonexistent users.deleted_at guard from MAPPS-330 backfill
cf5860bfeat(roles): every mokosh user is an admin of their own instance
9f61780fix(auth): cap + anti-replay TOTP verification on agent login
c8f2250Merge pull request 'fix(dev): bind app Postgres to loopback and fail loud on missing DB secrets (PMS-496)' (#392) from fix/PMS-496-postgres-loopback-bind-fail-loud-secrets into main
b9f0cffMerge branch 'main' into fix/PMS-496-postgres-loopback-bind-fail-loud-secrets
071b3ddfix(dev): bind dev Postgres to loopback and reject public LAN IP
f8ea1f8Merge pull request 'test(e2e): expect inline "Company is required." copy on new-ticket form (PMS-535)' (#394) from fix/PMS-535-company-required-copy into main
508fcebfix(config): repair merge tail + drop superseded validate_jwt_secret (PMS-497)
7c400b9test(e2e): expect inline "Company is required." copy on new-ticket form (PMS-535)
b99cb20Merge remote-tracking branch 'origin/main' into feat/PMS-388-app-level-security-headers
f7091aeMerge remote-tracking branch 'origin/main' into fix/PMS-497-jwt-secret-production-guard
72975a0ci: re-trigger E2E against staging (PMS-496)
9f74f7cMerge remote-tracking branch 'origin/main' into fix/PMS-496-postgres-loopback-bind-fail-loud-secrets
8007fb9Merge pull request 'Derive OCI publish mode from trigger to stop twin-publish race (GOV-15)' (#382) from fix/GOV-15-twin-trigger-publish-mode into main
817b4d9Merge branch 'main' into fix/GOV-15-twin-trigger-publish-mode
021897aMerge pull request 'test(kb): format assert_eq! in top-driving test, land coverage (PMS-533)' (#393) from fix/PMS-533-kb-test-rustfmt into main
f859ec0test(kb): format assert_eq! in top-driving test, land coverage (PMS-533)
300c0abfix(dev): bind app Postgres to loopback and fail loud on missing DB secrets (PMS-496)
a0e3b64Merge pull request 'ci(e2e): usebun xinstead of missingbunxshim (PMS-532)' (#391) from fix/PMS-532-e2e-bunx-shim into main
a1a1ef9ci(e2e): usebun xinstead of missingbunxshim (PMS-532)
233c31aMerge pull request 'feat(dev): ensure-env generates all self-owned secrets (PMS-490)' (#390) from feat/PMS-490-ensure-env-generates-secrets into main
75c11b9feat(dev): ensure-env generates all self-owned secrets (PMS-490)
d1f0b51Merge pull request 'chore(auth): drop stale crates/mokosh-auth-http comment refs (PMS-295)' (#389) from feat/PMS-295-remove-mokosh-auth-mechanism-2 into main
88b5a47chore(auth): drop stale crates/mokosh-auth-http comment refs (PMS-295)
1c619d7feat(auth): remove mokosh-auth; bunyip-as-OP is the sole OP (PMS-295)
d29284eMerge pull request 'feat(workflows): add ticket templates for new-ticket pre-fill (PMS-448)' (#387) from feat/PMS-448-ticket-templates into main
eb20ab6feat(workflows): add ticket templates for new-ticket pre-fill (PMS-448)
443e2e7ci(e2e): run E2E on opensuse-dev runner with pre-baked Playwright (PMS-423)
4145f0dMerge pull request 'feat(portal): rate-limit and lock out brute-force portal logins (PMS-501)' (#385) from feat/PMS-501-portal-login-rate-limit-lockout into main
9f431b3feat(portal): rate-limit and lock out brute-force portal logins (PMS-501)
06166acMerge pull request 'feat(time-tracking): split billable from worked minutes per entry (PMS-395)' (#384) from feat/PMS-395-billable-minutes-split into main
0ddb5d8feat(time-tracking): split billable from worked minutes per entry (PMS-395)
ac07565Merge pull request 'fix(config): require 64-hex ENCRYPTION_KEY outside dev/test (PMS-498)' (#383) from fix/PMS-498-require-hex-encryption-key-in-prod into main
cb2789efix(config): require 64-hex ENCRYPTION_KEY outside dev/test (PMS-498)
4ae07e4fix(ci): derive publish mode from trigger to stop twin-publish race
df0090aMerge pull request 'feat(db): self-provision split DB roles at startup (PMS-489)' (#381) from feat/PMS-489-self-provision-db-roles into main
c73584afeat(db): self-provision split DB roles at startup (PMS-489)
8daf44dMerge pull request 'fix(auth): enforce role ceiling on create_user (PMS-503)' (#380) from fix/PMS-503-create-user-role-ceiling into main
10f4a2cfix(auth): enforce role ceiling on create_user (PMS-503)
6d92b7bMerge pull request 'feat(email-intake): store inbound email attachments on the ticket (PMS-450)' (#379) from feat/PMS-450-email-intake-attachments into main
8a5cf9afeat(email-intake): store inbound email attachments on the ticket (PMS-450)
9999177Merge pull request 'fix(config): refuse dev JWT_SECRET/ENCRYPTION_KEY outside dev/test (PMS-499)' (#378) from fix/PMS-499-guard-dev-secrets-in-prod into main
aaad18cfix(config): refuse dev JWT_SECRET/ENCRYPTION_KEY outside dev/test (PMS-499)
a37c2bfMerge pull request 'chore(toolchain): pin rust-toolchain.toml to 1.94.1 (PMS-412)' (#377) from chore/PMS-412-pin-rust-toolchain into main
8262fb9chore(toolchain): pin rust-toolchain.toml to 1.94.1 (PMS-412)
0952d0fMerge pull request 'feat(assets): add licence section (vendor, seat count, expiry) to CMDB (PMS-454)' (#376) from feat/PMS-454-asset-license-fields into main
c3b4f31feat(assets): add licence section (vendor, seat count, expiry) to CMDB (PMS-454)
df9ea35Merge pull request 'chore(ci): rename OCI build job to mokosh-server (PMS-133)' (#374) from chore/PMS-133-rename-oci-job-to-mokosh-server into main
71932eechore(ci): rename OCI build job to mokosh-server (PMS-133)
ee465acMerge pull request 'chore(security): triage audit roll-up findings (PMS-504)' (#373) from chore/PMS-504-security-audit-triage into main
2d4cf75Merge pull request 'ci(oci): switch build cache from type=registry/inline to type=gha' (#366) from fix/PMS-525-oci-gha-build-cache into main
fd0051cMerge branch 'main' into fix/PMS-525-oci-gha-build-cache
6dc0077chore(security): triage audit roll-up findings (PMS-504)
05ff30cMerge pull request 'fix(ci): pass PR head ref as data, scope contents:write to publish job (PMS-500)' (#372) from fix/PMS-500-harden-create-release-injection into main
7cdf124fix(ci): pass PR head ref as data, scope contents:write to publish job (PMS-500)
821b04aMerge pull request 'feat(dev): merge compose.dev-sso overlay into compose.dev.yml (PMS-511)' (#371) from feat/PMS-511-merge-dev-compose-files into main
4dd9fdbfeat(dev): merge compose.dev-sso overlay into compose.dev.yml (PMS-511)
e6089c9fix(config): refuse to boot with a dev-default JWT_SECRET outside dev/test (PMS-497)
922d736Merge pull request 'feat(cli): fold bootstrap-infisical/clients/qa subcommands into mokosh-server (PMS-494)' (#369) from feat/PMS-494-fold-bootstrap-subcommands-into-server into main
bf8a0d6feat(cli): fold bootstrap-infisical/clients/qa subcommands into mokosh-server (PMS-494)
ac94aaaMerge pull request 'feat(auth): stamp profile_completed_at on Bunyip OIDC INSERT when both name claims arrive (MAPPS-329)' (#368) from feat/MAPPS-329-auto-populate-profile-from-bunyip into main
1a2e641feat(auth): stamp profile_completed_at on Bunyip OIDC INSERT when both name claims arrive (MAPPS-329)
dc6a8bafeat(api): emit security response headers on every response (PMS-388)
f3b1d12ci(oci): switch build cache from type=registry/inline to type=gha
7272270Merge pull request 'test(e2e): un-fixme form-validation + auth-ui to verify AC7 on staging (PMS-519)' (#364) from test/PMS-519-unfixme-form-validation into main
3444532Merge pull request 'fix(e2e): handle the OIDC consent screen in loginViaSpa (PMS-521)' (#365) from fix/PMS-521-loginviaspa-consent into main
bd21d6dtest(e2e): target the visible desktop sidebar, not the hidden drawer (PMS-519)
3d0320etest(e2e): drive form-validation via in-app nav, not hard goto (PMS-519)
b222ff4test(e2e): instrument form-validation + isolate from auth-ui (PMS-519)
356a9ceMerge branch 'fix/PMS-521-loginviaspa-consent' into test/PMS-519-unfixme-form-validation
25c1ea3fix(e2e): handle the OIDC consent screen in loginViaSpa (PMS-521)
44d7796test(e2e): un-fixme form-validation + auth-ui login to verify on staging (PMS-519)
37f3fa9Merge pull request 'test(e2e): form-validation regression coverage (PMS-518 AC7)' (#363) from test/PMS-518-form-validation-e2e into main
98378e6test(e2e): fix form-validation spec quarantine + login frugality (review)
729257ftest(e2e): add form-validation regression coverage (PMS-518 AC7)
bc51006Merge pull request 'fix(timesheets): request full page in history range test (PMS-507)' (#361) from fix/PMS-507-timesheet-history-range into main
b4403d2Merge origin/main into fix/PMS-507-timesheet-history-range
aab6a71Merge pull request 'fix(tickets): honour contact_id filter on list_tickets (MAPPS-311)' (#362) from fix/MAPPS-311-tickets-contact-id-filter into main
248c1b0fix(tickets): honour contact_id filter on list_tickets (MAPPS-311)
771ca07Merge pull request 'feat(attachments): ticket-note attachment upload / download / delete (PMS-483)' (#358) from feat/PMS-483-note-attachments into main
a7d2f6dfix(attachments): portal sub-router needs its own auth middleware layer (PMS-483)
a5619c6fix(test): portal login body must include tenant_slug (PMS-483)
e9443dcMerge pull request 'feat(timesheets): status filter + multi-week range + decision audit on list (PMS-506)' (#360) from feat/PMS-506-timesheet-history into main
43583f1fix(timesheets): request full page in history range test (PMS-507)
4ae0471fix(test): seed contact uses is_portal_user, not portal_enabled (PMS-483)
3227ab4fix(test): timesheet_history fixture must spell out pagination (PMS-506)
4451660fix(test): seed distinctly-named companies in portal cross-company test (PMS-483)
60b7fe5feat(timesheets): status filter + multi-week range + decision audit on list (PMS-506)
b99e0baMerge pull request 'feat(approvals): change_requests + quotes parent tables (PMS-484)' (#357) from feat/PMS-484-approvals-parent-tables into main
46f0ea9Merge pull request 'feat(kb): top-ticket-driving-articles endpoint (PMS-485)' (#356) from feat/PMS-485-kb-top-driving into main
5c0ad78feat(attachments): ticket-note attachment upload / download / delete (PMS-483)
d54fec4feat(approvals): change_requests + quotes parent tables (PMS-484)
79300a1feat(kb): top-ticket-driving-articles endpoint (PMS-485)
c500b82Merge pull request 'docs(e2e): add dev-docs/e2e.md engineering reference' (#355) from docs/PMS-492-e2e-kb into main
df31fd6docs(e2e): add dev-docs/e2e.md engineering reference
7d24578Merge pull request 'docs: add postgres provisioning + RLS conversation transcription' (#354) from docs/postgres-security-transcription into main
46f4358docs: add postgres provisioning + RLS conversation transcription
3713f71 Merge pull request 'chore(dev): move RLS bootstrap to postgres initdb.d, drop password-drift reset' (#353) from chore/PMS-488-postgres-initdb-rls into main
c55ae98chore(dev): move RLS bootstrap to postgres initdb.d, drop password-drift reset
3bcd7dbMerge pull request 'refactor: collapse CreateTicketRequest + RequireAdminUser + CurrentContact::tenant (PMS-479)' (#352) from feat/PMS-479-refactor-boilerplate into main
13ca35drefactor: collapse CreateTicketRequest + RequireAdminUser + CurrentContact::tenant (PMS-479)
81bbfb6Merge pull request 'feat(dashboards): scheduled dashboard delivery worker (PMS-471)' (#349) from feat/PMS-471-scheduled-dashboards into main
bbebe35Merge pull request 'feat(approvals): polymorphic approval surface across tickets + time-entries (PMS-470)' (#351) from feat/PMS-470-polymorphic-approvals into main
607979bMerge pull request 'feat(notes): expose created_by_contact_id on note DTO + contact-notes feed (PMS-468)' (#350) from feat/PMS-468-portal-notes-attachments into main
94f4d1efeat(approvals): polymorphic approval surface across tickets + time-entries (PMS-470)
371c12afeat(dashboards): scheduled dashboard delivery worker (PMS-471)
9a48f58feat(notes): expose created_by_contact_id on note DTO + contact-notes feed (PMS-468)
2ceb931Merge pull request 'feat(workflows): mutating actions on transition triggers + per-tenant cycle cap (PMS-467)' (#345) from feat/PMS-467-workflow-mutating-transitions into main
74e08a0feat(workflows): mutating actions on transition triggers + per-tenant cycle cap (PMS-467)
f89a41bMerge pull request 'feat(reports): scheduled report delivery worker (PMS-478)' (#348) from feat/PMS-478-scheduled-reports into main
c14ca8eMerge pull request 'feat(assets): CI impact-graph traversal endpoint (PMS-475)' (#347) from feat/PMS-475-ci-impact-traversal into main
1cbc846feat(reports): scheduled report delivery worker (PMS-478)
5cc093efeat(assets): CI impact-graph traversal endpoint (PMS-475)
41fbfefMerge pull request 'feat(email-intake): auto-create contact + reply-as-comment + intake-log audit (PMS-469)' (#346) from feat/PMS-469-email-intake-follow-ups into main
660e4d7feat(email-intake): auto-create contact + reply-as-comment + intake-log audit (PMS-469)
7a9b4daMerge pull request 'feat(reports): saved-report execution runtime - tickets, equality+IN, whitelisted columns (PMS-477)' (#344) from feat/PMS-477-report-execution into main
b81787afeat(reports): saved-report execution runtime - tickets, equality+IN, whitelisted columns (PMS-477)
d32fd2aMerge pull request 'feat(workflows): ticket.status_changed + ticket.priority_changed triggers (PMS-448 phase 2)' (#343) from feat/PMS-448-phase2-more-triggers into main
0638a98Merge pull request 'feat(email-intake): admin CRUD for tenant intake tokens (PMS-450 phase 2)' (#342) from feat/PMS-450-phase2-token-admin into main
5b0dcb9Merge pull request 'feat(workflows): ticket.created workflow rules with in-line executor (PMS-448 phase 1)' (#341) from feat/PMS-448-ticket-created-rules into main
9d28927feat(workflows): ticket.status_changed + ticket.priority_changed triggers (PMS-448 phase 2)
0b55f25feat(email-intake): admin CRUD for tenant intake tokens (PMS-450 phase 2)
8b499a6Merge pull request 'feat(approvals): per-ticket approval requests (PMS-451 phase 1)' (#334) from feat/PMS-451-ticket-approvals into main
5f2f6bfMerge pull request 'feat(portal): customer ticket comments (PMS-449 phase 1)' (#339) from feat/PMS-449-portal-ticket-comments into main
1a17f43fix(approvals): use axum 0.8 brace path-capture syntax (PMS-451)
eb6a6ebfeat(approvals): per-ticket approval requests (PMS-451 phase 1)
7f28f34feat(workflows): ticket.created workflow rules with in-line executor (PMS-448 phase 1)
746efc2Merge pull request 'feat(reports): saved custom-report definitions (PMS-457 phase 1)' (#340) from feat/PMS-457-saved-reports into main
6706fa6feat(reports): saved custom-report definitions (PMS-457 phase 1)
5811441Merge pull request 'feat(cmdb): ITIL CI classification on asset types and lifecycle on assets (PMS-456)' (#336) from feat/PMS-456-itil-ci-types into main
642f84cMerge pull request 'feat(email-intake): tenant-scoped email-to-ticket POST endpoint (PMS-450 phase 1)' (#337) from feat/PMS-450-email-intake into main
f655561feat(portal): customer ticket comments (PMS-449 phase 1)
5071ad9feat(email-intake): tenant-scoped email-to-ticket POST endpoint (PMS-450 phase 1)
9154572Merge pull request 'feat(tickets): source KB article on ticket creation (PMS-452 phase 1)' (#338) from feat/PMS-452-kb-source-ticket into main
2b9f90cfeat(tickets): source KB article on ticket creation (PMS-452 phase 1)
d25ebcafeat(cmdb): ITIL CI classification on asset types and lifecycle on assets (PMS-456)
17f9154Merge pull request 'feat/PMS-453-saved-dashboards' (#335) from feat/PMS-453-saved-dashboards into main
99fb6affix(dashboards): use axum 0.8 brace path-capture syntax (PMS-453)
8959ddffeat(dashboards): per-user saved dashboards CRUD (PMS-453 phase 1)
6691ce8feat(assets): CMDB expansion - assigned user, IP, hostname, MAC, installed date, department, in-transit ticket (PMS-454)
bcaa2a8Merge pull request 'feat(audit): tenant-scoped CSV export endpoint (PMS-455)' (#333) from feat/PMS-455-audit-log-csv-export into main
987b273Merge pull request 'feat(search): cross-entity tenant-scoped /api/v1/search endpoint (MAPPS-298)' (#332) from feat/MAPPS-298-global-search-endpoint into main
a6f764efeat(audit): tenant-scoped CSV export endpoint (PMS-455)
7c04a3bfeat(search): cross-entity tenant-scoped /api/v1/search endpoint (MAPPS-298)
0aa200bMerge pull request 'fix(auth): preserve invite role over the Bunyip subscriber floor' (#324) from fix/PMS-458-preserve-invite-role-over-subscriber-floor into main
0843268Merge origin/main into fix/PMS-458-preserve-invite-role-over-subscriber-floor
b6ce330Merge pull request 'test(contacts): isolate duplicate-name assertion from demo seed' (#331) from fix/PMS-464-company-dup-test-demo-seed into main
22ad97fMerge branch 'main' into fix/PMS-464-company-dup-test-demo-seed
ea44c80Merge pull request 'ci(e2e): run npm/npx via corepack, not the absent npm24' (#330) from fix/PMS-462-e2e-corepack-npm into main
5afc32btest(contacts): isolate duplicate-name assertion from demo seed
8258de5ci(e2e): run npm/npx via corepack, not the absent npm24
7f258aaMerge branch 'main' into fix/PMS-429-e2e-versioned-node-binaries
ff4c49aMerge pull request 'chore: Claude fix is now Claude Run' (#329) from chore/remove-claude-fix into main
8710667chore: Claude fix is now Claude Run
04c86a9Merge pull request 'chore: Sync the checks and justfile recipes' (#328) from chore/sync-checks-justfile into main
0f2909fMerge branch 'main' into chore/sync-checks-justfile
ecf3745chore: Sync the checks and justfile recipes
3718d2fMerge pull request 'feat(jit): consume bunyip given_name/family_name claims (BUNYIP-141)' (#327) from feat/bunyip-141-jit-consume-name-claims into main
4ebd699Merge pull request 'fix(ci): create-release workflow concludes success on non-release merges' (#326) from fix/ci-create-release-skip-conclusion into main
4d03d85fix(ci): create-release workflow concludes success on non-release merges
a31a5b7Merge pull request 'fix(auth): gate PMS-447 subscriber-Admin floor on invite absence' (#325) from fix/PMS-447-preserve-invite-role into main
1e0efe3fix(auth): gate PMS-447 subscriber-Admin floor on invite absence
83bf97efix(auth): preserve invite role over the Bunyip subscriber floor
ecaf31eMerge pull request 'feat(auth): single-tenancy admin floor on Bunyip RS path (PMS-447)' (#323) from feat/PMS-447-single-tenancy-admin-default into main
8802de2feat(auth): single-tenancy admin floor on Bunyip RS path (PMS-447)
7a21cc2Merge branch 'main' into fix/PMS-429-e2e-versioned-node-binaries
c58b00dMerge pull request 'test(e2e): quarantine OIDC token-flow spec blocked on bunyip BUNYIP-146' (#319) from fix/PMS-435-quarantine-oidc-token-flow-bunyip-146 into main
c684ed6Merge remote-tracking branch 'origin/main' into fix/PMS-435-quarantine-oidc-token-flow-bunyip-146
1f57c76Merge pull request 'test(e2e): surface authorize redirect target in OIDC token-flow (PMS-443)' (#322) from chore/pms-e2e-oidc-surface-redirect-target into main
81c162btest(e2e): surface authorize redirect target in OIDC token-flow
e3bf9b6Merge pull request 'fix(rls): make tenant-isolation GUC count symmetric with owner count' (#320) from fix/PMS-437-rls-isolation-internal-count-symmetry into main
6103ab7fix(rls): make tenant-isolation GUC count symmetric with owner count
1a2b2ddtest(e2e): quarantine OIDC token-flow spec blocked on bunyip BUNYIP-146
87e6fb8Merge pull request 'chore(e2e): log OP-session cookie name to diagnose OIDC authorize bounce (PMS-434)' (#318) from chore/pms-e2e-oidc-cookie-name-diagnostic into main
0962f69chore(e2e): log OP-session cookie name to diagnose OIDC authorize bounce
ec767bcci(e2e): invoke versioned node24/npm24/npx24 binaries
6b2b286ci(e2e): use runner's preinstalled nodejs24 instead of setup-node
74602d6Merge pull request 'test(rls): make tenant-isolation count robust to own-company seed' (#310) from fix/PMS-414-rls-isolation-test-own-company-seed into main
9625d65Merge branch 'main' into fix/PMS-414-rls-isolation-test-own-company-seed
dafee52Merge pull request 'feat(ci): cap native check.yml parallelism at nproc/2' (#313) from feat/GOV-10-native-check-nproc-cap into main
3f7e38dfeat(ci): cap native check.yml + integration.yml parallelism at nproc/2
3616ce4feat(jit): consume bunyip given_name/family_name claims (BUNYIP-141)
4271f34Merge pull request 'fix(migrations): exempt internal own-company from duplicate-name unique index (staging hotfix, PMS-413)' (#311) from fix/PMS-413-own-company-name-unique-collision into main
31132b3fix(migrations): exempt internal own-company from the duplicate-name unique index (PMS-413)
f84b10cMerge branch 'main' into fix/PMS-414-rls-isolation-test-own-company-seed
d7f575aMerge pull request 'feat(tenants): tenant own-company for general time logging (PMS-413)' (#309) from feat/PMS-413-tenant-own-company into main
45ecbb7style: match CI rustfmt for the PMS-413 emptiness-check edits (PMS-413)
edbd8cdfix(seed): exclude internal own-company from tenant emptiness checks (PMS-413)
1cce469test(rls): make tenant-isolation count robust to own-company seed
b3e1632fix(reports): exclude internal own-company from clients report; match CI rustfmt (PMS-413)
cf0a808feat(tenants): add tenant own-company for general time logging
42744d5Merge pull request 'Seed pre-commit .env from committed .env.example' (#302) from fix/pre-commit-clean-clone into main
ff6111bMerge branch 'main' into fix/pre-commit-clean-clone
73692c6Merge pull request 'feat(contracts): add weekly and bi-weekly billing cycles (PMS-404)' (#308) from feat/PMS-404-weekly-biweekly-billing-cycles into main
4a1826fMerge pull request 'fix(time-tracking): consume contract hours on timesheet approval (PMS-405)' (#307) from fix/PMS-405-wire-time-to-contract-balance into main
775efeaMerge pull request 'feat(projects): reject task/phase create on cancelled project (PMS-399)' (#305) from fix/PMS-399-reject-children-on-cancelled-project into main
af44724style: match CI rustfmt in PMS-404 contracts tests (PMS-404)
ea42a18style: match CI rustfmt in contracts tests (PMS-405)
224c2b7style: collapse short query to one line for CI rustfmt (PMS-399)
bc71b9cfeat(projects): reject task/phase create on cancelled project (PMS-399)
7f0cb05feat(contracts): add weekly and bi_weekly billing cycles
ff194eeMerge pull request 'feat(contacts): freeform company on contacts (nullable company_id + company_name) (PMS-402)' (#306) from feat/PMS-402-freeform-company-on-contacts into main
9926b2efix(time): consume contract hours on timesheet approval
4c29f2efeat(contacts): accept freeform company on contacts
7d74781Merge pull request 'fix(projects): reject inverted task start/due dates (PMS-398)' (#304) from fix/PMS-398-task-date-ordering into main
7828b27fix(projects): reject inverted task start/due dates (PMS-398)
712cb34Merge pull request 'feat(time-tracking): enforce per-tenant max-hours-per-day cap' (#298) from feat/PMS-396-max-hours-per-day-cap into main
9993537fix(test): set work_category on day-cap test helpers after rebase
e0ecc09Merge pull request 'test(tickets): pin server-side inline status/priority/assignee edit + SLA recalc' (#272) from test/pms-359-ticket-inline-edits into main
2503606test(tickets): pin server-side inline status/priority/assignee edit + SLA recalc
cc2b1deMerge pull request 'feat(projects): per-project standard due date override (PMS-345)' (#268) from feat/PMS-345-per-project-default-due into main
15abfafMerge pull request 'feat(calendar): add scheduling-template model and CRUD endpoints (PMS-403)' (#299) from feat/PMS-403-scheduling-templates into main
4653c86Merge pull request 'feat(tickets): wire team_id filter and team-scoped dashboard query' (#295) from feat/PMS-406-ticket-team-scope-filter into main
4c0296bMerge pull request 'feat(contacts): reject duplicate company names per tenant' (#296) from feat/PMS-400-reject-duplicate-company-names into main
69e707aMerge pull request 'test(modules): verify company-scoped list endpoint filtering' (#300) from test/PMS-401-company-scoped-list-filtering into main
0315de4fix(seed): set default_due_business_days on QA project specs after rebase
e0636e2chore(migrations): renumber project_default_due_business_days 051->059 after PMS-411 collision fix
e8d995cfeat(projects): per-project standard due date override (PMS-345)
43cf626feat(time-tracking): enforce per-tenant max-hours-per-day cap
90e3717chore(migrations): renumber tickets_tenant_team_idx to 058 after PMS-411 collision fix
11fafc0chore(migrations): renumber companies_tenant_name_unique to 057 after PMS-411 collision fix
73ef7b0feat(tickets): wire team_id filter and team-scoped dashboard query
4e5ebbdfeat(contacts): reject duplicate company names per tenant
335773echore(migrations): renumber scheduling_templates 054->056 after PMS-411 collision fix
c8114e3feat(calendar): add scheduling-template model and CRUD endpoints (PMS-403)
aa720ffMerge pull request 'fix(migrations): renumber duplicate 054 prefix to 055 (PMS-411)' (#303) from fix/PMS-migration-054-prefix-collision into main
57aefe6fix(migrations): renumber duplicate 054 prefix to 055 (PMS-411)
3af2a24fix(hooks): seed .env from committed .env.example on clean clone
dfa58e9Merge pull request 'style(time-tracking): rustfmt the work_category unit tests' (#297) from feat/PMS-394-time-entry-general-category into main
07abad8Merge pull request 'feat(auth): persist per-user theme preference (base mode + accent) (PMS-410)' (#301) from fix/PMS-410-theme-prefs into main
c355277feat(auth): persist per-user theme preference (base mode + accent) (PMS-410)
9d6b083test(modules): verify company-scoped list endpoint filtering
1e82dedstyle(time-tracking): rustfmt the work_category unit tests
9c87f15feat(time-tracking): add general-bucket work_category to time entries
a5b45baMerge pull request 'fix(validation): range/scale-guard money and hours numeric fields (PMS-383)' (#294) from fix/PMS-383-numeric-money-hours-validation into main
80a0333Merge branch 'main' into fix/PMS-383-numeric-money-hours-validation
d372b9bMerge pull request 'feat(notifications): add PUT update endpoints for channels/templates/rules' (#293) from feat/PMS-386-notification-config-update-endpoints into main
f5756b2Merge branch 'main' into feat/PMS-386-notification-config-update-endpoints
91a42cdMerge pull request 'feat(rmm): add PUT update routes for device-mappings and alert-rules' (#292) from feat/PMS-387-rmm-device-mapping-alert-rule-update into main
42acff8Merge branch 'main' into feat/PMS-387-rmm-device-mapping-alert-rule-update
d08de8fMerge pull request 'fix(reports): bucket dashboard ticket trend in the user's timezone' (#274) from fix/pms-360-user-timezone-date-bucketing into main
c3814e3Merge branch 'main' into fix/pms-360-user-timezone-date-bucketing
6eef45efix(validation): range/scale-guard money and hours numeric fields (PMS-383)
cad860afeat(notifications): add PUT update endpoints for channels/templates/rules
ada540cfeat(rmm): add PUT update routes for device-mappings and alert-rules
9d61aa5Merge pull request 'fix(validation): validate tenant admin_email as an email (PMS-385)' (#290) from fix/PMS-385-tenant-admin-email-validation into main
c86c58dMerge branch 'main' into fix/PMS-385-tenant-admin-email-validation
fc42816Merge pull request 'fix(validation): reject non-positive time-entry duration_minutes (PMS-384)' (#291) from fix/PMS-384-time-entry-duration-validation into main
f7366bfMerge branch 'main' into fix/PMS-384-time-entry-duration-validation
a432921Merge pull request 'fix(cors): cache preflight with Access-Control-Max-Age=600 (PMS-389)' (#289) from fix/PMS-389-cors-max-age into main
87598dafix(validation): reject non-positive time-entry duration_minutes
5917e76fix(validation): validate tenant admin_email as an email
f200bd3fix(cors): cache preflight with Access-Control-Max-Age=600
50ea5ccMerge pull request 'fix(seed): repair qa seed so main compiles (actual_end_date + AuditCtx) (PMS-379)' (#288) from fix/qa-seed-build-actual-end-date-audit-ctx into main
2bc8995fix(migrations): renumber duplicate 051 prefixes to 052/053
5869e1ffix(seed): repair qa seed for actual_end_date + AuditCtx create signatures
0b3dd22Merge main into fix/pms-360-user-timezone-date-bucketing
d6d16dfMerge pull request 'test(projects): pin oversized-budget 422 and company-id injection safety' (#283) from fix/pms-316-project-budget-oversize-and-safe-company-tests into main
0a4a1b0Merge pull request 'fix(validation): recurse nested ValidationErrors so 422 errors[] carry dotted field paths' (#280) from fix/pms-330-nested-validation-field-paths into main
13ddfabMerge pull request 'test(contacts): pin company search to substring ILIKE, not leading prefix' (#279) from fix/pms-372-company-search-substring into main
a9b0c7eMerge pull request 'fix(contacts): populate company_name via LEFT JOIN to companies' (#266) from fix/pms-334-contact-company-name into main
5799c34Merge pull request 'fix(billing): widen tax_rates.rate and validate the percentage range' (#281) from fix/pms-339-tax-rate-column-width-and-validation into main
20307fbMerge pull request 'feat(projects): accept actual_end_date on create for edit-form parity' (#278) from feat/pms-361-create-project-symmetry into main
ae60fa7Merge pull request 'feat(projects): surface owning company name in ProjectResponse' (#276) from feat/pms-335-project-company-name into main
7a3f773Merge pull request 'fix(assets): surface company_name on AssetResponse via LEFT JOIN' (#275) from fix/pms-336-asset-company-name into main
dfa96c8Merge pull request 'fix(billing): reject non-positive payment amounts with a 422' (#269) from fix/PMS-373-reject-non-positive-payment-amount into main
62433cbMerge pull request 'fix(tickets): humanise FK column names in change-history field labels' (#267) from fix/pms-370-humanize-history-field-labels into main
8c74d8bMerge pull request 'feat(seed): on-demand QA walkthrough dataset for a QA-marked tenant' (#265) from feat/PMS-331-qa-seed-dataset into main
d24677eMerge pull request 'fix(billing): make payment-gateway credential a write-only secret' (#263) from fix/pms-342-payment-gateway-write-only-secret into main
6730ed2Merge pull request 'feat(knowledge_base): wire client_specific company scoping write path' (#260) from feat/pms-341-kb-company-ids into main
077fce3Merge pull request 'test(tickets): pin priority round-trip on ticket create (PMS-358)' (#270) from feat/pms-358-priority-roundtrip-integration-test into main
45c0c07Merge pull request 'fix(validation): symmetric URL error message + close credential URL gap (PMS-351)' (#273) from fix/pms-351-url-field-validation-sweep into main
3504d3cMerge pull request 'fix(rbac): gate Contracts/Rate Cards reads and financial reports like Invoices' (#271) from fix/PMS-350-rbac-finance-gates into main
d12dbbafix(rbac): gate Client Profitability report + its CSV export like Invoices
3b7c2bdMerge pull request 'feat(audit): emit Create audit row on mileage entry creation' (#284) from feat/pms-315-mileage-create-audit into main
5f0f3e1feat(audit): emit Create audit row on mileage entry creation
b8ea044Merge pull request 'fix(projects): emit Create audit row on task creation' (#282) from fix/pms-318-create-task-audit-row into main
2a173e4feat(audit): emit Create audit rows for every remaining create path
1bb9439Merge pull request 'feat(mileage): mileage entries, per-mile rate card rate, invoice line type' (#277) from feat/pms-315-mileage-entries into main
0cd6088fix(mileage,time): validate re-associated ticket_id on update against tenant
3fd861eMerge pull request 'fix(calendar): validate recurrence_rule as RFC 5545 on appointment create' (#264) from fix/pms-374-validate-recurrence-rule into main
4ad95d0Merge pull request 'fix(reports): zero-fill canonical project and asset status buckets' (#261) from fix/pms-366-project-status-counters-zero-fill into main
7b2370dtest(projects): pin oversized-budget 422 and company-id injection safety
649c820fix(projects): emit Create audit row on task creation
e70560cfix(billing): widen tax_rates.rate and validate the percentage range
29c12e3fix(validation): recurse nested ValidationErrors so 422 errors[] carry dotted field paths
6a16cf2test(contacts): pin company search to substring ILIKE, not leading prefix
5ac383afeat(projects): accept actual_end_date on create for edit-form parity
ee415e8feat(mileage): mileage entries, per-mile rate card rate, invoice line type
43102d3feat(projects): surface owning company name in ProjectResponse
a3c9bb3fix(assets): surface company_name on AssetResponse via LEFT JOIN
e56be90fix(reports): bucket dashboard ticket trend in the user's timezone
8689abbfix(validation): symmetric URL error message + close credential URL gap (PMS-351)
a12a3b8Merge pull request 'fix(validation): re-key cross-field rules onto a named field so forms show inline messages' (#262) from fix/pms-364-cross-field-validation-field-key into main
73cc9affix(rbac): gate Contracts/Rate Cards reads and financial reports like Invoices
075555dtest(tickets): pin priority round-trip on ticket create (PMS-358)
ca16ea9fix(billing): reject non-positive payment amounts with a 422
a7565fefix(tickets): humanise FK column names in change-history field labels
27ddca3fix(contacts): populate company_name via LEFT JOIN to companies
553a995feat(seed): on-demand QA walkthrough dataset for a QA-marked tenant
7e04bbcfix(calendar): validate recurrence_rule as RFC 5545 on appointment create
8d31b36fix(billing): make payment-gateway credential a write-only secret
064c8dffix(validation): re-key cross-field rules onto a named field so forms show inline messages
13b7252fix(reports): zero-fill canonical project and asset status buckets
82a6912feat(knowledge_base): wire client_specific company scoping write path
1cb2ab1Merge pull request 'fix(tickets,assets): asset_id update + AssetFilter.q so PMS-344 inline editor and picker work end to end' (#259) from fix/pms-344-asset-filter-and-update-clearing-semantics into main
fb4e7dcfix(tickets,assets): asset_id update + AssetFilter.q so PMS-344 inline editor and picker work end to end
1e8b387Merge pull request 'feat(tickets): TicketResponse carries asset_id + asset_name; TicketFilter accepts asset_id (PMS-344)' (#258) from feat/pms-344-server-asset-id-filter-and-name into main
3a35f97feat(tickets): TicketResponse carries asset_id + asset_name; TicketFilter accepts asset_id (PMS-344)
c9f84e0Merge pull request 'feat(scheduling): tenant-wide standard due date for tasks and no-SLA tickets' (#257) from feat/PMS-345-standard-due-date into main
12f9bb7feat(scheduling): tenant-wide standard due date for tasks and no-SLA tickets
c3fa665Merge pull request 'fix(audit): skip change-history entry for description checkbox toggles (PMS-349)' (#256) from fix/PMS-349-skip-audit-for-checkbox-toggles into main
d793cbafix(audit): don't record a change-history entry for description checkbox toggles (PMS-349)
0b6287dMerge pull request 'fix(sla): validate SLA target hours (non-negative, <=2dp, first_response<=resolution) (PMS-338)' (#255) from fix/PMS-338-sla-target-validation into main
87494f2Merge remote-tracking branch 'origin/main' into fix/PMS-338-sla-target-validation
2957572Merge pull request 'fix(contracts): validate billing_cycle and status at the request layer (422 not 500) (PMS-337)' (#254) from fix/PMS-337-contract-status-billing-validation into main
1cf5505fix(sla): validate SLA target hours (non-negative, <=2dp, first_response<=resolution)
6d378c9fix(contracts): validate billing_cycle and status at the request layer (422 not 500)
c1ed191Merge pull request 'fix(calendar): reject inverted appointment time range on update (PMS-343)' (#253) from fix/PMS-343-appointment-time-range into main
d3be695fix(calendar): reject inverted appointment time range on update (PMS-343)
9f1f092Merge pull request 'feat(billing): payment_terms lookup table + CRUD, invoices reference it by FK' (#252) from feat/PMS-333-payment-terms-lookup into main
8e9d65bfeat(billing): payment_terms lookup table + CRUD, invoices reference it by FK
6de032aMerge pull request 'fix(dev): pre-create pg extensions + grant CREATE-on-db for fresh split-role volume' (#251) from fix/dev-pg-preinstall-extensions into main
32d1b38fix(dev): pre-create pg extensions + grant CREATE-on-db for fresh split-role volume
e866ed1Merge pull request 'feat(time): join work-item names (ticket/project/task) into the time-entry response' (#250) from feat/PMS-332-time-entry-work-item-names into main
1e22e9cfeat(time): join work-item names into the time-entry response
6982cadMerge pull request 'feat(projects): expose per-task logged_hours (non-rejected) alongside approved actual_hours' (#249) from feat/PMS-329-task-logged-hours into main
ecd62b4feat(projects): expose per-task logged_hours alongside approved actual_hours
b9769f2Merge pull request 'fix(time): PUT /time-entries preserves task_id (and expose it in the response)' (#248) from fix/PMS-328-time-entry-preserve-task-id into main
319b96efix(time): restrict time-entry edit/delete to owner or admin
106c298fix(time): preserve task_id on time-entry update and expose it
828afbfMerge pull request 'docs(qa): extend QA test-plan prompt with this round's validation findings [PMS-326]' (#246) from docs/PMS-326-qa-test-plan into main
e2c60acMerge pull request 'feat(contacts): validate phone/timezone/country/postal (fix contact phone 500) [PMS-325]' (#247) from fix/PMS-325-contact-field-validation into main
90cefedfeat(contacts): validate phone, timezone, country, and postal fields
b13bfbddocs(qa): fold validation findings into the QA test-plan prompt
768412dMerge pull request 'fix(projects): server-side validation for name + budget (fix Budget Hours 422) [PMS-324]' (#243) from fix/PMS-324-project-input-validation into main
457be7fMerge branch 'main' into fix/PMS-324-project-input-validation
0c46c90Merge pull request 'feat(contracts): add GET /rate-cards/{id} for single rate-card fetch' (#244) from feat/PMS-327-get-rate-card into main
2807521feat(contracts): add GET /rate-cards/{id} for single rate-card fetch
39de4e6Merge pull request 'harden(lookups): DB partial unique index for single-default per tenant' (#242) from feat/PMS-323-single-default-unique-index into main
0953a74fix(projects): validate name length and budget fields, accept numeric budgets
fd15023harden(lookups): DB partial unique index for single-default per tenant
1e649e9Merge pull request 'test(projects): pin duplicate project-type name as a 409' (#241) from feat/PMS-322-project-type-lookup into main
9bdca67test(projects): pin duplicate project-type name as a 409
aa04df8Merge pull request 'feat(projects): tenant-scoped project_types lookup table + CRUD' (#240) from feat/PMS-322-project-type-lookup into main
77625cafeat(projects): tenant-scoped project_types lookup + CRUD
c4dabdcMerge pull request 'feat(tickets): management CRUD for ticket status/priority/type/queue/category lookups' (#239) from feat/PMS-321-ticket-lookup-crud into main
d6c7f17fix(tickets): enforce same-tenant category parent at the DB layer (migration 047)
e7ec4a1fix(tickets): reject transitive category cycles; cover priority sla_multiplier
06bbe5cfeat(tickets): management CRUD for status/priority/type/queue/category lookups
8a8253fMerge pull request 'fix(justfile): add ensure-env dependency to dev-clean' (#238) from fix/PMS-307-dev-clean-ensure-env into main
7438c7ffix(justfile): add ensure-env dependency to dev-cleanDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)
-
v0.3.0
StableAll checks were successfulBuild OCI container / Build and push mokosh-api image (push) Successful in 4m21sreleased this
2026-06-14 19:00:55 +02:00 | 676 commits to main since this releaseChangelog
e070df6Merge pull request 'Release v0.3.0' (#237) from release/v0.3.0 into main
0ed8a38Release v0.3.0
008e467Merge pull request 'fix(validation): reject inverted date ranges and oversized payment amounts' (#236) from fix/PMS-306-validation-date-range-money-overflow into main
8b5b99ffix(validation): reject inverted date ranges and oversized payment amounts
5d9b8b7Merge pull request 'fix(migrations): renumber duplicate 033 profile_completed_at migration to 046' (#235) from chore/checks-workflow-048ddb98 into main
c2cf8c2fix(migrations): renumber duplicate 033 profile_completed_at migration to 046
048ddb9Merge pull request 'feat(auth): force new Bunyip-JIT users through name onboarding' (#151) from feat/force-profile-setup-on-jit into main
5faff29Merge branch 'main' into feat/force-profile-setup-on-jit
56be716Merge pull request 'feat(audit-log): resolve user + entity names server-side so the SPA can display them' (#152) from feat/audit-log-resolve-names into main
b4c7f6eMerge branch 'main' into feat/audit-log-resolve-names
a603d3eMerge pull request 'docs(qa): add reusable AI-driven QA test plan' (#234) from docs/qa-test-plan into main
86e899cMerge branch 'main' into docs/qa-test-plan
6bfb215Merge pull request 'fix(contracts): reject out-of-set contract_type with 422 instead of 500' (#233) from fix/pms-299-contract-type-validation into main
187eb94Merge branch 'main' into fix/pms-299-contract-type-validation
a2f3bf7Merge pull request 'fix(contacts): validate company create/update input to 422 not 500' (#232) from fix/pms-297-company-create-validation into main
19a5750Merge branch 'main' into fix/pms-297-company-create-validation
d8264a5docs(qa): add reusable AI-driven QA test plan
a7e5badMerge pull request 'fix(error): unify 4xx envelope and populate validation messages' (#231) from fix/pms-298-error-envelope into main
8b0625dfix(contracts): reject out-of-set contract_type with 422 instead of 500
fe9cf7afix(contacts): validate company create/update input to 422 not 500
8694729fix(error): unify 4xx envelope and populate validation messages
6dac348Merge pull request 'feat(ci): split check into fast and Postgres-backed integration gates' (#230) from feat/pms-267-split-fast-integration-ci into main
3d75880Merge branch 'main' into feat/pms-267-split-fast-integration-ci
615adadfeat(ci): split check into fast and Postgres-backed integration gates
009ef0cMerge pull request 'docs(auth): clarify SSO startup log + record PMS-291 posture decision' (#229) from fix/pms-291-sso-log-and-docs into main
6f4aaf6docs(auth): clarify SSO startup log + record PMS-291 posture decision
da5b705Merge pull request 'Release v0.2.0' (#228) from release/v0.2.0 into main
cbc6b03Release v0.2.0
00084a0Merge pull request 'fix(assets): wire configured AES key and harden vault crypto integrity' (#226) from fix/pms-188-assets-zero-key-crypto-integrity into main
93df0f9Merge origin/main into fix/pms-188-assets-zero-key-crypto-integrity
92a4975Merge origin/main into fix/pms-188-assets-zero-key-crypto-integrity
3a4327aMerge pull request 'feat(rls): activate RLS at runtime via split migrator/app DB roles' (#224) from feat/pms-285-rls-runtime-role-split into main
714658eMerge origin/main into feat/pms-285-rls-runtime-role-split
55000e0Merge pull request 'chore(cleanup): remove dead crates code and stray config/seed/test cruft' (#220) from chore/pms-202-remove-dead-code into main
1f4884eMerge origin/main into chore/pms-202-remove-dead-code
e1e04e2Merge pull request 'chore(cleanup): remove dead and stray code from src/ tree' (#218) from chore/pms-201-remove-dead-stray-code into main
5755852Merge origin/main into chore/pms-201-remove-dead-stray-code
69bdf0aMerge pull request 'fix: correct rmm, notifications, SLA, KB, portal, and contacts defects' (#217) from fix/pms-195-module-correctness-defects into main
0c7f45dMerge origin/main into fix/pms-195-module-correctness-defects
02c6300Merge pull request 'test(settings): hit canonical /api/v1/invoices in module-gate tests' (#215) from chore/checks-workflow-986a08ef into main
258450cMerge origin/main into chore/checks-workflow-986a08ef
2e34edeMerge pull request 'fix(contracts,billing): close financial-integrity gaps' (#213) from fix/pms-194-contracts-billing-financial-integrity into main
6d07954Merge origin/main into fix/pms-194-contracts-billing-financial-integrity
bad33e0Merge pull request 'refactor: consolidate duplicated helpers, types, and test fixtures' (#212) from feat/pms-199-consolidate-duplicated-helpers into main
c00cae2Merge origin/main into feat/pms-199-consolidate-duplicated-helpers
eac8dbbMerge pull request 'fix(db): converge ticket filter builder; audit count_query placeholder family' (#211) from feat/pms-197-audit-count-query-placeholder-family into main
4a7c72eMerge origin/main into feat/pms-197-audit-count-query-placeholder-family
06bddefMerge pull request 'fix(schema): harden migrations, FKs, seed, and truncation (PMS-196)' (#210) from feat/pms-196-harden-migrations-rls-integrity into main
ad47e38Merge origin/main into feat/pms-196-harden-migrations-rls-integrity
85fd769Merge pull request 'fix(tickets): scope writes to tenant and validate FK references' (#209) from fix/pms-193-scope-tickets-writes-validate-fk into main
3154fbaci: re-trigger Check (transient failure; green locally)
bde8f81Merge origin/main into fix/pms-193-scope-tickets-writes-validate-fk
27fa80bMerge pull request 'fix(misc): correctness, concurrency, and test-reliability defects' (#208) from fix/pms-200-misc-correctness-concurrency-test-reliability into main
7caf796Merge origin/main into fix/pms-200-misc-correctness-concurrency-test-reliability
a49cfbeMerge pull request 'fix(db,auth): dedupe migration prefix 041 and fix main compile' (#227) from fix/pms-293-dedupe-migration-prefix-041 into main
2c9c7c3fix(auth): return user: None in login_with_google mfa_required branch
820cc4dfix(db): renumber portal_setup_tokens migration 041 to 042
893f5d8fix(auth): omit user profile in Google-callback mfa_required branch
5b96470Merge origin/main into fix/pms-200-misc-correctness-concurrency-test-reliability
5946001Merge pull request 'feat(portal): mint setup-link token + email on portal-access grant' (#204) from feat/pms-136-portal-setup-link into main
c1b9663Merge origin/main into feat/pms-136-portal-setup-link
66367d5Merge pull request 'fix(auth): close invite, signup, password, and validation defects' (#203) from fix/pms-192-invite-signup-password-validation into main
52b32c5Merge origin/main into fix/pms-192-invite-signup-password-validation
8829844Merge pull request 'fix(auth): close SSO/OIDC auth-strength and conformance gaps' (#202) from feat/pms-191-sso-oidc-security-gaps into main
fbacbdeMerge origin/main into feat/pms-191-sso-oidc-security-gaps
3337ef3Merge pull request 'fix(auth): close legacy PSA auth path security gaps' (#201) from fix/pms-190-legacy-auth-security-gaps into main
7dd8b6aMerge origin/main into fix/pms-190-legacy-auth-security-gaps
7e5fa28fix(assets): allow 'deleted' in audit-log CHECK; add delete regression test
269bf16Merge pull request 'test(settings): fix stale billing route path in module-gating tests' (#225) from fix/pms-290-settings-stale-billing-path into main
4c89552fix(assets): wire configured AES key and harden vault crypto integrity
a8589c0test(settings): fix stale billing route path in module-gating tests
f67057cfeat(rls): activate RLS at runtime via split migrator/app DB roles
8d564e0Merge branch 'main' into chore/pms-201-remove-dead-stray-code
6dfb9eeMerge pull request 'fix(startup): fail loud when configured SSO bootstrap fails' (#223) from fix/pms-289-sso-fail-loud-when-configured into main
d79ab98fix(startup): fail loud when configured SSO bootstrap fails
86e40abMerge pull request 'fix(tenants): seed lookup config for tenants reached off the PSA path' (#222) from feat/pms-288-seed-lookup-config-on-placement into main
e0daef1perf(tenants): cheap-guard the per-request sequence seed
74adb16fix(tenants): seed lookup config for tenants reached off the PSA path
f75618fMerge pull request 'fix(tenants): set NOT-NULL kind in create_tenant; add regression test' (#221) from fix/pms-287-create-tenant-kind into main
f7f8b7dfix(tenants): set NOT-NULL kind in create_tenant; add regression test
8e2faadMerge pull request 'fix(startup): make migration failure fatal instead of warn-and-continue' (#219) from fix/pms-286-fatal-migrations into main
b5ad162Merge pull request 'feat(justfile): add dev-clean / dev-clean-all teardown recipes' (#214) from feat/dev-clean-recipes into main
f82d9b3Merge branch 'main' into feat/dev-clean-recipes
398c0bachore(cleanup): remove dead crates code and stray config/seed/test cruft
a3333dffix(startup): make migration failure fatal instead of warn-and-continue
842b18fchore(cleanup): remove dead and stray code from src/ tree
303efb5Merge pull request 'test(isolation): automate PMS-236 tenant-isolation QA across the API' (#216) from feat/pms-236-tenant-isolation-integration-test into main
a3224a8test(isolation): harden module-config and ticket_number checks
f5520f7fix: correct rmm, notifications, SLA, KB, portal, and contacts defects
2c69eb9test(isolation): automate PMS-236 tenant-isolation QA across the API
6678777test(settings): hit canonical /api/v1/invoices in module-gate tests
5086c63feat(justfile): add dev-clean / dev-clean-all teardown recipes
9579f2bfix(contracts,billing): close financial-integrity gaps
5f7c728refactor: consolidate duplicated helpers, types, and test fixtures
d68af1bfix(db): converge ticket filter builder; audit count_query placeholder family
eaa150ffix(schema): harden migrations, FKs, seed, and truncation (PMS-196)
0433815fix(tickets): scope writes to tenant and validate FK references
f69cc50Merge pull request 'fix(rls): cover tenant-less tables; tenant-scope user_oauth_identities' (#207) from feat/pms-258-rls-cover-tenantless-tables into main
eca763eMerge branch 'main' into feat/pms-258-rls-cover-tenantless-tables
92bf278fix(misc): correctness, concurrency, and test-reliability defects
c224ffbfix(rls): cover tenant-less tables; tenant-scope user_oauth_identities
3b508c1Merge pull request 'refactor: converge duplicated subsystems and document architecture seams' (#206) from feat/pms-198-converge-subsystems into main
f8029ebMerge branch 'main' into feat/pms-198-converge-subsystems
a9ccf05Merge pull request 'fix(audit): remove coarse per-request middleware that wrote unusable rows' (#198) from fix/pms-275-remove-coarse-audit-middleware into main
c54ebe3Merge branch 'main' into fix/pms-275-remove-coarse-audit-middleware
1b55130Merge pull request 'fix(ci): gate prod image push to main/tags; close CI coverage gaps' (#199) from fix/pms-189-ci-release-pipeline-drift into main
9c0a400Merge branch 'main' into fix/pms-189-ci-release-pipeline-drift
0316824refactor: converge duplicated subsystems and document architecture seams
e7521d3Merge pull request 'feat/pms-271-e2e-staging-prod-secrets' (#205) from feat/pms-271-e2e-staging-prod-secrets into main
5807db8fix(e2e): correct OIDC redirect_uri default to /auth/callback
fb735aarefactor(e2e): name CI secrets after deployment variables
0d33d0cfeat(portal): mint setup-link token + email on portal-access grant
2eb8977fix(auth): close invite, signup, password, and validation defects
222c649Revert "fix(e2e): keep bare E2E_* as staging, add only E2E_PRODUCTION_"
a4fef72fix(auth): close SSO/OIDC auth-strength and conformance gaps
d8e8eb0fix(e2e): keep bare E2E_ as staging, add only E2E_PRODUCTION_*
ffb58e1fix(auth): close legacy PSA auth path security gaps
3221b6bMerge pull request 'feat(e2e): split CI env vars into staging/production secrets; manual prod opt-in' (#200) from feat/pms-271-e2e-staging-prod-secrets into main
7788f76feat(e2e): split CI env vars into staging/production secrets
986a08efix(ci): gate prod image push to main/tags; close CI coverage gaps
6892bc4fix(audit): remove coarse per-request middleware that wrote unusable rows
730553aMerge pull request 'feat(migrations): no-op backfill + verification for co-mingled default-tenant rows' (#197) from feat/pms-263-comingled-backfill-verification into main
2e65ee8Merge branch 'main' into feat/pms-263-comingled-backfill-verification
2e62ad8Merge pull request 'test(isolation): per-user cross-isolation suite across modules' (#196) from feat/pms-264-per-user-isolation-suite into main
8968aa0feat(migrations): no-op backfill + verification for co-mingled default-tenant rows
f71a7c6test(isolation): per-user cross-isolation suite across modules
a927e4eMerge pull request 'fix(workers): scope notification template lookup; audit from_trusted' (#195) from feat/pms-261-worker-from-trusted-audit into main
2a9f970fix(workers): scope notification template lookup; audit from_trusted
6f54b2bMerge pull request 'refactor(domain): inject domains via env vars, never hardcode or fall back' (#192) from feat/pms-235-mokosh-domain-rebrand into main
d155840Merge branch 'main' into feat/pms-235-mokosh-domain-rebrand
6cd85carefactor(domain): inject all domains via env; drop hardcoded fallbacks
2ef2fbaMerge pull request 'fix(security): scope auth session methods to tenant; pin login-helper reachability' (#190) from feat/pms-260-cross-tenant-leak-fixes into main
3c987d4Merge branch 'main' into feat/pms-260-cross-tenant-leak-fixes
4028957Merge pull request 'feat(tenants): seed all editable lookups per tenant; reserve system-shared class' (#189) from feat/pms-259-seed-lookups-system-shared-class into main
57804d1fix(rls): renumber system-shared migration to 039; layer on PMS-257 fail-closed policy
408d9bdMerge remote-tracking branch 'origin/main' into feat/pms-259-seed-lookups-system-shared-class
100c59fMerge pull request 'feat(rls): flip tenant_isolation fail-closed with WITH CHECK and FORCE RLS' (#188) from feat/pms-257-rls-fail-closed into main
6175e84Merge branch 'main' into feat/pms-257-rls-fail-closed
d8d2696Merge pull request 'feat(tenant): remove the single-tenant cargo feature; no normal user lands in the default tenant' (#187) from feat/pms-262-remove-single-tenant-feature into main
28e059fMerge branch 'main' into feat/pms-262-remove-single-tenant-feature
50580b1Merge pull request 'feat(db): route tenant-scoped service queries through begin_with_tenant' (#186) from feat/pms-256-rls-guc-plumbing into main
c929e7cMerge branch 'main' into feat/pms-256-rls-guc-plumbing
5da88ebMerge pull request 'docs(rls): per-user isolation reference and decomposition for PMS-255' (#185) from docs/pms-255-rls-isolation-plan into main
18914baMerge branch 'main' into docs/pms-255-rls-isolation-plan
732427aMerge pull request 'chore: add pre-commit hook recipes' (#191) from chore/pre-commit-hooks into main
22b4f59Merge branch 'main' into chore/pre-commit-hooks
106f983Merge pull request 'fix(version): sanitise error bodies, warn on bad versions, test network path' (#194) from feat/pms-238-self-hosted-version-check into main
fcf44f5fix(version): sanitise error bodies, warn on bad versions, test network path
35445fdMerge pull request 'feat(version): add self-hosted update check endpoint' (#193) from feat/pms-238-self-hosted-version-check into main
551db74feat(version): cache update-check result with a TTL
e08a3adfeat(version): add self-hosted update check endpoint
ebaa8d2docs(domain): rebrand a8n.systems references to mokosh.systems (Bucket A)
2a34180chore: add install-hooks and pre-commit just recipes
cbcfad6fix(security): scope auth session methods to tenant; pin login-helper reachability
78c5992feat(tenants): seed all editable lookups per tenant; reserve system-shared class
3476ed6feat(rls): flip tenant_isolation fail-closed with WITH CHECK and FORCE RLS
6969297feat(tenant): remove the single-tenant cargo feature; no normal user lands in the default tenant
bb76afbfeat(db): route tenant-scoped service queries through begin_with_tenant
864a0d8docs(rls): per-user isolation reference and decomposition for PMS-255
2f89fc7Merge pull request 'feat(users): persist date_format_string preference on users (backend)' (#184) from feat/pms-253-date-format-preference-backend into main
c57d5c6feat(users): persist date_format_string preference on users (backend)
a8116f3Merge pull request 'chore(fmt): apply cargo fmt --all after PMS-244..PMS-249 sweep' (#183) from chore/pms-251-cargo-fmt-sweep into main
990d585chore(fmt): apply cargo fmt --all after PMS-244..PMS-249 sweep
23b3259Merge pull request 'test(auth): end-to-end placement tests for the bunyip login path (PMS-249)' (#182) from feat/mapps-249-bunyip-login-e2e into main
9291524test(auth): end-to-end placement tests for the bunyip login path (PMS-249)
339e61bMerge pull request 'feat(invitations): email the invitee on invite create (PMS-246)' (#181) from feat/mapps-246-invite-email into main
9d474edMerge remote-tracking branch 'origin/main' into feat/mapps-246-invite-email
85820e8Merge pull request 'feat(auth): backfill default-tenant users off the shared tenant on login (PMS-245)' (#180) from feat/mapps-245-backfill-default-tenant-users into main
9a752a6feat(invitations): email the invitee on invite create (PMS-246)
d8b05dffeat(auth): backfill default-tenant users off the shared tenant on login (PMS-245)
bf53e19Merge pull request 'test(auth): pin the bunyip userinfo email_verified contract (PMS-248)' (#179) from chore/mapps-248-userinfo-email-verified-contract into main
fd253a6test(auth): pin the bunyip userinfo email_verified contract (PMS-248)
f6c7d3fMerge pull request 'feat(invitations): tenant invite CRUD - Mokosh-owned org membership (PMS-244 phase 1)' (#178) from feat/mapps-244-invitations into main
bd8ffd7feat(auth): resolve SSO login to a tenant via Mokosh invites/self-signup (PMS-244, phase 2)
b54b06cfeat(invitations): tenant invite CRUD - Mokosh-owned org membership (PMS-244, phase 1)
fa7724fMerge pull request 'feat(auth): lazily re-home default-tenant users to their org tenant (PMS-243)' (#177) from feat/mapps-243-rehome into main
b78fa59feat(auth): lazily re-home default-tenant users to their org tenant (PMS-243)
59618acMerge pull request 'feat(auth): resolve SSO users to a per-org tenant via the Bunyip org claim (PMS-240)' (#175) from feat/mapps-240-bunyip-org-tenant into main
6b8ed51feat(auth): resolve SSO users to a per-org tenant via the Bunyip org claim (PMS-240)
bfb815fMerge pull request 'fix(seed): never auto-seed the shared Bunyip landing tenant (PMS-239)' (#174) from fix/mapps-239-demo-seed-shared-tenant into main
18c60effix(seed): never auto-seed the shared Bunyip landing tenant (PMS-239)
b2cf1b3Merge pull request 'chore: cargo fmt --all after the PMS-139 TenantId sweep' (#173) from chore/cargo-fmt-after-pms-139-sweep into main
c441b1cchore: cargo fmt --all after the PMS-139 TenantId sweep
c7badabMerge pull request 'feat(auth): migrate the tickets hub to TenantId, completing PMS-139 (sweep batch 8)' (#171) from feat/pms-139-sweep-tickets into main
17611c3feat(auth): migrate the tickets hub to TenantId, completing PMS-139 (sweep batch 8)
1ac0d22Merge pull request 'feat(auth): migrate the notifications hub to TenantId (PMS-139 sweep batch 7)' (#169) from feat/pms-139-sweep-notifications into main
d5c6133feat(auth): migrate the notifications hub to TenantId (PMS-139 sweep batch 7)
b4303f5Merge pull request 'feat(auth): migrate the audit hub to TenantId (PMS-139 sweep batch 6)' (#167) from feat/pms-139-sweep-hubs into main
f607764feat(auth): migrate the audit hub to TenantId (PMS-139 sweep batch 6)
23e36baMerge pull request 'feat(auth): migrate contacts + billing to TenantId (PMS-139 sweep batch 5)' (#164) from feat/pms-139-sweep-contacts-billing into main
3deb53efeat(auth): migrate contacts + billing to TenantId (PMS-139 sweep batch 5)
e2a6de3Merge pull request 'feat(auth): migrate knowledge_base + tenants + settings to TenantId (PMS-139 sweep batch 4)' (#163) from feat/pms-139-sweep-kb-tenants-settings into main
0a1006dfeat(auth): migrate knowledge_base + tenants + settings to TenantId (PMS-139 sweep batch 4)
85e08a2Merge pull request 'feat(auth): migrate calendar + sla + contracts to TenantId (PMS-139 sweep batch 3)' (#161) from feat/pms-139-sweep-calendar-sla-contracts into main
b77e671feat(auth): migrate calendar + sla + contracts to TenantId (PMS-139 sweep batch 3)
c6b6adbMerge pull request 'feat(auth): migrate assets + projects to TenantId (PMS-139 sweep batch 2)' (#160) from feat/pms-139-sweep-assets-projects into main
ee26720feat(auth): migrate assets + projects to TenantId (PMS-139 sweep batch 2)
622f3f4Merge pull request 'feat(auth): migrate rmm + time_tracking to TenantId (PMS-139 sweep batch 1)' (#159) from feat/pms-139-sweep-rmm-time into main
961251cfeat(auth): migrate rmm + time_tracking to TenantId (PMS-139 sweep batch 1)
1091d76Merge pull request 'feat(auth): typed TenantId scoping foundation + reports migration (PMS-139)' (#158) from feat/pms-139-tenant-id-foundation into main
2cc6511feat(auth): typed TenantId scoping foundation + reports migration (PMS-139)
a497e81Merge pull request 'feat(timesheets): draft state + withdraw endpoint (PMS-183)' (#157) from feat/pms-183-timesheet-withdraw into main
e75bdf9feat(timesheets): draft state + withdraw endpoint for timesheets (PMS-183)
45f51fcMerge pull request 'feat(audit): surface field-level before/after content in change history (PMS-204)' (#156) from feat/pms-204-history-content into main
60f0e4ffeat(audit): surface field-level before/after content in change history (PMS-204)
9acd44aMerge pull request 'feat(projects): record task and project edits in the audit trail (PMS-184)' (#155) from feat/pms-184-task-edit-history into main
6b20c9fMerge pull request 'feat(audit): per-record change-history endpoint (PMS-182)' (#154) from feat/pms-182-ticket-edit-history into main
f123889feat(projects): record task and project edits in the audit trail (PMS-184)
110f532feat(audit): per-record change-history endpoint for detail pages (PMS-182)
caacdc9Merge pull request 'docs: add 2026-06-06 platform audit to dev-docs/audits' (#153) from docs/add-platform-audit-2026-06-06 into main
455e9ccdocs: add 2026-06-06 platform audit to dev-docs/audits
579bee7feat(audit-log): resolve user + entity names server-side so the SPA can display them
b4a1571feat(auth): force new Bunyip-JIT users through name onboarding
9cd4103Merge pull request 'feat(billing): also surface invoice_number on payment responses (PMS-186)' (#150) from feat/pms-186-billing-company-name into main
11bcb0efeat(billing): also surface invoice_number on payment responses (PMS-186)
e450f5bMerge pull request 'feat(billing): include company_name on invoice and payment responses (PMS-186)' (#149) from feat/pms-186-billing-company-name into main
6bbe7fffeat(billing): include company_name on invoice and payment responses (PMS-186)
c32987cMerge pull request 'feat(reports): add safe custom report builder (PMS-180)' (#148) from feat/pms-180-custom-report-builder into main
cc0023bfeat(reports): add safe custom report builder (PMS-180)
4bc54e0Merge pull request 'feat(reports): add project + client report types end to end (PMS-179)' (#147) from feat/pms-179-project-client-reports into main
148d3f6feat(reports): add project + client report types end to end (PMS-179)
92e77eaMerge pull request 'feat(seed): seed demo data on a new account's first visit (PMS-157)' (#146) from feat/pms-157-new-account-seeding into main
b6f6ba1fix(seed): make demo ticket seeding best-effort; document E2E kill-switch
909dc07feat(seed): seed demo data on a new account's first visit (PMS-157)
aa6118fMerge pull request 'fix(contacts): 400 not 500 deleting a company with related records (PMS-170)' (#145) from fix/pms-170-company-delete-fk-400 into main
7e13835fix(contacts): return 400 not 500 when deleting a company with related records
a86e802Merge pull request 'fix(audit): correct SQL placeholder numbering in audit-log list (PMS-178)' (#144) from fix/pms-178-audit-list-placeholders into main
7acb419fix(audit): correct SQL placeholder numbering in audit-log list query
ce0dc98Merge pull request 'docs(e2e): spell out how to set the E2E account's admin role (SQL + bootstrap)' (#143) from docs/pms-155-e2e-admin-account into main
d436054Merge pull request 'feat(auth): translate Bunyip bunyip_role claim to mokosh role (PMS-172)' (#142) from feat/pms-172-bunyip-role-translation into main
e950947refactor(auth): clarify authz source + log Bunyip role transitions (PMS-172 review)
8378289feat(auth): translate Bunyip bunyip_role claim to mokosh role on the RS path
0e3285bMerge pull request 'docs(e2e): how to set the E2E account admin role (SQL + bootstrap)' (#141) from docs/pms-155-e2e-admin-howto into main
67c9cb8docs(e2e): spell out how to set the E2E account's admin role (SQL + bootstrap)
abd36b9docs(e2e): spell out how to set the E2E account's admin role (SQL + bootstrap)
3fcd925Merge pull request 'docs(e2e): require admin role for the E2E account (PMS-155)' (#140) from docs/pms-155-e2e-admin-account into main
e025056docs(e2e): require admin role for the E2E account (PMS-155)
f636e04Merge pull request 'test(e2e): add API CRUD specs for time-tracking, projects, billing, contracts (PMS-155)' (#136) from feat/pms-155-e2e-core-modules into main
8f878ddtest(e2e): add API specs for RMM and the dispatch board (PMS-155 batch 4)
007ba8btest(e2e): add API specs for notifications, settings, audit, reports (PMS-155 batch 3)
fcf367ftest(e2e): add API CRUD specs for calendar, SLA, assets, knowledge-base (PMS-155 batch 2)
9aaeac6test(e2e): make PMS-155 spec cleanup resilient to a single delete failure
802a291test(e2e): add API CRUD specs for time-tracking, projects, billing, contracts (PMS-155)
c1dab9cMerge pull request 'fix(e2e): tolerate 405 on ticket delete until staging deploys PMS-149 route' (#135) from fix/pms-149-e2e-deploy-tolerant-ticket-delete into main
289e772fix(e2e): tolerate 405 on ticket delete until staging deploys PMS-149 route
ba39eddMerge pull request 'feat(tickets): add DELETE /tickets/{id} so E2E cleans up its company (PMS-149)' (#133) from feat/pms-149-ticket-delete-route into main
451fa6dfix(tickets): map ticket-delete FK violation to 400, not 500
8a2e442feat(tickets): add DELETE /tickets/{id} so E2E cleans up its company
5cc3581Merge pull request 'feat(e2e): un-fixme OIDC token-flow via replayed OP cookies (PMS-143)' (#132) from feat/pms-143-oidc-unfixme into main
0de7285chore(e2e): surface bunyip body on OIDC authorize non-3xx
868658cfix(e2e): skip parent-domain derivation for IP literals
0368bfffeat(e2e): un-fixme OIDC token-flow via replayed OP cookies (PMS-143)
853f9a1Merge pull request 'test(e2e): re-fixme auth-ui pending PMS-148 login race' (#131) from fix/pms-148-refixme-auth-ui into main
82418fctest(e2e): re-fixme auth-ui pending PMS-148 login race
3e34835Merge pull request 'feat(e2e): un-fixme auth-ui login + logout round-trip (PMS-142 v2)' (#130) from feat/pms-142-auth-ui-unfixme-v2 into main
9b3cfe1feat(e2e): un-fixme auth-ui login + logout round-trip (PMS-142 v2)
5f850e7Merge pull request 'chore(build): bump rust-builder-glibc to v1.0.1' (#127) from chore/bump-rust-builder-glibc-v1.0.1 into main
0b7e68eMerge branch 'main' into chore/bump-rust-builder-glibc-v1.0.1
5b184d2Merge pull request 'feat(reports): GET /reports registry + integration tests (PMS-146)' (#129) from feat/pms-146-reports-registry-and-tests into main
73e8682feat(reports): add GET /reports registry + integration tests (PMS-146, closes PMS-93 gaps)
cc4dcbdMerge pull request 'feat(assets): audited secret reveal, no plaintext in lists, tests (PMS-71)' (#128) from feat/pms-71-asset-secret-reveal-and-tests into main
10b3760feat(assets): stop leaking secrets in lists; add audited reveal endpoints + tests (PMS-71)
78672aechore(build): bump rust-builder-glibc to v1.0.1
aac7c96Merge pull request 'feat(projects): budget-vs-actual + time rollup + tests (PMS-51)' (#126) from feat/pms-51-project-actuals-and-tests into main
5dc8acdfeat(projects): compute budget-vs-actual, roll approved time into actuals, add tests (PMS-51)
56e0a18Merge pull request 'feat(portal): wire company-scoped invoices + add portal isolation tests (PMS-25)' (#125) from feat/pms-25-portal-invoices-and-tests into main
7e0f275feat(portal): wire company-scoped invoices + add portal isolation tests (PMS-25)
bcf6f01Merge pull request 'chore: Sync .gitignore' (#124) from chore/sync-gitignore into main
86bbecachore: Sync .gitignore
70e2ae4Merge pull request 'chore(e2e): capture access_token from /oauth2/token response, not just Bearer header' (#123) from chore/e2e-capture-spa-build-hash into main
160688dchore(e2e): capture access_token from /oauth2/token response, not just Bearer header
7619ecbMerge pull request 'chore(e2e): surface mokosh-apps SPA bundle hash in timeout diagnostic' (#122) from chore/e2e-capture-spa-build-hash into main
cdf46cechore(e2e): surface mokosh-apps SPA bundle hash in timeout diagnostic
63ab9c1Merge pull request 'fix(auth): JIT placeholder name no longer surfaces UUID fragments' (#121) from fix/jit-fallback-name-not-uuid-fragments into main
37fcc9cfix(auth): JIT placeholder name no longer surfaces UUID fragments
321520aMerge pull request 'feat(kb): one vote per user account for article ratings (toggle/switch)' (#120) from feat/kb-rating-per-user-votes into main
f2e670fstyle: cargo fmt
aeb0e56feat(kb): make article ratings one vote per user account
7a19fb6Merge pull request 'feat(billing): generate recurring invoices from contract items (PMS-64 AC5)' (#119) from feat/pms64-recurring-invoicing into main
a58c1dbMerge branch 'main' into feat/pms64-recurring-invoicing
4a4ec49Merge pull request 'feat(kb): serve portal KB feed only via the portal-authed route' (#118) from feat/portal-kb-feed-auth into main
bb0d8d2Merge branch 'main' into feat/portal-kb-feed-auth
98ec545Merge pull request 'feat(notifications): backfill default rules for pre-existing tenants' (#117) from feat/notifications-seed-existing-tenants into main
0f837bestyle: apply cargo fmt
a1747d4style: apply cargo fmt
bd72ab6style: apply cargo fmt
e266dcafeat(billing): generate recurring invoices from contracts (PMS-64 AC5)
de3ebfffeat(kb): serve portal KB feed only via portal-authed route
d03ff7ffeat(notifications): backfill default worker rules for existing tenants
0c620dcMerge pull request 'fix(api): repair list ORDER BY misuse + time-entries count placeholders (PMS-145)' (#116) from fix/pms-145-time-entries-count-placeholders into main
df0ce4bfix(api): repair list ORDER BY misuse + time-entries count placeholders
66a1da9Merge pull request 'fix(ci): cap integration-test parallelism to dodge sqlx-test pool timeout' (#115) from fix/check-pg-pool-saturation into main
d531f38Merge pull request 'feat(e2e): close PMS-142 - un-fixme the auth-ui login + logout round-trip' (#112) from feat/pms-142-auth-ui-unfixme into main
eea87f3fix(ci): cap integration-test parallelism to dodge sqlx-test pool timeout
02c30e0Merge pull request 'fix(billing): gate invoicing on timesheet approval (PMS-144)' (#114) from fix/pms-144-billing-approval-gate into main
4bd93f4fix(billing): gate invoicing on timesheet approval (ready_to_bill)
d9abe84Merge pull request 'feat(dev-sso): validate bunyip-issued tokens as a Resource Server' (#113) from feat/dev-sso-rs-trust-bunyip into main
b6d9619test(e2e): re-quarantine auth-ui - bunyip /logout does not kill OP session
ce25821feat(dev-sso): validate bunyip-issued tokens as a Resource Server
8c50b19test(e2e): tighten page-diagnostics API + use Error cause for original stack
826e5b4feat(e2e): close PMS-142 - un-fixme the auth-ui login + logout round-trip
c94e090Merge pull request 'feat(ci): close PMS-141 - promote E2E to merge gate on PRs to main' (#111) from feat/pms-141-e2e-merge-gate into main
ae35028feat(ci): close PMS-141 - promote E2E suite to merge gate on PRs to main
b60a8d3Merge pull request 'test(e2e): quarantine OIDC token-flow test - needs OP session cookie' (#110) from fix/e2e-oidc-fixme into main
bfa3945test(e2e): quarantine OIDC token-flow test - needs OP session cookie
cab7078Merge pull request 'fix(e2e): point OIDC test at the OP host, quarantine auth-ui round-trip' (#109) from fix/e2e-oidc-op-base-url-and-auth-ui-fixme into main
dc5019edocs(e2e): refresh stale comments + README harness description
718e6bbfix(e2e): point OIDC test at the OP host, quarantine auth-ui round-trip
d9d3084Merge pull request 'fix(e2e): capture bearer from ANY host, not just /api/v1' (#108) from fix/e2e-capture-bearer-any-host into main
8a69f3ffix(e2e): capture bearer from ANY host, not just /api/v1
95637bdMerge pull request 'fix(ci): pass E2E_TOTP_SECRET secret into the E2E job env' (#107) from fix/e2e-wire-totp-secret into main
5bcaf8dfix(ci): pass E2E_TOTP_SECRET secret into the E2E job env
319f8d2Merge pull request 'feat(e2e): enter TOTP second factor during SPA login' (#106) from feat/e2e-totp-handling into main
1a9e37efeat(e2e): enter TOTP second factor during SPA login
4d46bf6Merge pull request 'fix(e2e): treat /login/* as still IN the login flow' (#105) from fix/e2e-login-pathname-anchor into main
88c274bfix(e2e): treat /login/* (e.g. /login/2fa) as still IN the login flow
a90fbfbMerge pull request 'test(e2e): dump full URL/trail/request diagnostic when setup times out' (#104) from fix/e2e-bearer-diagnostics into main
b30dc74test(e2e): dump full URL/trail/request diagnostic when setup times out
a383fb1Merge pull request 'fix(e2e): probe data routes for bearer, merge auth-ui to dodge rate limit' (#103) from fix/e2e-spa-bearer-intercept-and-logout into main
66e3433test(e2e): harden auth-ui locators with .first(), tighten /api/v1 filter
de17374fix(e2e): force a post-login probe + merge auth-ui tests to dodge rate limit
29d2eb8Merge pull request 'fix(e2e): intercept SPA bearer for setup, click User-menu -> Logout' (#102) from fix/e2e-spa-bearer-intercept-and-logout into main
30d66a9test(e2e): refresh auth-state comment, drop dead routes.authLogin
328ffbcfix(e2e): intercept SPA bearer for setup, click User-menu -> Logout
4b01eefMerge pull request 'fix(ci): wait-for-deploy refetches missing trees, skips gate if unresolvable' (#101) from fix/e2e-wait-deploy-skip-when-unresolvable into main
9c73dd1fix(ci): wait-for-deploy refetches missing trees, skips gate if unresolvable
6bf0e9aMerge pull request 'fix(ci): wait-for-deploy unshallows the clone when git log returns empty' (#100) from fix/e2e-wait-deploy-unshallow into main
efea598fix(ci): wait-for-deploy unshallows the clone when git log returns empty
d47d72aMerge pull request 'fix(ci): resolve deploy-sync expected SHA to the last build-relevant commit' (#99) from fix/e2e-runner-toolcache into main
6040838fix(ci): resolve deploy-sync expected SHA to the last build-relevant commit
8924692Merge pull request 'test(e2e): aggregate-all-missing env vars in a preflight setup project' (#98) from fix/e2e-runner-toolcache into main
104ed55test(e2e): aggregate-all-missing env vars in a preflight setup project
99738adMerge pull request 'fix(ci): bake MOKOSH_GIT_HASH + describe + date into OCI build' (#97) from fix/e2e-runner-toolcache into main
52742c6fix(ci): bake MOKOSH_GIT_HASH + describe + date into OCI build
256d17fMerge pull request 'fix(ci): API host is api.msp., not msp-api.' (#96) from fix/e2e-runner-toolcache into main
3adb4a2fix(ci): API host is api.msp., not msp-api.
9d8b11aMerge pull request 'fix(ci): split E2E SPA host from API host, derive msp-api.' (#95) from fix/e2e-runner-toolcache into main
3883fc8fix(ci): split E2E SPA host from API host, derive msp-api.
80a160eMerge pull request 'fix(ci): treat empty E2E_BASE_URL as missing, not as override' (#94) from fix/e2e-runner-toolcache into main
0de6163fix(ci): treat empty E2E_BASE_URL as missing, not as override
e965450Merge pull request 'fix(ci): drop playwright --with-deps - opensuse runner has no apt-get' (#93) from fix/e2e-runner-toolcache into main
21ca57ffix(ci): drop playwright --with-deps - opensuse runner has no apt-get
78ed118Merge pull request 'fix(ci): hardcode RUNNER_TOOL_CACHE path - runner context unbound in job env' (#92) from fix/e2e-runner-toolcache into main
020631bfix(ci): hardcode RUNNER_TOOL_CACHE path - runner context unbound in job env
3f8c2a4Merge pull request 'fix(ci): point E2E setup-node tool cache at RUNNER_TEMP' (#91) from fix/e2e-runner-toolcache into main
55eb53cfix(ci): point E2E setup-node tool cache at RUNNER_TEMP
aadb3bbMerge pull request 'PMS-140: Add Playwright E2E suite against staging, run on every merge to main' (#90) from feat/pms-140-e2e-playwright into main
01a4d7dtest(e2e): fix auth path, require OIDC redirect, harden teardown and CI
b4ccc9atest(e2e): add Playwright suite against staging, run post-merge to main
0c39d1eMerge pull request 'feat(auth): close PMS-138 - subdomain-driven tenant hint on login + forgot-password + Google JIT' (#89) from feat/pms-138-closeout into main
c7d40edfeat(auth): close PMS-138 - subdomain-driven tenant hint on login + forgot-password + Google JIT
4b4c1f4Merge pull request 'fix(settings): drop legacy DELETE /settings/{id} - matchit conflict with /settings/{category}' (#88) from fix/settings-route-conflict into main
a0d3d91fix(settings): drop legacy DELETE /settings/{id} - matchit conflict with /settings/{category}
934f96aMerge pull request 'feat(settings): close PMS-113 - unify module-config, add category endpoints + value validation, gate optional modules at runtime' (#87) from feat/pms-113-closeout into main
606ba79feat(settings): close PMS-113 - unify module-config, add category endpoints + value validation, gate optional modules at runtime
63a1bfcMerge pull request 'feat(tenants): close PMS-21 - cfg-gate cleanup + module-config and cross-tenant tests' (#86) from feat/pms-21-closeout into main
272d179feat(tenants): close PMS-21 - cfg-gate cleanup + module-config and cross-tenant tests
7a34463Merge pull request 'fix(list-queries): correct WHERE param numbering for count_query in 6 list_* methods' (#85) from fix/list-count-query-param-mismatch into main
6acbb23fix(list-queries): correct WHERE param numbering for count_query in 6 list_* methods
68580e0Merge pull request 'fix(migrations): rename PMS-4 recovery-codes migration 027 -> 029 (version collision with PMS-106)' (#84) from fix/migration-027-collision into main
7edbf13fix(migrations): rename PMS-4 recovery-codes migration 027 -> 029 (version collision with PMS-106)
4d995d4Merge pull request 'feat(auth): close PMS-4 - list filter, layered rate limit, MFA recovery codes, tenant hardening' (#83) from feat/pms-4-closeout into main
387e18dMerge pull request 'feat(calendar): appointment reminders worker (PMS-58)' (#81) from feat/pms-58-calendar-reminders into main
e922e0fMerge branch 'main' into feat/pms-58-calendar-reminders
d00c3d0Merge remote-tracking branch 'origin/main' into feat/pms-58-calendar-reminders
6a0e444Merge pull request 'feat(audit): record billing + contracts mutations in the audit log (PMS-117)' (#82) from feat/pms-117-audit-hooks into main
be05264Merge branch 'main' into feat/pms-117-audit-hooks
ef0ffbffeat(audit): record billing + contracts mutations in the audit log (PMS-117)
35704a5Merge pull request 'feat(sla): at-risk + breach notifications via sweep worker (PMS-106)' (#80) from feat/pms-106-sla-notify into main
1d020fbfeat(calendar): appointment reminders worker (PMS-58)
d25444bfeat(auth): close PMS-4 - list filter, layered rate limit, MFA recovery codes, tenant hardening
e1244a0feat(sla): at-risk + breach notifications via sweep worker (PMS-106)
242360aMerge pull request 'feat(calendar): RRULE expansion + dispatch view (PMS-58)' (#77) from feat/pms-58-calendar into main
8874be8Merge branch 'main' into feat/pms-58-calendar
bdcb4d5Merge pull request 'feat(contracts): hour-balance consumption, rate resolution, lifecycle (PMS-64)' (#75) from feat/pms-64-contracts into main
0fd9124Merge remote-tracking branch 'origin/main' into feat/pms-58-calendar
39950bfMerge remote-tracking branch 'origin/main' into feat/pms-64-contracts
269c79dMerge pull request 'feat(kb): publish lifecycle, slug uniqueness, version restore, trigram search, feedback, portal feed (PMS-79)' (#78) from feat/pms-79-kb into main
89fd6fdMerge branch 'main' into feat/pms-79-kb
dbf8c91feat(kb): publish lifecycle, slug uniqueness, version restore, trigram search, feedback, portal feed (PMS-79)
f1d7e99Merge pull request 'feat(billing): generate invoices from billable time entries (PMS-33)' (#76) from feat/pms-33-billing into main
c7884b1Merge branch 'main' into feat/pms-33-billing
025f6d3Merge pull request 'feat(sla): business-hours-aware SLA clock engine (PMS-106)' (#72) from feat/pms-106-sla-clock into main
bc9e86aMerge branch 'main' into feat/pms-106-sla-clock
1cff709Merge pull request 'feat(audit): record entity mutations + auth events (PMS-117)' (#70) from feat/pms-117-audit-log into main
d5e9b1bfeat(calendar): RRULE expansion + dispatch view (PMS-58)
ba69f11Merge remote-tracking branch 'origin/main' into feat/pms-64-contracts
d807030Merge remote-tracking branch 'origin/main' into feat/pms-106-sla-clock
f7f08c1Merge remote-tracking branch 'origin/main' into feat/pms-117-audit-log
7396d1bfeat(billing): generate invoices from billable time entries (PMS-33)
9c14ffafeat(contracts): hour-balance consumption, rate resolution, lifecycle (PMS-64)
a3ebcd0Merge pull request 'test(pms-11): cover assign + assert JOINed ticket DTO fields (F3)' (#73) from feat/pms-11-tickets-assign-joined-fields-test into main
fca3248Merge pull request 'fix(contacts): make update_company and update_contact persist every UpdateRequest field' (#74) from feat/pms-17-tests into main
ef5af80test(pms-11): cover assign + assert JOINed ticket DTO fields (F3)
3bbf1e5fix(contacts): make update_company and update_contact persist every UpdateRequest field
6bd23e4feat(sla): business-hours-aware SLA clock engine (PMS-106)
e489d7aMerge pull request 'test(pms-17): integration tests pinning F4 fix + site/contact CRUD + portal flag + F9 filter' (#71) from feat/pms-17-tests into main
e1aec1atest(pms-17): integration tests pinning F4 fix + site/contact CRUD + portal flag + F9 filter
708d322feat(audit): record entity mutations + auth events in the audit log
a305bcaMerge pull request 'feat(scheduler): shared background-job runner (PMS-135)' (#69) from feat/pms-135-scheduler into main
3895e17fix(scheduler): address code-review findings on shared scheduler (PMS-135)
887dbd7feat(scheduler): shared background-job runner (PMS-135)
0d4c473Merge pull request 'feat(api): readiness probe at /api/v1/ready (PMS-130)' (#68) from feat/pms-130-readiness into main
bbe9855fix(api): address code-review findings on /ready (PMS-130)
6174aa4feat(api): readiness probe at /api/v1/ready (PMS-130)
69364fcMerge pull request 'feat(types): extract shared DTOs into mokosh-types workspace crate (PMS-129)' (#67) from feat/pms-129-mokosh-types into main
99ca90efix(types): add serde_json dep + refresh Cargo.lock for new crate (PMS-129)
02fa99ffix(types): replace AppError reference with crate-local AuthRequired marker (PMS-129)
5454f62feat(types): extract shared DTOs into a mokosh-types workspace crate (PMS-129)
e24ff59Merge pull request 'feat(migrations): split 1688-line initial schema into per-feature files (PMS-128)' (#66) from feat/pms-128-migration-split into main
813c1c1feat(migrations): split 1688-line initial schema into per-feature files (PMS-128)
666913fMerge pull request 'feat(api): paginate every list handler (PMS-127)' (#65) from feat/pms-127-pagination into main
a03bfffdocs(pagination): clarify audit-log cap drop + dual-Query convention
91e1a40feat(api): route every list handler through utils/pagination (PMS-127)
46a45a1Merge pull request 'feat(tracing): named instrument spans on every service method (PMS-126)' (#64) from feat/pms-126-tracing-spans into main
529e778feat(tracing): add named instrument spans on every service method (PMS-126)
6c80f4cMerge pull request 'feat(router): self-documenting 501 body for placeholder modules (PMS-125)' (#63) from feat/pms-125-stub-bodies into main
d5044c0style: allow dead_code on common::{seed_admin,login} for unauthenticated test binaries
d8ae8afstyle: rewrap assert! to satisfy rustfmt in dispatch_stub test
0940a9dstyle: reflow long lines for rustfmt in PMS-125 stub
f421318feat(router): self-documenting 501 body for placeholder modules (PMS-125)
bf5c42aMerge pull request 'feat(rmm): device-sync worker, provider trait, suppression + dedupe (PMS-103)' (#62) from feat/pms-103-rmm-sync-worker into main
0dfea6dstyle: drop unused RmmService accessor methods
6aefab3style: apply rustfmt to PMS-103 rmm sync worker work
1840992feat(rmm): sync worker, provider trait, prefs/dedupe, encryption key wire-up
9889f59Merge pull request 'feat(notifications): dispatcher worker, prefs, encryption (PMS-92)' (#61) from feat/pms-92-notifications-dispatcher into main
09e5435style(tests): factor notifications row tuple into NotifRow alias
4f43203style: blank line between bullet list and paragraph in dispatch doc
76a54d7style: apply rustfmt to PMS-92 notifications dispatcher work
d3717d4feat(notifications): dispatcher worker, preference enforcement, encryption key wire-up
98d3aa7Merge pull request 'fix(auth): seed first_name/last_name defaults on bunyip JIT user upsert' (#60) from feat/jit-user-name-defaults into main
7dceaf6fix(auth): seed first_name/last_name defaults on bunyip JIT user upsert
d775285Merge pull request 'feat(contacts): populate CompanyResponse rollup fields' (#59) from feat/crm-ops into main
abc2bc4feat(contacts): populate CompanyResponse rollup fields
7747fb4Merge pull request 'feat(time-tracking): rounding, rate derivation, timesheet approval, tenant scoping' (#58) from feat/time-tracking-resolve-rounding into main
d0acbb5feat(time-tracking): apply rounding, derive rates, add timesheet approval + tenant scoping
248e135Merge pull request 'fix/dev-sso-private-network-name' (#57) from fix/dev-sso-private-network-name into main
dd34ae9fix(dev): drop server's depends_on infisical so compose project is valid
0aaa5f2fix(dev-sso): match overlay private network name to base per-user name
87cac87Merge pull request 'style(tests): rustfmt wrap on hash_password call' (#56) from fix/pms-124-fmt-wrap into main
81a294cfix(tickets): cast sla_targets DECIMAL columns to float8 for sqlx decode
fb96025test(common): init tracing subscriber so the real sqlx error surfaces
2de1bd8fix(tests): sendcustom_fields: {}on create ticket, surface error body
81487c8fix(ci): point DATABASE_URL at the postgres service name, not localhost
c4727dcstyle(tests): allow dead_code on per-binary-unused common items
e56e42astyle(tests): rustfmt wrap on hash_password call
cc5f7c3Merge pull request 'feat(tests): module-level integration tests for real route groups (F10)' (#55) from feat/pms-124-integration-tests into main
806312ffix(tests): authenticate via Authorization: Bearer, not a cookie jar
d172c15feat(tests): module-level integration tests for real route groups (F10)
3b62355Merge pull request 'feat(api): add length validation to all Filter query types (F9)' (#54) from feat/pms-123-filter-validate into main
7b67a7adocs(kb): note ILIKE cap rationale on KbArticleFilter.q
b7c612ffeat(api): add length validation to all Filter query types (F9)
53450bfMerge pull request 'style(auth): cargo fmt oidc_rs.rs' (#53) from fix/oidc-rs-fmt into main
9c3dffdstyle(auth): cargo fmt oidc_rs.rs
52a790dMerge pull request 'feat/bunyip-op-cutover' (#52) from feat/bunyip-op-cutover into main
cae15d2feat(auth): wire bunyip RS verifier into AuthMiddleware
cf2ff21feat(auth): implement Resource-Server at+jwt verifier
8131438feat(auth): scaffold Resource-Server OIDC verifier (bunyip-as-OP cutover)
d351093Merge pull request 'feat/fix-just-dev-wont-start-infisical' (#51) from feat/fix-just-dev-wont-start-infisical into main
de6da3arewrite comment for dev-down and dev-clean
d286b3afix comment
ef1649aadd start infisical recipe
0b3727cadd tag
eabf8e4Merge pull request 'fix(ci): generate release notes from commits since previous tag' (#50) from fix/release-notes-since-prev-tag into main
dd7f0fdfix(ci): generate release notes from commits since previous tag
5b5eef0Merge pull request 'fix/db-migrations-in-app' (#49) from fix/db-migrations-in-app into main
0c9a066WIP: Build on every push
3d2b51aWIP: Build on every push
82b3044WIP: Build on every push
562f8e4fix(migrations): move mokosh_auth schema/columns into app migrations
9b551afMerge pull request 'PSA audit: auth + tenancy security fixes' (#48) from feat/m1-vas into main
dc202a9fix(test): bind reset-token strings before borrowing (E0716)
1b2568efix(router): use api.msp host prefix in not_a_frontend fallback
033b6bcstyle: cargo fmt --all
92c485etest(auth): unit-test reset-token parsing + super-admin email allowlist
ddaaeebci: publish the server image as mokosh-server (single name)
6f406d3ci: publish the server image as both mokosh-server and mokosh-api
71e65cefix(db): parameterize RLS tenant GUC; drop ineffective with_tenant
1d5ac98feat(auth): harden Google OAuth (verified-email link, email allowlist, fail-closed)
5e0af57fix(tenancy): validate cross-tenant foreign keys on create/update
bd1d794fix(auth): bind reset tokens to user; gate sign-in on tenant status
6c50a88Merge pull request 'fix(dev-sso): route Traefik labels on Compose 2.40 + shared Traefik' (#47) from fix/dev-sso-traefik-label-interpolation into main
d13ba40fix(dev-sso): route Traefik labels correctly on Compose 2.40 + shared Traefik
c170baaMerge pull request 'docs: quickstart for fresh clones + CLAUDE.md' (#46) from docs/quickstart into main
a05771adocs: add quickstart for fresh clones, plus CLAUDE.md
e1ddf6fMerge pull request 'fix(ci): trigger image build on crates/ edits + add manual dispatch' (#45) from fix/ci-trigger-crates into main
6cb9513fix(ci): trigger image build on crates/** edits + add manual dispatch
3fdc0efMerge pull request 'feat(ci): use $RUNNER_TEMP instead of /tmp in claude-fix workflow' (#44) from feat/pms-132-no-tmp into main
bcd0990feat(ci): guard against unset RUNNER_TEMP before using it
54f1941feat(ci): use $RUNNER_TEMP instead of /tmp in claude-fix workflow
11fc65bMerge pull request 'fix(clippy): use ok_or instead of ok_or_else for plain HttpError values' (#43) from fix/clippy-sessions-ok-or into main
1f83ca5fix(clippy): use ok_or instead of ok_or_else for plain HttpError values
d2e9177Merge pull request 'Implementing SSO, OIDC (All auth)' (#42) from feature-sso into main
09751b3Merge remote-tracking branch 'origin/main' into feature-sso
ce3f90ffeat(oidc): fan back-channel logout out on RP-initiated /oauth2/logout
93883edfeat(extractor): BearerUser rejects tokens from revoked op_sessions
0b99014feat(auth): emit back-channel logout to every registered RP on /v1/auth/logout
97af972Merge pull request 'feat(justfile): fj-driven create-release + group attrs (DEV-331)' (#41) from feat/justfile-fj-pr-create-DEV-331 into main
778a440feat(justfile): fj-driven create-release + group attrs (DEV-331)
4353d52log 5xx errors with underlying AuthError detail
8a0b75fMerge pull request 'feat: consolidate PMS server PRs (PMS-4..PMS-131)' (#40) from feat/pms-merge into main
9fa4c00fix(clippy): resolve remaining workspace clippy warnings for -D warnings
ff7413dfix(clippy): apply machine-applicable clippy suggestions
0db5161style: cargo fmt --all; suppress two pre-existing clippy lints in mokosh-auth-core
01ebd03ci(check): add fmt + clippy + compile + tests workflow
01aefb8Merge remote-tracking branch 'origin/chore/claude-fix-workflow' into feat/pms-merge
13d5ddaMerge remote-tracking branch 'origin/feat/audit-story-pms-117' into feat/pms-merge
52ad3acMerge remote-tracking branch 'origin/feat/settings-story-pms-113' into feat/pms-merge
be878e7Merge remote-tracking branch 'origin/feat/sla-story-pms-106' into feat/pms-merge
0862e7fMerge remote-tracking branch 'origin/feat/rmm-story-pms-100' into feat/pms-merge
d1d4efbMerge remote-tracking branch 'origin/feat/reports-story-pms-93' into feat/pms-merge
a057e56Merge remote-tracking branch 'origin/feat/notifications-story-pms-85' into feat/pms-merge
6023551Merge remote-tracking branch 'origin/feat/kb-story-pms-79' into feat/pms-merge
c415e73Merge remote-tracking branch 'origin/feat/assets-story-pms-71' into feat/pms-merge
b718b3fMerge remote-tracking branch 'origin/feat/contracts-story-pms-64' into feat/pms-merge
236e484Merge remote-tracking branch 'origin/feat/calendar-story-pms-58' into feat/pms-merge
62b9643Merge remote-tracking branch 'origin/feat/projects-story-pms-51' into feat/pms-merge
b239c93Merge remote-tracking branch 'origin/feat/time-tracking-story-pms-42' into feat/pms-merge
c166d47Merge remote-tracking branch 'origin/feat/billing-story-pms-33' into feat/pms-merge
7ea90afMerge remote-tracking branch 'origin/feat/portal-story-pms-25' into feat/pms-merge
40d26acMerge remote-tracking branch 'origin/feat/tenants-story-pms-21' into feat/pms-merge
66f1da3Merge remote-tracking branch 'origin/feat/contacts-story-pms-17' into feat/pms-merge
e957286Merge remote-tracking branch 'origin/feat/tickets-story-pms-11' into feat/pms-merge
a35b3f0Merge remote-tracking branch 'origin/feat/auth-story-pms-4' into feat/pms-merge
e2fb8b2ci: add claude-fix workflow
47b3574fix(justfile): register lets-chat with per-provider redirect_uri slug
02deaedfeat(audit): scaffold + writer middleware + read endpoint
43b1c1ffeat(settings): scaffold + tenant settings + module configs
f4a2d8afeat(sla): scaffold + policies, targets, business hours, holidays, evaluator
ff4b78efeat(rmm): scaffold + connections, device mappings, alert rules, ingest
25ea790feat(reports): scaffold + dashboard, tickets, time, billing, CSV export
fe702ccfeat(notifications): scaffold + channels, templates, prefs, inbox, rules, dispatcher
d1812eafeat(kb): scaffold + categories, articles, versioning, portal feed
ffce981feat(assets): scaffold + asset types, assets, relationships, CIs, credentials, audit
7298b90feat(contracts): scaffold + CRUD for contracts, items, balances, rate cards
24ddf81feat(calendar): scaffold + appointments, availability, time-off, on-call
96ce98bfeat(projects): scaffold + projects, phases, task statuses, tasks, dependencies
adaa594feat(time-tracking): implement work types, time entries, timesheets, timers, rounding rules
cefa9acfeat(time-tracking): scaffold module + wire router (PMS-43)
f31778bfeat(billing): tax rates CRUD + jurisdiction lookup
81da537feat(billing): payment gateway configs CRUD with at-rest encryption
d3de7f1feat(billing): payments CRUD with invoice-status reconciliation
e67030cfeat(billing): PUT /api/v1/invoices/:id with frozen-status guard
47a0ae4feat(billing): POST /api/v1/invoices with atomic sequence + line items
44e178ffeat(billing): GET /api/v1/invoices/:id with lines
04e89defeat(billing): GET /api/v1/invoices paginated + filterable (F7)
5105a8afeat(billing): scaffold module + wire router (PMS-34)
fed6a72feat(portal): GET /api/v1/portal/kb placeholder pending PMS-79
28775fcfeat(portal): GET /api/v1/portal/invoices/:id placeholder pending PMS-33
73d99e2feat(portal): GET /api/v1/portal/invoices placeholder pending PMS-33
ab0b9f2feat(portal): GET /api/v1/portal/tickets/:id with cross-company 404
60488bcfeat(portal): GET /api/v1/portal/tickets lists company-scoped tickets
b06c6b0feat(portal): POST /api/v1/portal/tickets creates contact-scoped ticket
c1d6b7afeat(portal): contact-scoped session + portal auth middleware (F6)
c38cdeafeat(router): gate /api/v1/tenants behind the multi-tenant feature
3bcfe6ffeat(auth): TenantScope extractor for explicit tenant-id propagation
2b634abchore(router): drop the dead /companies alias
e00a272feat(contacts): honor create_portal_access on create_contact
06de4abfeat(tickets): dispatch notifications + webhooks from automation rules
7bb0df5feat(tickets): send email when add_note has send_email = true
eaf66dbfix(tickets): join lookup tables into TicketResponse (F3)
e90708cfeat(auth): personal API key CRUD (issue / list / revoke)
3a9cb3ffeat(auth): implement MFA TOTP verification + enrollment endpoints
8ce5238feat(auth): send welcome email on admin user creation
d67f8bffeat(auth): send password reset email via Mailer trait
e2eff78Merge pull request 'Revert M1 image distribution work' (#19) from revert/m1-image-distribution into main
b573fc4Revert M1 image distribution work
848fcc3Merge pull request 'ci: fix QEMU binfmt registration for arm64 cross-build' (#18) from feat/m1-image-distribution into main
fa7ab7dci: fix QEMU binfmt registration for arm64 cross-build
89d19f4Merge pull request 'ci: register QEMU binfmt inline instead of via setup-qemu-action' (#17) from feat/m1-image-distribution into main
a74fbd5ci: register QEMU binfmt inline instead of via setup-qemu-action
2444c15Merge pull request 'feat/m1-image-distribution' (#16) from feat/m1-image-distribution into main
36b647edocs(operator): document container registry auth for self-hosters
fcb323efeat(m1): operator compose.yml + update check + multi-arch build
dc17aeeMerge pull request 'fix(oci): drop image.source label causing dual-org package listing' (#15) from fix/drop-oci-source-label into main
87a85b6fix(oci): drop image.source label causing dual-org package listing
bc546f0chore(justfile): add register-lets-chat-client recipe (sso M1)
a253ef3feat(users): protect Owner memberships from other admins
c097ae3fix(auth): switch_active_tenant rebinds new token to caller's op_session
8ac097afeat(audit): filter extensions + CSV export (item 7 server)
e0575bdfeat(sessions): admin endpoints to list+revoke another user's sessions
139d71bMerge pull request 'feat: multi-origin CORS + msp-api placeholder + calendar route stub' (#14) from feat/cors-multi-origin-and-placeholder into main
7beb7a4security: stop tracking .env.dev; gitignore future copies
4fb15b2docs: milestone-1 handoff for the PSA Systems v0.1.0 cutoverDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)
-
v0.2.0
StableSome checks failedBuild OCI container / Build and push mokosh-api image (push) Failing after 9sreleased this
2026-05-14 23:57:18 +02:00 | 1257 commits to main since this releaseChangelog
da5b705Merge pull request 'Release v0.2.0' (#228) from release/v0.2.0 into main
cbc6b03Release v0.2.0
00084a0Merge pull request 'fix(assets): wire configured AES key and harden vault crypto integrity' (#226) from fix/pms-188-assets-zero-key-crypto-integrity into main
93df0f9Merge origin/main into fix/pms-188-assets-zero-key-crypto-integrity
92a4975Merge origin/main into fix/pms-188-assets-zero-key-crypto-integrity
3a4327aMerge pull request 'feat(rls): activate RLS at runtime via split migrator/app DB roles' (#224) from feat/pms-285-rls-runtime-role-split into main
714658eMerge origin/main into feat/pms-285-rls-runtime-role-split
55000e0Merge pull request 'chore(cleanup): remove dead crates code and stray config/seed/test cruft' (#220) from chore/pms-202-remove-dead-code into main
1f4884eMerge origin/main into chore/pms-202-remove-dead-code
e1e04e2Merge pull request 'chore(cleanup): remove dead and stray code from src/ tree' (#218) from chore/pms-201-remove-dead-stray-code into main
5755852Merge origin/main into chore/pms-201-remove-dead-stray-code
69bdf0aMerge pull request 'fix: correct rmm, notifications, SLA, KB, portal, and contacts defects' (#217) from fix/pms-195-module-correctness-defects into main
0c7f45dMerge origin/main into fix/pms-195-module-correctness-defects
02c6300Merge pull request 'test(settings): hit canonical /api/v1/invoices in module-gate tests' (#215) from chore/checks-workflow-986a08ef into main
258450cMerge origin/main into chore/checks-workflow-986a08ef
2e34edeMerge pull request 'fix(contracts,billing): close financial-integrity gaps' (#213) from fix/pms-194-contracts-billing-financial-integrity into main
6d07954Merge origin/main into fix/pms-194-contracts-billing-financial-integrity
bad33e0Merge pull request 'refactor: consolidate duplicated helpers, types, and test fixtures' (#212) from feat/pms-199-consolidate-duplicated-helpers into main
c00cae2Merge origin/main into feat/pms-199-consolidate-duplicated-helpers
eac8dbbMerge pull request 'fix(db): converge ticket filter builder; audit count_query placeholder family' (#211) from feat/pms-197-audit-count-query-placeholder-family into main
4a7c72eMerge origin/main into feat/pms-197-audit-count-query-placeholder-family
06bddefMerge pull request 'fix(schema): harden migrations, FKs, seed, and truncation (PMS-196)' (#210) from feat/pms-196-harden-migrations-rls-integrity into main
ad47e38Merge origin/main into feat/pms-196-harden-migrations-rls-integrity
85fd769Merge pull request 'fix(tickets): scope writes to tenant and validate FK references' (#209) from fix/pms-193-scope-tickets-writes-validate-fk into main
3154fbaci: re-trigger Check (transient failure; green locally)
bde8f81Merge origin/main into fix/pms-193-scope-tickets-writes-validate-fk
27fa80bMerge pull request 'fix(misc): correctness, concurrency, and test-reliability defects' (#208) from fix/pms-200-misc-correctness-concurrency-test-reliability into main
7caf796Merge origin/main into fix/pms-200-misc-correctness-concurrency-test-reliability
a49cfbeMerge pull request 'fix(db,auth): dedupe migration prefix 041 and fix main compile' (#227) from fix/pms-293-dedupe-migration-prefix-041 into main
2c9c7c3fix(auth): return user: None in login_with_google mfa_required branch
820cc4dfix(db): renumber portal_setup_tokens migration 041 to 042
893f5d8fix(auth): omit user profile in Google-callback mfa_required branch
5b96470Merge origin/main into fix/pms-200-misc-correctness-concurrency-test-reliability
5946001Merge pull request 'feat(portal): mint setup-link token + email on portal-access grant' (#204) from feat/pms-136-portal-setup-link into main
c1b9663Merge origin/main into feat/pms-136-portal-setup-link
66367d5Merge pull request 'fix(auth): close invite, signup, password, and validation defects' (#203) from fix/pms-192-invite-signup-password-validation into main
52b32c5Merge origin/main into fix/pms-192-invite-signup-password-validation
8829844Merge pull request 'fix(auth): close SSO/OIDC auth-strength and conformance gaps' (#202) from feat/pms-191-sso-oidc-security-gaps into main
fbacbdeMerge origin/main into feat/pms-191-sso-oidc-security-gaps
3337ef3Merge pull request 'fix(auth): close legacy PSA auth path security gaps' (#201) from fix/pms-190-legacy-auth-security-gaps into main
7dd8b6aMerge origin/main into fix/pms-190-legacy-auth-security-gaps
7e5fa28fix(assets): allow 'deleted' in audit-log CHECK; add delete regression test
269bf16Merge pull request 'test(settings): fix stale billing route path in module-gating tests' (#225) from fix/pms-290-settings-stale-billing-path into main
4c89552fix(assets): wire configured AES key and harden vault crypto integrity
a8589c0test(settings): fix stale billing route path in module-gating tests
f67057cfeat(rls): activate RLS at runtime via split migrator/app DB roles
8d564e0Merge branch 'main' into chore/pms-201-remove-dead-stray-code
6dfb9eeMerge pull request 'fix(startup): fail loud when configured SSO bootstrap fails' (#223) from fix/pms-289-sso-fail-loud-when-configured into main
d79ab98fix(startup): fail loud when configured SSO bootstrap fails
86e40abMerge pull request 'fix(tenants): seed lookup config for tenants reached off the PSA path' (#222) from feat/pms-288-seed-lookup-config-on-placement into main
e0daef1perf(tenants): cheap-guard the per-request sequence seed
74adb16fix(tenants): seed lookup config for tenants reached off the PSA path
f75618fMerge pull request 'fix(tenants): set NOT-NULL kind in create_tenant; add regression test' (#221) from fix/pms-287-create-tenant-kind into main
f7f8b7dfix(tenants): set NOT-NULL kind in create_tenant; add regression test
8e2faadMerge pull request 'fix(startup): make migration failure fatal instead of warn-and-continue' (#219) from fix/pms-286-fatal-migrations into main
b5ad162Merge pull request 'feat(justfile): add dev-clean / dev-clean-all teardown recipes' (#214) from feat/dev-clean-recipes into main
f82d9b3Merge branch 'main' into feat/dev-clean-recipes
398c0bachore(cleanup): remove dead crates code and stray config/seed/test cruft
a3333dffix(startup): make migration failure fatal instead of warn-and-continue
842b18fchore(cleanup): remove dead and stray code from src/ tree
303efb5Merge pull request 'test(isolation): automate PMS-236 tenant-isolation QA across the API' (#216) from feat/pms-236-tenant-isolation-integration-test into main
a3224a8test(isolation): harden module-config and ticket_number checks
f5520f7fix: correct rmm, notifications, SLA, KB, portal, and contacts defects
2c69eb9test(isolation): automate PMS-236 tenant-isolation QA across the API
6678777test(settings): hit canonical /api/v1/invoices in module-gate tests
5086c63feat(justfile): add dev-clean / dev-clean-all teardown recipes
9579f2bfix(contracts,billing): close financial-integrity gaps
5f7c728refactor: consolidate duplicated helpers, types, and test fixtures
d68af1bfix(db): converge ticket filter builder; audit count_query placeholder family
eaa150ffix(schema): harden migrations, FKs, seed, and truncation (PMS-196)
0433815fix(tickets): scope writes to tenant and validate FK references
f69cc50Merge pull request 'fix(rls): cover tenant-less tables; tenant-scope user_oauth_identities' (#207) from feat/pms-258-rls-cover-tenantless-tables into main
eca763eMerge branch 'main' into feat/pms-258-rls-cover-tenantless-tables
92bf278fix(misc): correctness, concurrency, and test-reliability defects
c224ffbfix(rls): cover tenant-less tables; tenant-scope user_oauth_identities
3b508c1Merge pull request 'refactor: converge duplicated subsystems and document architecture seams' (#206) from feat/pms-198-converge-subsystems into main
f8029ebMerge branch 'main' into feat/pms-198-converge-subsystems
a9ccf05Merge pull request 'fix(audit): remove coarse per-request middleware that wrote unusable rows' (#198) from fix/pms-275-remove-coarse-audit-middleware into main
c54ebe3Merge branch 'main' into fix/pms-275-remove-coarse-audit-middleware
1b55130Merge pull request 'fix(ci): gate prod image push to main/tags; close CI coverage gaps' (#199) from fix/pms-189-ci-release-pipeline-drift into main
9c0a400Merge branch 'main' into fix/pms-189-ci-release-pipeline-drift
0316824refactor: converge duplicated subsystems and document architecture seams
e7521d3Merge pull request 'feat/pms-271-e2e-staging-prod-secrets' (#205) from feat/pms-271-e2e-staging-prod-secrets into main
5807db8fix(e2e): correct OIDC redirect_uri default to /auth/callback
fb735aarefactor(e2e): name CI secrets after deployment variables
0d33d0cfeat(portal): mint setup-link token + email on portal-access grant
2eb8977fix(auth): close invite, signup, password, and validation defects
222c649Revert "fix(e2e): keep bare E2E_* as staging, add only E2E_PRODUCTION_"
a4fef72fix(auth): close SSO/OIDC auth-strength and conformance gaps
d8e8eb0fix(e2e): keep bare E2E_ as staging, add only E2E_PRODUCTION_*
ffb58e1fix(auth): close legacy PSA auth path security gaps
3221b6bMerge pull request 'feat(e2e): split CI env vars into staging/production secrets; manual prod opt-in' (#200) from feat/pms-271-e2e-staging-prod-secrets into main
7788f76feat(e2e): split CI env vars into staging/production secrets
986a08efix(ci): gate prod image push to main/tags; close CI coverage gaps
6892bc4fix(audit): remove coarse per-request middleware that wrote unusable rows
730553aMerge pull request 'feat(migrations): no-op backfill + verification for co-mingled default-tenant rows' (#197) from feat/pms-263-comingled-backfill-verification into main
2e65ee8Merge branch 'main' into feat/pms-263-comingled-backfill-verification
2e62ad8Merge pull request 'test(isolation): per-user cross-isolation suite across modules' (#196) from feat/pms-264-per-user-isolation-suite into main
8968aa0feat(migrations): no-op backfill + verification for co-mingled default-tenant rows
f71a7c6test(isolation): per-user cross-isolation suite across modules
a927e4eMerge pull request 'fix(workers): scope notification template lookup; audit from_trusted' (#195) from feat/pms-261-worker-from-trusted-audit into main
2a9f970fix(workers): scope notification template lookup; audit from_trusted
6f54b2bMerge pull request 'refactor(domain): inject domains via env vars, never hardcode or fall back' (#192) from feat/pms-235-mokosh-domain-rebrand into main
d155840Merge branch 'main' into feat/pms-235-mokosh-domain-rebrand
6cd85carefactor(domain): inject all domains via env; drop hardcoded fallbacks
2ef2fbaMerge pull request 'fix(security): scope auth session methods to tenant; pin login-helper reachability' (#190) from feat/pms-260-cross-tenant-leak-fixes into main
3c987d4Merge branch 'main' into feat/pms-260-cross-tenant-leak-fixes
4028957Merge pull request 'feat(tenants): seed all editable lookups per tenant; reserve system-shared class' (#189) from feat/pms-259-seed-lookups-system-shared-class into main
57804d1fix(rls): renumber system-shared migration to 039; layer on PMS-257 fail-closed policy
408d9bdMerge remote-tracking branch 'origin/main' into feat/pms-259-seed-lookups-system-shared-class
100c59fMerge pull request 'feat(rls): flip tenant_isolation fail-closed with WITH CHECK and FORCE RLS' (#188) from feat/pms-257-rls-fail-closed into main
6175e84Merge branch 'main' into feat/pms-257-rls-fail-closed
d8d2696Merge pull request 'feat(tenant): remove the single-tenant cargo feature; no normal user lands in the default tenant' (#187) from feat/pms-262-remove-single-tenant-feature into main
28e059fMerge branch 'main' into feat/pms-262-remove-single-tenant-feature
50580b1Merge pull request 'feat(db): route tenant-scoped service queries through begin_with_tenant' (#186) from feat/pms-256-rls-guc-plumbing into main
c929e7cMerge branch 'main' into feat/pms-256-rls-guc-plumbing
5da88ebMerge pull request 'docs(rls): per-user isolation reference and decomposition for PMS-255' (#185) from docs/pms-255-rls-isolation-plan into main
18914baMerge branch 'main' into docs/pms-255-rls-isolation-plan
732427aMerge pull request 'chore: add pre-commit hook recipes' (#191) from chore/pre-commit-hooks into main
22b4f59Merge branch 'main' into chore/pre-commit-hooks
106f983Merge pull request 'fix(version): sanitise error bodies, warn on bad versions, test network path' (#194) from feat/pms-238-self-hosted-version-check into main
fcf44f5fix(version): sanitise error bodies, warn on bad versions, test network path
35445fdMerge pull request 'feat(version): add self-hosted update check endpoint' (#193) from feat/pms-238-self-hosted-version-check into main
551db74feat(version): cache update-check result with a TTL
e08a3adfeat(version): add self-hosted update check endpoint
ebaa8d2docs(domain): rebrand a8n.systems references to mokosh.systems (Bucket A)
2a34180chore: add install-hooks and pre-commit just recipes
cbcfad6fix(security): scope auth session methods to tenant; pin login-helper reachability
78c5992feat(tenants): seed all editable lookups per tenant; reserve system-shared class
3476ed6feat(rls): flip tenant_isolation fail-closed with WITH CHECK and FORCE RLS
6969297feat(tenant): remove the single-tenant cargo feature; no normal user lands in the default tenant
bb76afbfeat(db): route tenant-scoped service queries through begin_with_tenant
864a0d8docs(rls): per-user isolation reference and decomposition for PMS-255
2f89fc7Merge pull request 'feat(users): persist date_format_string preference on users (backend)' (#184) from feat/pms-253-date-format-preference-backend into main
c57d5c6feat(users): persist date_format_string preference on users (backend)
a8116f3Merge pull request 'chore(fmt): apply cargo fmt --all after PMS-244..PMS-249 sweep' (#183) from chore/pms-251-cargo-fmt-sweep into main
990d585chore(fmt): apply cargo fmt --all after PMS-244..PMS-249 sweep
23b3259Merge pull request 'test(auth): end-to-end placement tests for the bunyip login path (PMS-249)' (#182) from feat/mapps-249-bunyip-login-e2e into main
9291524test(auth): end-to-end placement tests for the bunyip login path (PMS-249)
339e61bMerge pull request 'feat(invitations): email the invitee on invite create (PMS-246)' (#181) from feat/mapps-246-invite-email into main
9d474edMerge remote-tracking branch 'origin/main' into feat/mapps-246-invite-email
85820e8Merge pull request 'feat(auth): backfill default-tenant users off the shared tenant on login (PMS-245)' (#180) from feat/mapps-245-backfill-default-tenant-users into main
9a752a6feat(invitations): email the invitee on invite create (PMS-246)
d8b05dffeat(auth): backfill default-tenant users off the shared tenant on login (PMS-245)
bf53e19Merge pull request 'test(auth): pin the bunyip userinfo email_verified contract (PMS-248)' (#179) from chore/mapps-248-userinfo-email-verified-contract into main
fd253a6test(auth): pin the bunyip userinfo email_verified contract (PMS-248)
f6c7d3fMerge pull request 'feat(invitations): tenant invite CRUD - Mokosh-owned org membership (PMS-244 phase 1)' (#178) from feat/mapps-244-invitations into main
bd8ffd7feat(auth): resolve SSO login to a tenant via Mokosh invites/self-signup (PMS-244, phase 2)
b54b06cfeat(invitations): tenant invite CRUD - Mokosh-owned org membership (PMS-244, phase 1)
fa7724fMerge pull request 'feat(auth): lazily re-home default-tenant users to their org tenant (PMS-243)' (#177) from feat/mapps-243-rehome into main
b78fa59feat(auth): lazily re-home default-tenant users to their org tenant (PMS-243)
59618acMerge pull request 'feat(auth): resolve SSO users to a per-org tenant via the Bunyip org claim (PMS-240)' (#175) from feat/mapps-240-bunyip-org-tenant into main
6b8ed51feat(auth): resolve SSO users to a per-org tenant via the Bunyip org claim (PMS-240)
bfb815fMerge pull request 'fix(seed): never auto-seed the shared Bunyip landing tenant (PMS-239)' (#174) from fix/mapps-239-demo-seed-shared-tenant into main
18c60effix(seed): never auto-seed the shared Bunyip landing tenant (PMS-239)
b2cf1b3Merge pull request 'chore: cargo fmt --all after the PMS-139 TenantId sweep' (#173) from chore/cargo-fmt-after-pms-139-sweep into main
c441b1cchore: cargo fmt --all after the PMS-139 TenantId sweep
c7badabMerge pull request 'feat(auth): migrate the tickets hub to TenantId, completing PMS-139 (sweep batch 8)' (#171) from feat/pms-139-sweep-tickets into main
17611c3feat(auth): migrate the tickets hub to TenantId, completing PMS-139 (sweep batch 8)
1ac0d22Merge pull request 'feat(auth): migrate the notifications hub to TenantId (PMS-139 sweep batch 7)' (#169) from feat/pms-139-sweep-notifications into main
d5c6133feat(auth): migrate the notifications hub to TenantId (PMS-139 sweep batch 7)
b4303f5Merge pull request 'feat(auth): migrate the audit hub to TenantId (PMS-139 sweep batch 6)' (#167) from feat/pms-139-sweep-hubs into main
f607764feat(auth): migrate the audit hub to TenantId (PMS-139 sweep batch 6)
23e36baMerge pull request 'feat(auth): migrate contacts + billing to TenantId (PMS-139 sweep batch 5)' (#164) from feat/pms-139-sweep-contacts-billing into main
3deb53efeat(auth): migrate contacts + billing to TenantId (PMS-139 sweep batch 5)
e2a6de3Merge pull request 'feat(auth): migrate knowledge_base + tenants + settings to TenantId (PMS-139 sweep batch 4)' (#163) from feat/pms-139-sweep-kb-tenants-settings into main
0a1006dfeat(auth): migrate knowledge_base + tenants + settings to TenantId (PMS-139 sweep batch 4)
85e08a2Merge pull request 'feat(auth): migrate calendar + sla + contracts to TenantId (PMS-139 sweep batch 3)' (#161) from feat/pms-139-sweep-calendar-sla-contracts into main
b77e671feat(auth): migrate calendar + sla + contracts to TenantId (PMS-139 sweep batch 3)
c6b6adbMerge pull request 'feat(auth): migrate assets + projects to TenantId (PMS-139 sweep batch 2)' (#160) from feat/pms-139-sweep-assets-projects into main
ee26720feat(auth): migrate assets + projects to TenantId (PMS-139 sweep batch 2)
622f3f4Merge pull request 'feat(auth): migrate rmm + time_tracking to TenantId (PMS-139 sweep batch 1)' (#159) from feat/pms-139-sweep-rmm-time into main
961251cfeat(auth): migrate rmm + time_tracking to TenantId (PMS-139 sweep batch 1)
1091d76Merge pull request 'feat(auth): typed TenantId scoping foundation + reports migration (PMS-139)' (#158) from feat/pms-139-tenant-id-foundation into main
2cc6511feat(auth): typed TenantId scoping foundation + reports migration (PMS-139)
a497e81Merge pull request 'feat(timesheets): draft state + withdraw endpoint (PMS-183)' (#157) from feat/pms-183-timesheet-withdraw into main
e75bdf9feat(timesheets): draft state + withdraw endpoint for timesheets (PMS-183)
45f51fcMerge pull request 'feat(audit): surface field-level before/after content in change history (PMS-204)' (#156) from feat/pms-204-history-content into main
60f0e4ffeat(audit): surface field-level before/after content in change history (PMS-204)
9acd44aMerge pull request 'feat(projects): record task and project edits in the audit trail (PMS-184)' (#155) from feat/pms-184-task-edit-history into main
6b20c9fMerge pull request 'feat(audit): per-record change-history endpoint (PMS-182)' (#154) from feat/pms-182-ticket-edit-history into main
f123889feat(projects): record task and project edits in the audit trail (PMS-184)
110f532feat(audit): per-record change-history endpoint for detail pages (PMS-182)
caacdc9Merge pull request 'docs: add 2026-06-06 platform audit to dev-docs/audits' (#153) from docs/add-platform-audit-2026-06-06 into main
455e9ccdocs: add 2026-06-06 platform audit to dev-docs/audits
9cd4103Merge pull request 'feat(billing): also surface invoice_number on payment responses (PMS-186)' (#150) from feat/pms-186-billing-company-name into main
11bcb0efeat(billing): also surface invoice_number on payment responses (PMS-186)
e450f5bMerge pull request 'feat(billing): include company_name on invoice and payment responses (PMS-186)' (#149) from feat/pms-186-billing-company-name into main
6bbe7fffeat(billing): include company_name on invoice and payment responses (PMS-186)
c32987cMerge pull request 'feat(reports): add safe custom report builder (PMS-180)' (#148) from feat/pms-180-custom-report-builder into main
cc0023bfeat(reports): add safe custom report builder (PMS-180)
4bc54e0Merge pull request 'feat(reports): add project + client report types end to end (PMS-179)' (#147) from feat/pms-179-project-client-reports into main
148d3f6feat(reports): add project + client report types end to end (PMS-179)
92e77eaMerge pull request 'feat(seed): seed demo data on a new account's first visit (PMS-157)' (#146) from feat/pms-157-new-account-seeding into main
b6f6ba1fix(seed): make demo ticket seeding best-effort; document E2E kill-switch
909dc07feat(seed): seed demo data on a new account's first visit (PMS-157)
aa6118fMerge pull request 'fix(contacts): 400 not 500 deleting a company with related records (PMS-170)' (#145) from fix/pms-170-company-delete-fk-400 into main
7e13835fix(contacts): return 400 not 500 when deleting a company with related records
a86e802Merge pull request 'fix(audit): correct SQL placeholder numbering in audit-log list (PMS-178)' (#144) from fix/pms-178-audit-list-placeholders into main
7acb419fix(audit): correct SQL placeholder numbering in audit-log list query
ce0dc98Merge pull request 'docs(e2e): spell out how to set the E2E account's admin role (SQL + bootstrap)' (#143) from docs/pms-155-e2e-admin-account into main
d436054Merge pull request 'feat(auth): translate Bunyip bunyip_role claim to mokosh role (PMS-172)' (#142) from feat/pms-172-bunyip-role-translation into main
e950947refactor(auth): clarify authz source + log Bunyip role transitions (PMS-172 review)
8378289feat(auth): translate Bunyip bunyip_role claim to mokosh role on the RS path
0e3285bMerge pull request 'docs(e2e): how to set the E2E account admin role (SQL + bootstrap)' (#141) from docs/pms-155-e2e-admin-howto into main
67c9cb8docs(e2e): spell out how to set the E2E account's admin role (SQL + bootstrap)
abd36b9docs(e2e): spell out how to set the E2E account's admin role (SQL + bootstrap)
3fcd925Merge pull request 'docs(e2e): require admin role for the E2E account (PMS-155)' (#140) from docs/pms-155-e2e-admin-account into main
e025056docs(e2e): require admin role for the E2E account (PMS-155)
f636e04Merge pull request 'test(e2e): add API CRUD specs for time-tracking, projects, billing, contracts (PMS-155)' (#136) from feat/pms-155-e2e-core-modules into main
8f878ddtest(e2e): add API specs for RMM and the dispatch board (PMS-155 batch 4)
007ba8btest(e2e): add API specs for notifications, settings, audit, reports (PMS-155 batch 3)
fcf367ftest(e2e): add API CRUD specs for calendar, SLA, assets, knowledge-base (PMS-155 batch 2)
9aaeac6test(e2e): make PMS-155 spec cleanup resilient to a single delete failure
802a291test(e2e): add API CRUD specs for time-tracking, projects, billing, contracts (PMS-155)
c1dab9cMerge pull request 'fix(e2e): tolerate 405 on ticket delete until staging deploys PMS-149 route' (#135) from fix/pms-149-e2e-deploy-tolerant-ticket-delete into main
289e772fix(e2e): tolerate 405 on ticket delete until staging deploys PMS-149 route
ba39eddMerge pull request 'feat(tickets): add DELETE /tickets/{id} so E2E cleans up its company (PMS-149)' (#133) from feat/pms-149-ticket-delete-route into main
451fa6dfix(tickets): map ticket-delete FK violation to 400, not 500
8a2e442feat(tickets): add DELETE /tickets/{id} so E2E cleans up its company
5cc3581Merge pull request 'feat(e2e): un-fixme OIDC token-flow via replayed OP cookies (PMS-143)' (#132) from feat/pms-143-oidc-unfixme into main
0de7285chore(e2e): surface bunyip body on OIDC authorize non-3xx
868658cfix(e2e): skip parent-domain derivation for IP literals
0368bfffeat(e2e): un-fixme OIDC token-flow via replayed OP cookies (PMS-143)
853f9a1Merge pull request 'test(e2e): re-fixme auth-ui pending PMS-148 login race' (#131) from fix/pms-148-refixme-auth-ui into main
82418fctest(e2e): re-fixme auth-ui pending PMS-148 login race
3e34835Merge pull request 'feat(e2e): un-fixme auth-ui login + logout round-trip (PMS-142 v2)' (#130) from feat/pms-142-auth-ui-unfixme-v2 into main
9b3cfe1feat(e2e): un-fixme auth-ui login + logout round-trip (PMS-142 v2)
5f850e7Merge pull request 'chore(build): bump rust-builder-glibc to v1.0.1' (#127) from chore/bump-rust-builder-glibc-v1.0.1 into main
0b7e68eMerge branch 'main' into chore/bump-rust-builder-glibc-v1.0.1
5b184d2Merge pull request 'feat(reports): GET /reports registry + integration tests (PMS-146)' (#129) from feat/pms-146-reports-registry-and-tests into main
73e8682feat(reports): add GET /reports registry + integration tests (PMS-146, closes PMS-93 gaps)
cc4dcbdMerge pull request 'feat(assets): audited secret reveal, no plaintext in lists, tests (PMS-71)' (#128) from feat/pms-71-asset-secret-reveal-and-tests into main
10b3760feat(assets): stop leaking secrets in lists; add audited reveal endpoints + tests (PMS-71)
78672aechore(build): bump rust-builder-glibc to v1.0.1
aac7c96Merge pull request 'feat(projects): budget-vs-actual + time rollup + tests (PMS-51)' (#126) from feat/pms-51-project-actuals-and-tests into main
5dc8acdfeat(projects): compute budget-vs-actual, roll approved time into actuals, add tests (PMS-51)
56e0a18Merge pull request 'feat(portal): wire company-scoped invoices + add portal isolation tests (PMS-25)' (#125) from feat/pms-25-portal-invoices-and-tests into main
7e0f275feat(portal): wire company-scoped invoices + add portal isolation tests (PMS-25)
bcf6f01Merge pull request 'chore: Sync .gitignore' (#124) from chore/sync-gitignore into main
86bbecachore: Sync .gitignore
70e2ae4Merge pull request 'chore(e2e): capture access_token from /oauth2/token response, not just Bearer header' (#123) from chore/e2e-capture-spa-build-hash into main
160688dchore(e2e): capture access_token from /oauth2/token response, not just Bearer header
7619ecbMerge pull request 'chore(e2e): surface mokosh-apps SPA bundle hash in timeout diagnostic' (#122) from chore/e2e-capture-spa-build-hash into main
cdf46cechore(e2e): surface mokosh-apps SPA bundle hash in timeout diagnostic
63ab9c1Merge pull request 'fix(auth): JIT placeholder name no longer surfaces UUID fragments' (#121) from fix/jit-fallback-name-not-uuid-fragments into main
37fcc9cfix(auth): JIT placeholder name no longer surfaces UUID fragments
321520aMerge pull request 'feat(kb): one vote per user account for article ratings (toggle/switch)' (#120) from feat/kb-rating-per-user-votes into main
f2e670fstyle: cargo fmt
aeb0e56feat(kb): make article ratings one vote per user account
7a19fb6Merge pull request 'feat(billing): generate recurring invoices from contract items (PMS-64 AC5)' (#119) from feat/pms64-recurring-invoicing into main
a58c1dbMerge branch 'main' into feat/pms64-recurring-invoicing
4a4ec49Merge pull request 'feat(kb): serve portal KB feed only via the portal-authed route' (#118) from feat/portal-kb-feed-auth into main
bb0d8d2Merge branch 'main' into feat/portal-kb-feed-auth
98ec545Merge pull request 'feat(notifications): backfill default rules for pre-existing tenants' (#117) from feat/notifications-seed-existing-tenants into main
0f837bestyle: apply cargo fmt
a1747d4style: apply cargo fmt
bd72ab6style: apply cargo fmt
e266dcafeat(billing): generate recurring invoices from contracts (PMS-64 AC5)
de3ebfffeat(kb): serve portal KB feed only via portal-authed route
d03ff7ffeat(notifications): backfill default worker rules for existing tenants
0c620dcMerge pull request 'fix(api): repair list ORDER BY misuse + time-entries count placeholders (PMS-145)' (#116) from fix/pms-145-time-entries-count-placeholders into main
df0ce4bfix(api): repair list ORDER BY misuse + time-entries count placeholders
66a1da9Merge pull request 'fix(ci): cap integration-test parallelism to dodge sqlx-test pool timeout' (#115) from fix/check-pg-pool-saturation into main
d531f38Merge pull request 'feat(e2e): close PMS-142 - un-fixme the auth-ui login + logout round-trip' (#112) from feat/pms-142-auth-ui-unfixme into main
eea87f3fix(ci): cap integration-test parallelism to dodge sqlx-test pool timeout
02c30e0Merge pull request 'fix(billing): gate invoicing on timesheet approval (PMS-144)' (#114) from fix/pms-144-billing-approval-gate into main
4bd93f4fix(billing): gate invoicing on timesheet approval (ready_to_bill)
d9abe84Merge pull request 'feat(dev-sso): validate bunyip-issued tokens as a Resource Server' (#113) from feat/dev-sso-rs-trust-bunyip into main
b6d9619test(e2e): re-quarantine auth-ui - bunyip /logout does not kill OP session
ce25821feat(dev-sso): validate bunyip-issued tokens as a Resource Server
8c50b19test(e2e): tighten page-diagnostics API + use Error cause for original stack
826e5b4feat(e2e): close PMS-142 - un-fixme the auth-ui login + logout round-trip
c94e090Merge pull request 'feat(ci): close PMS-141 - promote E2E to merge gate on PRs to main' (#111) from feat/pms-141-e2e-merge-gate into main
ae35028feat(ci): close PMS-141 - promote E2E suite to merge gate on PRs to main
b60a8d3Merge pull request 'test(e2e): quarantine OIDC token-flow test - needs OP session cookie' (#110) from fix/e2e-oidc-fixme into main
bfa3945test(e2e): quarantine OIDC token-flow test - needs OP session cookie
cab7078Merge pull request 'fix(e2e): point OIDC test at the OP host, quarantine auth-ui round-trip' (#109) from fix/e2e-oidc-op-base-url-and-auth-ui-fixme into main
dc5019edocs(e2e): refresh stale comments + README harness description
718e6bbfix(e2e): point OIDC test at the OP host, quarantine auth-ui round-trip
d9d3084Merge pull request 'fix(e2e): capture bearer from ANY host, not just /api/v1' (#108) from fix/e2e-capture-bearer-any-host into main
8a69f3ffix(e2e): capture bearer from ANY host, not just /api/v1
95637bdMerge pull request 'fix(ci): pass E2E_TOTP_SECRET secret into the E2E job env' (#107) from fix/e2e-wire-totp-secret into main
5bcaf8dfix(ci): pass E2E_TOTP_SECRET secret into the E2E job env
319f8d2Merge pull request 'feat(e2e): enter TOTP second factor during SPA login' (#106) from feat/e2e-totp-handling into main
1a9e37efeat(e2e): enter TOTP second factor during SPA login
4d46bf6Merge pull request 'fix(e2e): treat /login/* as still IN the login flow' (#105) from fix/e2e-login-pathname-anchor into main
88c274bfix(e2e): treat /login/* (e.g. /login/2fa) as still IN the login flow
a90fbfbMerge pull request 'test(e2e): dump full URL/trail/request diagnostic when setup times out' (#104) from fix/e2e-bearer-diagnostics into main
b30dc74test(e2e): dump full URL/trail/request diagnostic when setup times out
a383fb1Merge pull request 'fix(e2e): probe data routes for bearer, merge auth-ui to dodge rate limit' (#103) from fix/e2e-spa-bearer-intercept-and-logout into main
66e3433test(e2e): harden auth-ui locators with .first(), tighten /api/v1 filter
de17374fix(e2e): force a post-login probe + merge auth-ui tests to dodge rate limit
29d2eb8Merge pull request 'fix(e2e): intercept SPA bearer for setup, click User-menu -> Logout' (#102) from fix/e2e-spa-bearer-intercept-and-logout into main
30d66a9test(e2e): refresh auth-state comment, drop dead routes.authLogin
328ffbcfix(e2e): intercept SPA bearer for setup, click User-menu -> Logout
4b01eefMerge pull request 'fix(ci): wait-for-deploy refetches missing trees, skips gate if unresolvable' (#101) from fix/e2e-wait-deploy-skip-when-unresolvable into main
9c73dd1fix(ci): wait-for-deploy refetches missing trees, skips gate if unresolvable
6bf0e9aMerge pull request 'fix(ci): wait-for-deploy unshallows the clone when git log returns empty' (#100) from fix/e2e-wait-deploy-unshallow into main
efea598fix(ci): wait-for-deploy unshallows the clone when git log returns empty
d47d72aMerge pull request 'fix(ci): resolve deploy-sync expected SHA to the last build-relevant commit' (#99) from fix/e2e-runner-toolcache into main
6040838fix(ci): resolve deploy-sync expected SHA to the last build-relevant commit
8924692Merge pull request 'test(e2e): aggregate-all-missing env vars in a preflight setup project' (#98) from fix/e2e-runner-toolcache into main
104ed55test(e2e): aggregate-all-missing env vars in a preflight setup project
99738adMerge pull request 'fix(ci): bake MOKOSH_GIT_HASH + describe + date into OCI build' (#97) from fix/e2e-runner-toolcache into main
52742c6fix(ci): bake MOKOSH_GIT_HASH + describe + date into OCI build
256d17fMerge pull request 'fix(ci): API host is api.msp., not msp-api.' (#96) from fix/e2e-runner-toolcache into main
3adb4a2fix(ci): API host is api.msp., not msp-api.
9d8b11aMerge pull request 'fix(ci): split E2E SPA host from API host, derive msp-api.' (#95) from fix/e2e-runner-toolcache into main
3883fc8fix(ci): split E2E SPA host from API host, derive msp-api.
80a160eMerge pull request 'fix(ci): treat empty E2E_BASE_URL as missing, not as override' (#94) from fix/e2e-runner-toolcache into main
0de6163fix(ci): treat empty E2E_BASE_URL as missing, not as override
e965450Merge pull request 'fix(ci): drop playwright --with-deps - opensuse runner has no apt-get' (#93) from fix/e2e-runner-toolcache into main
21ca57ffix(ci): drop playwright --with-deps - opensuse runner has no apt-get
78ed118Merge pull request 'fix(ci): hardcode RUNNER_TOOL_CACHE path - runner context unbound in job env' (#92) from fix/e2e-runner-toolcache into main
020631bfix(ci): hardcode RUNNER_TOOL_CACHE path - runner context unbound in job env
3f8c2a4Merge pull request 'fix(ci): point E2E setup-node tool cache at RUNNER_TEMP' (#91) from fix/e2e-runner-toolcache into main
55eb53cfix(ci): point E2E setup-node tool cache at RUNNER_TEMP
aadb3bbMerge pull request 'PMS-140: Add Playwright E2E suite against staging, run on every merge to main' (#90) from feat/pms-140-e2e-playwright into main
01a4d7dtest(e2e): fix auth path, require OIDC redirect, harden teardown and CI
b4ccc9atest(e2e): add Playwright suite against staging, run post-merge to main
0c39d1eMerge pull request 'feat(auth): close PMS-138 - subdomain-driven tenant hint on login + forgot-password + Google JIT' (#89) from feat/pms-138-closeout into main
c7d40edfeat(auth): close PMS-138 - subdomain-driven tenant hint on login + forgot-password + Google JIT
4b4c1f4Merge pull request 'fix(settings): drop legacy DELETE /settings/{id} - matchit conflict with /settings/{category}' (#88) from fix/settings-route-conflict into main
a0d3d91fix(settings): drop legacy DELETE /settings/{id} - matchit conflict with /settings/{category}
934f96aMerge pull request 'feat(settings): close PMS-113 - unify module-config, add category endpoints + value validation, gate optional modules at runtime' (#87) from feat/pms-113-closeout into main
606ba79feat(settings): close PMS-113 - unify module-config, add category endpoints + value validation, gate optional modules at runtime
63a1bfcMerge pull request 'feat(tenants): close PMS-21 - cfg-gate cleanup + module-config and cross-tenant tests' (#86) from feat/pms-21-closeout into main
272d179feat(tenants): close PMS-21 - cfg-gate cleanup + module-config and cross-tenant tests
7a34463Merge pull request 'fix(list-queries): correct WHERE param numbering for count_query in 6 list_* methods' (#85) from fix/list-count-query-param-mismatch into main
6acbb23fix(list-queries): correct WHERE param numbering for count_query in 6 list_* methods
68580e0Merge pull request 'fix(migrations): rename PMS-4 recovery-codes migration 027 -> 029 (version collision with PMS-106)' (#84) from fix/migration-027-collision into main
7edbf13fix(migrations): rename PMS-4 recovery-codes migration 027 -> 029 (version collision with PMS-106)
4d995d4Merge pull request 'feat(auth): close PMS-4 - list filter, layered rate limit, MFA recovery codes, tenant hardening' (#83) from feat/pms-4-closeout into main
387e18dMerge pull request 'feat(calendar): appointment reminders worker (PMS-58)' (#81) from feat/pms-58-calendar-reminders into main
e922e0fMerge branch 'main' into feat/pms-58-calendar-reminders
d00c3d0Merge remote-tracking branch 'origin/main' into feat/pms-58-calendar-reminders
6a0e444Merge pull request 'feat(audit): record billing + contracts mutations in the audit log (PMS-117)' (#82) from feat/pms-117-audit-hooks into main
be05264Merge branch 'main' into feat/pms-117-audit-hooks
ef0ffbffeat(audit): record billing + contracts mutations in the audit log (PMS-117)
35704a5Merge pull request 'feat(sla): at-risk + breach notifications via sweep worker (PMS-106)' (#80) from feat/pms-106-sla-notify into main
1d020fbfeat(calendar): appointment reminders worker (PMS-58)
d25444bfeat(auth): close PMS-4 - list filter, layered rate limit, MFA recovery codes, tenant hardening
e1244a0feat(sla): at-risk + breach notifications via sweep worker (PMS-106)
242360aMerge pull request 'feat(calendar): RRULE expansion + dispatch view (PMS-58)' (#77) from feat/pms-58-calendar into main
8874be8Merge branch 'main' into feat/pms-58-calendar
bdcb4d5Merge pull request 'feat(contracts): hour-balance consumption, rate resolution, lifecycle (PMS-64)' (#75) from feat/pms-64-contracts into main
0fd9124Merge remote-tracking branch 'origin/main' into feat/pms-58-calendar
39950bfMerge remote-tracking branch 'origin/main' into feat/pms-64-contracts
269c79dMerge pull request 'feat(kb): publish lifecycle, slug uniqueness, version restore, trigram search, feedback, portal feed (PMS-79)' (#78) from feat/pms-79-kb into main
89fd6fdMerge branch 'main' into feat/pms-79-kb
dbf8c91feat(kb): publish lifecycle, slug uniqueness, version restore, trigram search, feedback, portal feed (PMS-79)
f1d7e99Merge pull request 'feat(billing): generate invoices from billable time entries (PMS-33)' (#76) from feat/pms-33-billing into main
c7884b1Merge branch 'main' into feat/pms-33-billing
025f6d3Merge pull request 'feat(sla): business-hours-aware SLA clock engine (PMS-106)' (#72) from feat/pms-106-sla-clock into main
bc9e86aMerge branch 'main' into feat/pms-106-sla-clock
1cff709Merge pull request 'feat(audit): record entity mutations + auth events (PMS-117)' (#70) from feat/pms-117-audit-log into main
d5e9b1bfeat(calendar): RRULE expansion + dispatch view (PMS-58)
ba69f11Merge remote-tracking branch 'origin/main' into feat/pms-64-contracts
d807030Merge remote-tracking branch 'origin/main' into feat/pms-106-sla-clock
f7f08c1Merge remote-tracking branch 'origin/main' into feat/pms-117-audit-log
7396d1bfeat(billing): generate invoices from billable time entries (PMS-33)
9c14ffafeat(contracts): hour-balance consumption, rate resolution, lifecycle (PMS-64)
a3ebcd0Merge pull request 'test(pms-11): cover assign + assert JOINed ticket DTO fields (F3)' (#73) from feat/pms-11-tickets-assign-joined-fields-test into main
fca3248Merge pull request 'fix(contacts): make update_company and update_contact persist every UpdateRequest field' (#74) from feat/pms-17-tests into main
ef5af80test(pms-11): cover assign + assert JOINed ticket DTO fields (F3)
3bbf1e5fix(contacts): make update_company and update_contact persist every UpdateRequest field
6bd23e4feat(sla): business-hours-aware SLA clock engine (PMS-106)
e489d7aMerge pull request 'test(pms-17): integration tests pinning F4 fix + site/contact CRUD + portal flag + F9 filter' (#71) from feat/pms-17-tests into main
e1aec1atest(pms-17): integration tests pinning F4 fix + site/contact CRUD + portal flag + F9 filter
708d322feat(audit): record entity mutations + auth events in the audit log
a305bcaMerge pull request 'feat(scheduler): shared background-job runner (PMS-135)' (#69) from feat/pms-135-scheduler into main
3895e17fix(scheduler): address code-review findings on shared scheduler (PMS-135)
887dbd7feat(scheduler): shared background-job runner (PMS-135)
0d4c473Merge pull request 'feat(api): readiness probe at /api/v1/ready (PMS-130)' (#68) from feat/pms-130-readiness into main
bbe9855fix(api): address code-review findings on /ready (PMS-130)
6174aa4feat(api): readiness probe at /api/v1/ready (PMS-130)
69364fcMerge pull request 'feat(types): extract shared DTOs into mokosh-types workspace crate (PMS-129)' (#67) from feat/pms-129-mokosh-types into main
99ca90efix(types): add serde_json dep + refresh Cargo.lock for new crate (PMS-129)
02fa99ffix(types): replace AppError reference with crate-local AuthRequired marker (PMS-129)
5454f62feat(types): extract shared DTOs into a mokosh-types workspace crate (PMS-129)
e24ff59Merge pull request 'feat(migrations): split 1688-line initial schema into per-feature files (PMS-128)' (#66) from feat/pms-128-migration-split into main
813c1c1feat(migrations): split 1688-line initial schema into per-feature files (PMS-128)
666913fMerge pull request 'feat(api): paginate every list handler (PMS-127)' (#65) from feat/pms-127-pagination into main
a03bfffdocs(pagination): clarify audit-log cap drop + dual-Query convention
91e1a40feat(api): route every list handler through utils/pagination (PMS-127)
46a45a1Merge pull request 'feat(tracing): named instrument spans on every service method (PMS-126)' (#64) from feat/pms-126-tracing-spans into main
529e778feat(tracing): add named instrument spans on every service method (PMS-126)
6c80f4cMerge pull request 'feat(router): self-documenting 501 body for placeholder modules (PMS-125)' (#63) from feat/pms-125-stub-bodies into main
d5044c0style: allow dead_code on common::{seed_admin,login} for unauthenticated test binaries
d8ae8afstyle: rewrap assert! to satisfy rustfmt in dispatch_stub test
0940a9dstyle: reflow long lines for rustfmt in PMS-125 stub
f421318feat(router): self-documenting 501 body for placeholder modules (PMS-125)
bf5c42aMerge pull request 'feat(rmm): device-sync worker, provider trait, suppression + dedupe (PMS-103)' (#62) from feat/pms-103-rmm-sync-worker into main
0dfea6dstyle: drop unused RmmService accessor methods
6aefab3style: apply rustfmt to PMS-103 rmm sync worker work
1840992feat(rmm): sync worker, provider trait, prefs/dedupe, encryption key wire-up
9889f59Merge pull request 'feat(notifications): dispatcher worker, prefs, encryption (PMS-92)' (#61) from feat/pms-92-notifications-dispatcher into main
09e5435style(tests): factor notifications row tuple into NotifRow alias
4f43203style: blank line between bullet list and paragraph in dispatch doc
76a54d7style: apply rustfmt to PMS-92 notifications dispatcher work
d3717d4feat(notifications): dispatcher worker, preference enforcement, encryption key wire-up
98d3aa7Merge pull request 'fix(auth): seed first_name/last_name defaults on bunyip JIT user upsert' (#60) from feat/jit-user-name-defaults into main
7dceaf6fix(auth): seed first_name/last_name defaults on bunyip JIT user upsert
d775285Merge pull request 'feat(contacts): populate CompanyResponse rollup fields' (#59) from feat/crm-ops into main
abc2bc4feat(contacts): populate CompanyResponse rollup fields
7747fb4Merge pull request 'feat(time-tracking): rounding, rate derivation, timesheet approval, tenant scoping' (#58) from feat/time-tracking-resolve-rounding into main
d0acbb5feat(time-tracking): apply rounding, derive rates, add timesheet approval + tenant scoping
248e135Merge pull request 'fix/dev-sso-private-network-name' (#57) from fix/dev-sso-private-network-name into main
dd34ae9fix(dev): drop server's depends_on infisical so compose project is valid
0aaa5f2fix(dev-sso): match overlay private network name to base per-user name
87cac87Merge pull request 'style(tests): rustfmt wrap on hash_password call' (#56) from fix/pms-124-fmt-wrap into main
81a294cfix(tickets): cast sla_targets DECIMAL columns to float8 for sqlx decode
fb96025test(common): init tracing subscriber so the real sqlx error surfaces
2de1bd8fix(tests): sendcustom_fields: {}on create ticket, surface error body
81487c8fix(ci): point DATABASE_URL at the postgres service name, not localhost
c4727dcstyle(tests): allow dead_code on per-binary-unused common items
e56e42astyle(tests): rustfmt wrap on hash_password call
cc5f7c3Merge pull request 'feat(tests): module-level integration tests for real route groups (F10)' (#55) from feat/pms-124-integration-tests into main
806312ffix(tests): authenticate via Authorization: Bearer, not a cookie jar
d172c15feat(tests): module-level integration tests for real route groups (F10)
3b62355Merge pull request 'feat(api): add length validation to all Filter query types (F9)' (#54) from feat/pms-123-filter-validate into main
7b67a7adocs(kb): note ILIKE cap rationale on KbArticleFilter.q
b7c612ffeat(api): add length validation to all Filter query types (F9)
53450bfMerge pull request 'style(auth): cargo fmt oidc_rs.rs' (#53) from fix/oidc-rs-fmt into main
9c3dffdstyle(auth): cargo fmt oidc_rs.rs
52a790dMerge pull request 'feat/bunyip-op-cutover' (#52) from feat/bunyip-op-cutover into main
cae15d2feat(auth): wire bunyip RS verifier into AuthMiddleware
cf2ff21feat(auth): implement Resource-Server at+jwt verifier
8131438feat(auth): scaffold Resource-Server OIDC verifier (bunyip-as-OP cutover)
d351093Merge pull request 'feat/fix-just-dev-wont-start-infisical' (#51) from feat/fix-just-dev-wont-start-infisical into main
de6da3arewrite comment for dev-down and dev-clean
d286b3afix comment
ef1649aadd start infisical recipe
0b3727cadd tag
eabf8e4Merge pull request 'fix(ci): generate release notes from commits since previous tag' (#50) from fix/release-notes-since-prev-tag into main
dd7f0fdfix(ci): generate release notes from commits since previous tag
5b5eef0Merge pull request 'fix/db-migrations-in-app' (#49) from fix/db-migrations-in-app into main
0c9a066WIP: Build on every push
3d2b51aWIP: Build on every push
82b3044WIP: Build on every push
562f8e4fix(migrations): move mokosh_auth schema/columns into app migrations
9b551afMerge pull request 'PSA audit: auth + tenancy security fixes' (#48) from feat/m1-vas into main
dc202a9fix(test): bind reset-token strings before borrowing (E0716)
1b2568efix(router): use api.msp host prefix in not_a_frontend fallback
033b6bcstyle: cargo fmt --all
92c485etest(auth): unit-test reset-token parsing + super-admin email allowlist
ddaaeebci: publish the server image as mokosh-server (single name)
6f406d3ci: publish the server image as both mokosh-server and mokosh-api
71e65cefix(db): parameterize RLS tenant GUC; drop ineffective with_tenant
1d5ac98feat(auth): harden Google OAuth (verified-email link, email allowlist, fail-closed)
5e0af57fix(tenancy): validate cross-tenant foreign keys on create/update
bd1d794fix(auth): bind reset tokens to user; gate sign-in on tenant status
6c50a88Merge pull request 'fix(dev-sso): route Traefik labels on Compose 2.40 + shared Traefik' (#47) from fix/dev-sso-traefik-label-interpolation into main
d13ba40fix(dev-sso): route Traefik labels correctly on Compose 2.40 + shared Traefik
c170baaMerge pull request 'docs: quickstart for fresh clones + CLAUDE.md' (#46) from docs/quickstart into main
a05771adocs: add quickstart for fresh clones, plus CLAUDE.md
e1ddf6fMerge pull request 'fix(ci): trigger image build on crates/ edits + add manual dispatch' (#45) from fix/ci-trigger-crates into main
6cb9513fix(ci): trigger image build on crates/** edits + add manual dispatch
3fdc0efMerge pull request 'feat(ci): use $RUNNER_TEMP instead of /tmp in claude-fix workflow' (#44) from feat/pms-132-no-tmp into main
bcd0990feat(ci): guard against unset RUNNER_TEMP before using it
54f1941feat(ci): use $RUNNER_TEMP instead of /tmp in claude-fix workflow
11fc65bMerge pull request 'fix(clippy): use ok_or instead of ok_or_else for plain HttpError values' (#43) from fix/clippy-sessions-ok-or into main
1f83ca5fix(clippy): use ok_or instead of ok_or_else for plain HttpError values
d2e9177Merge pull request 'Implementing SSO, OIDC (All auth)' (#42) from feature-sso into main
09751b3Merge remote-tracking branch 'origin/main' into feature-sso
ce3f90ffeat(oidc): fan back-channel logout out on RP-initiated /oauth2/logout
93883edfeat(extractor): BearerUser rejects tokens from revoked op_sessions
0b99014feat(auth): emit back-channel logout to every registered RP on /v1/auth/logout
97af972Merge pull request 'feat(justfile): fj-driven create-release + group attrs (DEV-331)' (#41) from feat/justfile-fj-pr-create-DEV-331 into main
778a440feat(justfile): fj-driven create-release + group attrs (DEV-331)
4353d52log 5xx errors with underlying AuthError detail
8a0b75fMerge pull request 'feat: consolidate PMS server PRs (PMS-4..PMS-131)' (#40) from feat/pms-merge into main
9fa4c00fix(clippy): resolve remaining workspace clippy warnings for -D warnings
ff7413dfix(clippy): apply machine-applicable clippy suggestions
0db5161style: cargo fmt --all; suppress two pre-existing clippy lints in mokosh-auth-core
01ebd03ci(check): add fmt + clippy + compile + tests workflow
01aefb8Merge remote-tracking branch 'origin/chore/claude-fix-workflow' into feat/pms-merge
13d5ddaMerge remote-tracking branch 'origin/feat/audit-story-pms-117' into feat/pms-merge
52ad3acMerge remote-tracking branch 'origin/feat/settings-story-pms-113' into feat/pms-merge
be878e7Merge remote-tracking branch 'origin/feat/sla-story-pms-106' into feat/pms-merge
0862e7fMerge remote-tracking branch 'origin/feat/rmm-story-pms-100' into feat/pms-merge
d1d4efbMerge remote-tracking branch 'origin/feat/reports-story-pms-93' into feat/pms-merge
a057e56Merge remote-tracking branch 'origin/feat/notifications-story-pms-85' into feat/pms-merge
6023551Merge remote-tracking branch 'origin/feat/kb-story-pms-79' into feat/pms-merge
c415e73Merge remote-tracking branch 'origin/feat/assets-story-pms-71' into feat/pms-merge
b718b3fMerge remote-tracking branch 'origin/feat/contracts-story-pms-64' into feat/pms-merge
236e484Merge remote-tracking branch 'origin/feat/calendar-story-pms-58' into feat/pms-merge
62b9643Merge remote-tracking branch 'origin/feat/projects-story-pms-51' into feat/pms-merge
b239c93Merge remote-tracking branch 'origin/feat/time-tracking-story-pms-42' into feat/pms-merge
c166d47Merge remote-tracking branch 'origin/feat/billing-story-pms-33' into feat/pms-merge
7ea90afMerge remote-tracking branch 'origin/feat/portal-story-pms-25' into feat/pms-merge
40d26acMerge remote-tracking branch 'origin/feat/tenants-story-pms-21' into feat/pms-merge
66f1da3Merge remote-tracking branch 'origin/feat/contacts-story-pms-17' into feat/pms-merge
e957286Merge remote-tracking branch 'origin/feat/tickets-story-pms-11' into feat/pms-merge
a35b3f0Merge remote-tracking branch 'origin/feat/auth-story-pms-4' into feat/pms-merge
e2fb8b2ci: add claude-fix workflow
47b3574fix(justfile): register lets-chat with per-provider redirect_uri slug
02deaedfeat(audit): scaffold + writer middleware + read endpoint
43b1c1ffeat(settings): scaffold + tenant settings + module configs
f4a2d8afeat(sla): scaffold + policies, targets, business hours, holidays, evaluator
ff4b78efeat(rmm): scaffold + connections, device mappings, alert rules, ingest
25ea790feat(reports): scaffold + dashboard, tickets, time, billing, CSV export
fe702ccfeat(notifications): scaffold + channels, templates, prefs, inbox, rules, dispatcher
d1812eafeat(kb): scaffold + categories, articles, versioning, portal feed
ffce981feat(assets): scaffold + asset types, assets, relationships, CIs, credentials, audit
7298b90feat(contracts): scaffold + CRUD for contracts, items, balances, rate cards
24ddf81feat(calendar): scaffold + appointments, availability, time-off, on-call
96ce98bfeat(projects): scaffold + projects, phases, task statuses, tasks, dependencies
adaa594feat(time-tracking): implement work types, time entries, timesheets, timers, rounding rules
cefa9acfeat(time-tracking): scaffold module + wire router (PMS-43)
f31778bfeat(billing): tax rates CRUD + jurisdiction lookup
81da537feat(billing): payment gateway configs CRUD with at-rest encryption
d3de7f1feat(billing): payments CRUD with invoice-status reconciliation
e67030cfeat(billing): PUT /api/v1/invoices/:id with frozen-status guard
47a0ae4feat(billing): POST /api/v1/invoices with atomic sequence + line items
44e178ffeat(billing): GET /api/v1/invoices/:id with lines
04e89defeat(billing): GET /api/v1/invoices paginated + filterable (F7)
5105a8afeat(billing): scaffold module + wire router (PMS-34)
fed6a72feat(portal): GET /api/v1/portal/kb placeholder pending PMS-79
28775fcfeat(portal): GET /api/v1/portal/invoices/:id placeholder pending PMS-33
73d99e2feat(portal): GET /api/v1/portal/invoices placeholder pending PMS-33
ab0b9f2feat(portal): GET /api/v1/portal/tickets/:id with cross-company 404
60488bcfeat(portal): GET /api/v1/portal/tickets lists company-scoped tickets
b06c6b0feat(portal): POST /api/v1/portal/tickets creates contact-scoped ticket
c1d6b7afeat(portal): contact-scoped session + portal auth middleware (F6)
c38cdeafeat(router): gate /api/v1/tenants behind the multi-tenant feature
3bcfe6ffeat(auth): TenantScope extractor for explicit tenant-id propagation
2b634abchore(router): drop the dead /companies alias
e00a272feat(contacts): honor create_portal_access on create_contact
06de4abfeat(tickets): dispatch notifications + webhooks from automation rules
7bb0df5feat(tickets): send email when add_note has send_email = true
eaf66dbfix(tickets): join lookup tables into TicketResponse (F3)
e90708cfeat(auth): personal API key CRUD (issue / list / revoke)
3a9cb3ffeat(auth): implement MFA TOTP verification + enrollment endpoints
8ce5238feat(auth): send welcome email on admin user creation
d67f8bffeat(auth): send password reset email via Mailer trait
e2eff78Merge pull request 'Revert M1 image distribution work' (#19) from revert/m1-image-distribution into main
b573fc4Revert M1 image distribution work
848fcc3Merge pull request 'ci: fix QEMU binfmt registration for arm64 cross-build' (#18) from feat/m1-image-distribution into main
fa7ab7dci: fix QEMU binfmt registration for arm64 cross-build
89d19f4Merge pull request 'ci: register QEMU binfmt inline instead of via setup-qemu-action' (#17) from feat/m1-image-distribution into main
a74fbd5ci: register QEMU binfmt inline instead of via setup-qemu-action
2444c15Merge pull request 'feat/m1-image-distribution' (#16) from feat/m1-image-distribution into main
36b647edocs(operator): document container registry auth for self-hosters
fcb323efeat(m1): operator compose.yml + update check + multi-arch build
dc17aeeMerge pull request 'fix(oci): drop image.source label causing dual-org package listing' (#15) from fix/drop-oci-source-label into main
87a85b6fix(oci): drop image.source label causing dual-org package listing
bc546f0chore(justfile): add register-lets-chat-client recipe (sso M1)
a253ef3feat(users): protect Owner memberships from other admins
c097ae3fix(auth): switch_active_tenant rebinds new token to caller's op_session
8ac097afeat(audit): filter extensions + CSV export (item 7 server)
e0575bdfeat(sessions): admin endpoints to list+revoke another user's sessions
139d71bMerge pull request 'feat: multi-origin CORS + msp-api placeholder + calendar route stub' (#14) from feat/cors-multi-origin-and-placeholder into main
7beb7a4security: stop tracking .env.dev; gitignore future copies
4fb15b2docs: milestone-1 handoff for the PSA Systems v0.1.0 cutoverDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)