Skip to content

Release v5.20.0 - #871

Merged
evilguy4000 merged 49 commits into
mainfrom
rc/v5.20.0
Nov 10, 2026
Merged

evilguy4000 merged 49 commits into
mainfrom
rc/v5.20.0

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Release 5.20.0

Automated release candidate cut from develop.

Checklist

  • CI is green (ci-pass)
  • CHANGELOG looks correct
  • Migrations reviewed (if any)

Notes

Added

  • Enterprise identity — OAuth 2.0 API apps (authorization code + PKCE, admin CRUD), SAML 2.0 login, SCIM Users provisioning, and shared Slack/Teams timer bot commands.
  • Bank reconciliation & payroll — Bank reconciliation workflows plus payroll/labor export APIs and UI.
  • Inventory — Stock locations, purchase-order email, and stock-levels CSV export.
  • Invoicing — XRechnung export and PDF QR/barcode elements on invoice/quote layouts.
  • Peppol bridge: Let’s Peppol + inbox — PEPPOL_BRIDGE_PROVIDER=letspeppol for Belgian access-point delivery, plus inbound Peppol inbox poll/ack in the bridge and admin UI.
  • Kanban & custom fields — Enforce kanban WIP limits; extend custom fields coverage.
  • Clients — Mobile sync retry backoff and failed-sync screen; desktop failed offline-sync surfacing and broader i18n; browser extension 2FA login, Firefox packaging, and tab URL suggestions.
  • DigitalOcean one-click — .do/deploy.template.yaml (Docker Hub image + Dev Database) and Deploy to DigitalOcean button in the README / Distribution guide.
  • Unraid CA profile — Root ca_profile.xml (CommunityApplications + <Profile>) required for Community Applications submission.

Security

  • CodeQL — Clear open redirect, stack-trace, weak-hashing, and XML-related alerts on develop paths used by auth/OAuth and related utilities.

Fixed

  • Invoices — Generating an invoice from many time entries no longer fails on PostgreSQL: invoice_items.time_entry_ids is now TEXT (was VARCHAR(500)).
  • Report export — CSV and Excel exports from the report form now apply the client, task, billable, source and tags filters.
  • Payments — Stripe checkout now sends JPY and other zero-decimal currencies (and three-decimal ones such as KWD) in the unit Stripe expects; before, every amount was multiplied by 100, so a JPY invoice was charged 100 times its balance, and the webhook amount was divided by 100 the same way.
  • Peppol — The UBL invoice now reports payments already recorded on the invoice as PrepaidAmount and sets PayableAmount to the total minus those payments (BR-CO-16), never below zero, as the Factur-X/ZUGFeRD export already does; before, a partly paid invoice sent or exported as UBL asked the buyer for the full total.
  • CI / Docker — Restore gunicorn 25.x (eventlet worker) after a major bump broke image boot; isolate setup-wizard fixture state; use push before SHA for migration drift; keep mobile on Riverpod 2.x.

Changed

  • Mobile Android — Bump Gradle wrapper to 8.14 so Flutter 3.47 release builds satisfy the minimum Gradle version.
  • Dependencies — Pip, Actions, npm (root + desktop), and Flutter mobile dependency bumps (with Dependabot major ignores for gunicorn and flutter_riverpod).

