Adds MealAllowanceRate as a flat, nullable EUR amount on Facility, following
the same pattern as the existing TravelCostRate/BillingRate fields — a fixed
per-facility rate, not the statutory day-based VMA tiers, per explicit
request.
Both generated API clients are regenerated/rebuilt as required after any
Contract/Controller change (see omsorgCore/CLAUDE.md, "Generierte API-
Clients"). The PHP client regen also picks up the DELETE /api/roles/{id}
endpoint added in a previous backend change but never synced to this client
until now.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Facility: TravelCostMode (Pauschale/ProKilometer) + TravelCostPerKm, alongside
the existing flat rate; fixes FacilityService.UpdateAsync silently dropping all
Konditionen fields on update.
- New EmployeeFacilityDistance (Mitarbeiter x Einrichtung -> km) with full
office-side CRUD in omsorgapp, plus a self-service endpoint/UI so field staff
can maintain their own commute distance via OMSORG Connect (new
ModuleType.EmployeeFacilityDistances, Own-scope, no Facilities access needed).
- Roles can now be deleted (blocked with a 409 while still assigned to a user).
- Fix employeesApi.js missing the Date-object conversion for dateOfBirth/entryDate/
exitDate that crashed employee creation whenever a date was filled in; add a
clear/remove control for those date fields.
- Requirements: flesh out FR-REC-3 with a staged Akquise cadence, add FR-REC-5/6
for CRM feature scope and success metrics.
- Regenerate api-client-ts and api-client-php for all of the above.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The cookie-only refresh-token migration earlier this session broke both
mitarbeiter-app and mitarbeiter-app-legacy: they're server-to-server PHP
clients (cURL/Guzzle calling omsorgCore directly) with no browser cookie
jar, so dropping refreshToken from the login/refresh response body left
them with nothing to store - login appeared to succeed, redirected to
the dashboard, but the very next page's session check failed silently
(mitarbeiter-app's _ensure_fresh_token() bails out whenever
$_SESSION['omsorgcore_refresh_token'] is empty), bouncing the user back
to the login form every time.
Fix: dual-mode refresh token transport instead of cookie-only.
- LoginResponse includes refreshToken again (restores the pre-migration
contract PHP already expected) alongside the HttpOnly cookie.
- AuthController.Refresh/Logout accept an optional body-carried
RefreshRequest/LogoutRequest as a fallback: cookie is checked first
(browser/omsorgapp), body second (server-to-server clients).
- omsorgapp keeps ignoring the body's refreshToken and relies solely on
the cookie (XSS-safe) - only its authApi.js needed a small update since
the regenerated client now requires an explicit (empty) parameter
object for refresh/logout.
- Regenerated omsorgcore-client-ts; api-client-php's lib/ was already
consistent (never regenerated during the original migration, so it
still expected refreshToken all along - only the backend had stopped
providing it).
Verified end-to-end against a live instance: PHP login+refresh via
omsorgcore_login()/omsorgcore_refresh(), and the browser cookie-only
flow via curl with Origin/credentials headers - both work.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
omsorgCore/CLAUDE.md documents vendor/ as committed so the app can run
without a composer install step, but the generator's own .gitignore
(api-client-php/.gitignore) excludes /vendor/ - it only ever existed
untracked on disk locally, which is why the Docker build worked for me
but mitarbeiter-app crashed at runtime on a real (fresh-checkout) deploy:
"Failed opening required '.../api-client-php/vendor/autoload.php'".
Verified by building from a git-archive-simulated fresh checkout with
this fix applied - mitarbeiter-app's login page now renders without the
fatal error.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The root .htaccess forces HTTPS via `RewriteCond %{HTTPS} !=on`. Behind a
reverse proxy that terminates TLS and forwards to Apache over plain HTTP,
%{HTTPS} is always "off" - verified via mod_rewrite trace logging that
this is NOT spoofable via SetEnvIf or a RewriteRule E-flag, despite that
being commonly recommended; %{HTTPS} reflects only the actual TLS
connection to Apache. Every request was therefore redirected to https://,
which the proxy forwarded back over HTTP, looping forever (browser: "the
page isn't redirecting properly").
Fix: .htaccess's redirect condition also accepts a trusted
X-Forwarded-Proto: https header as evidence the request is already
HTTPS. omsorgWeb/docker/000-default.conf additionally sets HTTPS=on in
the request environment when that header is present, so mod_headers'
`env=HTTPS` condition (HSTS header) still fires correctly - this part
doesn't affect mod_rewrite's %{HTTPS} but is unrelated to the redirect fix.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- docker-compose.yml: pull omsorgcore/omsorgapp/omsorgweb from the Gitea
registry (pinnable via OMSORG_IMAGE_TAG) instead of building locally;
remove the MySQL service (mitarbeiter-app-legacy is unmaintained legacy
code) and switch all persistent storage from named Docker volumes to
bind mounts under /root/data/.
- omsorgWeb/Dockerfile: create the upload/download/etc. directories before
chown'ing them - they're excluded by .gitignore, so a fresh CI checkout
doesn't have them and the build failed there (only worked locally because
of leftover local test files).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- omsorgapp: drop Electron, run as a plain Vite/React browser app; refresh
token moves to an HttpOnly cookie (omsorgCore), CORS added for the new
browser origin, document download/preview switched to Blob-based browser
APIs.
- Add Dockerfiles for omsorgCore, omsorgapp, and omsorgWeb, a docker-compose.yml
wiring Postgres/MySQL/all three apps together, and a Gitea Actions workflow
that builds and pushes images to the repo's container registry on push to
main and on version tags.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Extends omsorgCore with full CRUD for Facility/Contract/Order plus
configurable value lists and an audit trail, and wires the omsorgapp
frontend up to the new facilities, settings, and audit-log modules;
includes a sidebar active-nav-item highlight.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New omsorgWeb/mitarbeiter-app/ replaces the legacy PHP app for now
with just the login flow, built fresh instead of incrementally
refactored. Reuses the already-working omsorgCore JWT auth pattern
(login, silent refresh, session-stored token pair, /api/auth/me for
role+permissions) but drops everything legacy carried alongside it:
no local MySQL user cache, no admin/user-management endpoints, no
admin UI. Employee/user management stays exclusive to OMSORG Desktop
per architecture decision - Connect only ever acts on the current
user's own session.
logout.php additionally revokes the refresh token server-side via
omsorgcore_logout(), which the legacy version never did.
Verified end-to-end against a running omsorgCore instance: login,
dashboard via /api/auth/me, logout + token revocation, unauth
redirect, and wrong-credential error handling.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Consolidates the previously separate omsorgapp and omsorgCore repos
(each had their own nested .git with GitHub history) plus the old
root-level website/mitarbeiter-app into a single monorepo, matching
the structure already documented in the root CLAUDE.md. Also moves
the PHP employee app aside as omsorgWeb/mitarbeiter-app-legacy/ to
serve as a template for a ground-up rewrite.
Fixes .gitignore in the same pass: the config-secrets/uploads/data
patterns were unanchored (relative to repo root, not depth-agnostic),
so they silently stopped matching once the app moved under omsorgWeb/.
Patterns are now **/-prefixed and cover both mitarbeiter-app and
mitarbeiter-app-legacy, keeping DB/SMTP credentials and uploaded
employee documents out of version control.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>