Documentation

  • OrcaRouter — AI Helper docs and Admin settings include a signup link for an OrcaRouter API key (https://www.orcarouter.ai/ref/ref_984e584cb4cd86485a8c).
  • Deploy & discovery — DigitalOcean and Railway deploy guides; Unraid CA + directory listing submission packages; publishing checklist (docs/deploy/*, docs/marketing/*).
  • Gap roadmap — Archive stale gap analyses; Phase 6 marked done for the implementation pass.

Merging this PR will tag v5.20.0, publish via CD - Release Build,
back-merge into develop, and delete rc/v5.20.0.

evilguy4000 and others added 30 commits November 7, 2026 07:47
chore: back-merge v5.19.1 into develop
Clarify that past-due handling is a one-shot daily job and that recurring templates generate drafts from unbilled time, and correct stale docs that still listed these as future work.
…mit.

Move ca_profile.xml to the repo root with a CommunityApplications Profile, drop the mistaken templates/unraid copy that CA flagged as a duplicate non-Container app, and document Railway/listing publish steps.
Default branches include AndroidManifest.xml which CA flags as not_unraid_application; point TemplateURLs at the clean branch.
Stripe takes amounts in the currency's smallest unit. Checkout and payment
intents multiplied every amount by 100 and the webhook divided by 100, so a
JPY invoice (the invoice currency comes from the free-text currency setting)
was charged 100 times its balance, and three-decimal currencies such as KWD
were charged a tenth. Convert with the currency's factor (1, 100 or 1000) in
both directions.
fix(payments): use the currency's minor unit for Stripe amounts
The Peppol UBL set PayableAmount (BT-115) to the invoice total and never
emitted PrepaidAmount (BT-113), so an invoice with a recorded payment was
sent or exported asking the buyer for the full total. The Factur-X/CII
export already subtracts amount_paid.

Emit PrepaidAmount when payments are recorded and set PayableAmount to
TaxInclusiveAmount - PrepaidAmount (BR-CO-16). As in the CII export, the
amount due is never negative; here the prepaid amount is capped at the
total so BR-CO-16 holds, and an overpayment is therefore not shown in
full in PrepaidAmount.
fix(peppol): report recorded payments as PrepaidAmount in the UBL
Point REQUIREMENTS and competitive rubric at the live roadmap so planning docs stop overstating shipped work.
…tions

Complete password login when the API requires TOTP, ship a Firefox zip target, and optionally suggest a project from the active tab URL.
Let users retry or discard failed queue entries, show a badge when sync problems exist, and wire key shell strings through the locale catalog.
Match desktop offline queue limits with attempts, exponential backoff, and retry/discard so stalled timer ops stop looping forever.
Block status moves that would exceed column WIP, and render/save custom fields on tasks and time entries as well as projects.
Build CIUS-DE XRechnung from Peppol UBL with Leitweg-ID validation, and render QR/Code128 including EPC SEPA payloads in the PDF designer.
…xport

Expose warehouse location on adjust/transfer forms and give operators email/PDF and CSV actions for day-to-day stock work.
… Teams bot commands

Turn Phase 5 identity stubs into working flows: Authlib-style authorize/token with tto_ API tokens, SAML ACS via shared external identity provisioning, SCIM Users CRUD, and Slack/Teams slash commands through one service.
…nd route-size CI

Expose gantt, workflows, resource scheduling, and team chat on API v1; make payroll exports template-aware with labor-compliance presets; import CAMT/CSV bank statements for invoice matching; and soft-fail CI when new route modules grow past 2500 lines.
Bumps the npm-desktop group in /desktop with 3 updates: [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react), [electron](https://github.com/electron/electron) and [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `@vitejs/plugin-react` from 6.1.2 to 6.2.1
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.2.1/packages/plugin-react)

Updates `electron` from 45.2.1 to 45.2.3
- [Release notes](https://github.com/electron/electron/releases)
- [Commits](electron/electron@v45.2.1...v45.2.3)

Updates `vite` from 8.3.5 to 8.3.6
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.3.6/packages/vite)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 6.2.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-desktop
- dependency-name: electron
  dependency-version: 45.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-desktop
- dependency-name: vite
  dependency-version: 8.3.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-desktop
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps the npm-root group with 2 updates: [@simonwep/pickr](https://github.com/simonwep/pickr) and [fullcalendar](https://github.com/fullcalendar/fullcalendar/tree/HEAD/packages/vanilla).


Updates `@simonwep/pickr` from 1.10.2 to 1.10.3
- [Release notes](https://github.com/simonwep/pickr/releases)
- [Commits](simonwep/pickr@v1.10.2...v1.10.3)

Updates `fullcalendar` from 7.1.3 to 7.1.4
- [Release notes](https://github.com/fullcalendar/fullcalendar/releases)
- [Changelog](https://github.com/fullcalendar/fullcalendar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fullcalendar/fullcalendar/commits/v7.1.4/packages/vanilla)

---
updated-dependencies:
- dependency-name: "@simonwep/pickr"
  dependency-version: 1.10.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-root
- dependency-name: fullcalendar
  dependency-version: 7.1.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-root
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps the pub-mobile group in /mobile with 1 update: [flutter_local_notifications](https://github.com/MaikuB/flutter_local_notifications).


Updates `flutter_local_notifications` from 22.3.3 to 23.0.0
- [Release notes](https://github.com/MaikuB/flutter_local_notifications/releases)
- [Commits](MaikuB/flutter_local_notifications@flutter_local_notifications-v22.3.3...flutter_local_notifications-v23.0.0)

---
updated-dependencies:
- dependency-name: flutter_local_notifications
  dependency-version: 23.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: pub-mobile
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps the github-actions group with 1 update: [softprops/action-gh-release](https://github.com/softprops/action-gh-release).


Updates `softprops/action-gh-release` from 3.0.3 to 3.0.4
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](softprops/action-gh-release@efb3536...8a0cd65)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 3.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Updates the requirements on [flask-socketio](https://code.miguelgrinberg.com/miguelgrinberg/flask-socketio), [authlib](https://github.com/authlib/authlib), [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy), [gunicorn](https://github.com/benoitc/gunicorn), [pytz](https://github.com/stub42/pytz), [markdown](https://github.com/Python-Markdown/markdown), [sentry-sdk](https://github.com/getsentry/sentry-python), [flask-swagger-ui](https://github.com/sveint/flask-swagger-ui), [apispec](https://github.com/marshmallow-code/apispec), [marshmallow](https://github.com/marshmallow-code/marshmallow), [coverage](https://github.com/coveragepy/coveragepy), [pytest-env](https://github.com/pytest-dev/pytest-env) and [types-python-dateutil](https://github.com/python/typeshed) to permit the latest version.

Updates `flask-socketio` from 5.7.1 to 5.7.2

Updates `authlib` from 1.9.2 to 1.9.5
- [Release notes](https://github.com/authlib/authlib/releases)
- [Commits](authlib/authlib@v1.9.2...v1.9.5)

Updates `sqlalchemy` from 2.1.6 to 2.1.8
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

Updates `gunicorn` from 25.3.0 to 26.2.0
- [Release notes](https://github.com/benoitc/gunicorn/releases)
- [Commits](benoitc/gunicorn@25.3.0...26.2.0)

Updates `pytz` to 2026.6
- [Release notes](https://github.com/stub42/pytz/releases)
- [Commits](stub42/pytz@release_2025.2...release_2026.6)

Updates `markdown` from 3.11.2 to 3.11.3
- [Release notes](https://github.com/Python-Markdown/markdown/releases)
- [Changelog](https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md)
- [Commits](Python-Markdown/markdown@3.11.2...3.11.3)

Updates `sentry-sdk` from 2.73.0 to 2.74.0
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](getsentry/sentry-python@2.73.0...2.74.0)

Updates `flask-swagger-ui` from 5.34.0 to 5.34.1
- [Release notes](https://github.com/sveint/flask-swagger-ui/releases)
- [Commits](sveint/flask-swagger-ui@v5.34.0...v5.34.1)

Updates `apispec` from 6.10.0 to 6.10.1
- [Changelog](https://github.com/marshmallow-code/apispec/blob/dev/CHANGELOG.rst)
- [Commits](marshmallow-code/apispec@6.10.0...6.10.1)

Updates `marshmallow` from 4.3.1 to 4.4.0
- [Changelog](https://github.com/marshmallow-code/marshmallow/blob/dev/CHANGELOG.rst)
- [Commits](marshmallow-code/marshmallow@4.3.1...4.4.0)

Updates `coverage` from 7.17.0 to 7.17.2
- [Release notes](https://github.com/coveragepy/coveragepy/releases)
- [Changelog](https://github.com/coveragepy/coveragepy/blob/main/CHANGES.rst)
- [Commits](coveragepy/coveragepy@7.17.0...7.17.2)

Updates `pytest-env` from 1.8.4 to 1.8.5
- [Release notes](https://github.com/pytest-dev/pytest-env/releases)
- [Changelog](https://github.com/pytest-dev/pytest-env/blob/main/CHANGELOG.md)
- [Commits](pytest-dev/pytest-env@1.8.4...1.8.5)

Updates `types-python-dateutil` from 2.9.0.20261029 to 2.9.0.20261104
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: flask-socketio
  dependency-version: 5.7.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip
- dependency-name: authlib
  dependency-version: 1.9.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip
- dependency-name: sqlalchemy
  dependency-version: 2.1.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip
- dependency-name: gunicorn
  dependency-version: 26.2.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: pip
- dependency-name: pytz
  dependency-version: '2026.6'
  dependency-type: direct:production
  dependency-group: pip
- dependency-name: markdown
  dependency-version: 3.11.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip
- dependency-name: sentry-sdk
  dependency-version: 2.74.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip
- dependency-name: flask-swagger-ui
  dependency-version: 5.34.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip
- dependency-name: apispec
  dependency-version: 6.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip
- dependency-name: marshmallow
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: pip
- dependency-name: coverage
  dependency-version: 7.17.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip
- dependency-name: pytest-env
  dependency-version: 1.8.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip
- dependency-name: types-python-dateutil
  dependency-version: 2.9.0.20261104
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
The client, task, billable, source and tags filters were read but never
applied, so every export held all entries in the date range.
A grouped invoice line joins every entry id, so about 100 entries
overflowed VARCHAR(500) and generation failed on PostgreSQL.
…develop/npm-desktop-371b0f8b99

chore(deps-dev): bump the npm-desktop group in /desktop with 3 updates
…npm-root-1d7174847e

chore(deps): bump the npm-root group with 2 updates
…b-mobile-9acdf14d0b

chore(deps): bump flutter_local_notifications from 22.3.3 to 23.0.0 in /mobile in the pub-mobile group
…p/github-actions-6d69e638c7

chore(deps): bump softprops/action-gh-release from 3.0.3 to 3.0.4 in the github-actions group
…bbb57

chore(deps): bump the pip group with 13 updates
evilguy4000 and others added 17 commits November 10, 2026 08:49
…ilters

fix(reports): apply the export form's filters to CSV and Excel
…ry-ids-text

fix(invoices): store time_entry_ids as text
…base

Re-pin gunicorn to 25.x for eventlet workers, isolate installation config in tests, format black drift, and compare migration autogenerate against github.event.before on push.
…XML alerts

Use allowlisted OAuth redirects, stop echoing exception text to clients,
HMAC-hash OAuth tokens with legacy fallback, and parse CAMT via defusedxml.
Bring CI fixes (gunicorn pin, wizard test isolation, black, migration BASE_SHA) onto develop alongside the CodeQL security fixes so full CI can re-run.
Bumps the pub-mobile group in /mobile with 1 update: [flutter_riverpod](https://github.com/rrousselGit/riverpod).


Updates `flutter_riverpod` from 2.6.1 to 3.5.0
- [Commits](rrousselGit/riverpod@flutter_riverpod-v2.6.1...flutter_riverpod-v3.5.0)

---
updated-dependencies:
- dependency-name: flutter_riverpod
  dependency-version: 3.5.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: pub-mobile
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps the pip group with 1 update: [types-markdown](https://github.com/python/typeshed).


Updates `types-markdown` from 3.11.2.20261029 to 3.11.2.20261107
- [Commits](https://github.com/python/typeshed/commits)

---
updated-dependencies:
- dependency-name: types-markdown
  dependency-version: 3.11.2.20261107
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
…ecee9

chore(deps): bump types-markdown from 3.11.2.20261029 to 3.11.2.20261107 in the pip group
…b-mobile-ba269c91c6

chore(deps): bump flutter_riverpod from 2.6.1 to 3.5.0 in /mobile in the pub-mobile group
Wire hosted be.letspeppol.org into peppol-bridge for outbound BIS3 sends, and poll/store inbound UBL documents in a Peppol Inbox UI so Belgian operators can send and receive without a paid AP middleman.
Undo the Dependabot flutter_riverpod 3.x bump that broke StateNotifier-based mobile providers, ignore future majors, and format the leftover chat_command_service exception log line.
Expand Unreleased changelog for the post-5.19.1 feature set, bump Android Gradle to 8.14 for Flutter 3.47, and run pod install before iOS simulator builds.
@evilguy4000

Copy link
Copy Markdown
Collaborator

Reopening to approve Actions for github-actions[bot] PR.

@evilguy4000 evilguy4000 reopened this Nov 10, 2026
SFTY-20261008-90293 targets persistent job-store pickle loads; TimeTracker uses MemoryJobStore only, and no patched 3.x release exists yet.
fix(security): ignore APScheduler Safety advisory for rc/v5.20.0
@evilguy4000
evilguy4000 merged commit c7e8583 into main Nov 10, 2026
20 checks passed
@evilguy4000
evilguy4000 deleted the rc/v5.20.0 branch November 10, 2026 13:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants