From 7c24887ec1d43de31afb82622b9a80bf809c65ef Mon Sep 17 00:00:00 2001 From: patrick Date: Wed, 5 Aug 2026 18:56:55 +0200 Subject: [PATCH] fix(hours_payouts): RLS-Bypass-Falle bei mid-request commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _build_out() lief nach db.commit() -> app.bypass_rls verfällt mit Transaktion, Post-Commit-Reads sahen keine Zeilen mehr. _build_out() jetzt vor commit aufgerufen (create/request/approve/reject/cancel). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01LTxkZEUdfgMxZvHPiZJ8bV --- DEVLOG.md | 50 ++++++++++++++++++++++++++++ backend/app/routers/hours_payouts.py | 22 ++++++------ 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/DEVLOG.md b/DEVLOG.md index edf3ee7..4085703 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -2636,3 +2636,53 @@ Keine Commits in dieser Session. - server-update.sh | 14 ++++++++++---- --- +## 2026-07-10 01:54 – 01:55 (0m) +**Beschreibung:** Claude Code Session +**Projekt:** custom-addons + +### Commits +Keine Commits in dieser Session. + +### Geänderte Dateien +- DEVLOG.md | 460 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +- backend/DEVLOG.md | 13 ++++ +- backend/app/models/company.py | 2 + +- backend/app/models/hours_payout.py | 17 ++++- +- backend/app/routers/hours_payouts.py | 280 +++++++++++++++++++++++++++++++++++++++++++++++-------------------- +- backend/app/schemas/company.py | 2 + +- backend/app/schemas/hours_payout.py | 17 +++++ +- backend/migrations/versions/0042_payout_requests.py | 36 +++++++++ +- backend/tests/test_hours_payouts.py | 87 +++++++++++++++++++++ +- frontend/DEVLOG.md | 39 ++++++++++ +- frontend/src/components/PayoutRequestCard.tsx | 150 ++++++++++++++++++++++++++++++++++++ +- frontend/src/pages/AbsencesPage.tsx | 3 + +- frontend/src/pages/CompanySettingsPage.tsx | 31 +++++++- +- frontend/src/pages/HoursPayoutPage.tsx | 82 +++++++++++++++++--- +- frontend/src/types/hoursPayout.ts | 7 ++ + +--- +## 2026-08-05 18:56 – 18:56 (0m) +**Beschreibung:** Claude Code Session +**Projekt:** timemaster + +### Commits +Keine Commits in dieser Session. + +### Geänderte Dateien +- DEVLOG.md | 460 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +- backend/DEVLOG.md | 13 ++++ +- backend/app/models/company.py | 2 + +- backend/app/models/hours_payout.py | 17 ++++- +- backend/app/routers/hours_payouts.py | 280 +++++++++++++++++++++++++++++++++++++++++++++++-------------------- +- backend/app/schemas/company.py | 2 + +- backend/app/schemas/hours_payout.py | 17 +++++ +- backend/migrations/versions/0042_payout_requests.py | 36 +++++++++ +- backend/tests/test_hours_payouts.py | 87 +++++++++++++++++++++ +- frontend/DEVLOG.md | 39 ++++++++++ +- frontend/src/components/PayoutRequestCard.tsx | 150 ++++++++++++++++++++++++++++++++++++ +- frontend/src/pages/AbsencesPage.tsx | 3 + +- frontend/src/pages/CompanySettingsPage.tsx | 31 +++++++- +- frontend/src/pages/HoursPayoutPage.tsx | 82 +++++++++++++++++--- +- frontend/src/types/hoursPayout.ts | 7 ++ + +--- diff --git a/backend/app/routers/hours_payouts.py b/backend/app/routers/hours_payouts.py index 6ffc823..c97c536 100644 --- a/backend/app/routers/hours_payouts.py +++ b/backend/app/routers/hours_payouts.py @@ -118,6 +118,7 @@ async def create_payout( ) db.add(payout) await db.flush() + await db.refresh(payout) # server_default created_at – noch in-Transaktion (RLS-Kontext da) db.add(AuditLog( company_id=current_user.company_id, user_id=current_user.id, @@ -128,9 +129,9 @@ async def create_payout( }, ip=get_client_ip(request), )) + out = await _build_out(payout, db) await db.commit() - await db.refresh(payout) - return await _build_out(payout, db) + return out # ── POST /hr/payouts/request (Mitarbeiter-Selbstbedienung) ──────────────────── @@ -161,6 +162,7 @@ async def request_payout( ) db.add(payout) await db.flush() + await db.refresh(payout) # server_default created_at – noch in-Transaktion (RLS-Kontext da) db.add(AuditLog( company_id=current_user.company_id, user_id=current_user.id, @@ -168,9 +170,9 @@ async def request_payout( new_value={"hours": str(hours), "note": data.note}, ip=get_client_ip(request), )) + out = await _build_out(payout, db) await db.commit() - await db.refresh(payout) - return await _build_out(payout, db) + return out # ── POST /hr/payouts/{id}/approve ───────────────────────────────────────────── @@ -202,9 +204,9 @@ async def approve_payout( new_value={"hours": str(payout.hours), "user_id": str(payout.user_id)}, ip=get_client_ip(request), )) + out = await _build_out(payout, db) await db.commit() - await db.refresh(payout) - return await _build_out(payout, db) + return out # ── POST /hr/payouts/{id}/reject ────────────────────────────────────────────── @@ -235,9 +237,9 @@ async def reject_payout( new_value={"rejection_reason": data.rejection_reason, "user_id": str(payout.user_id)}, ip=get_client_ip(request), )) + out = await _build_out(payout, db) await db.commit() - await db.refresh(payout) - return await _build_out(payout, db) + return out # ── POST /hr/payouts/{id}/cancel (Antragsteller zieht zurück) ───────────────── @@ -264,9 +266,9 @@ async def cancel_payout( action="hours_payout_cancelled", entity_type="hours_payout", entity_id=payout.id, ip=get_client_ip(request), )) + out = await _build_out(payout, db) await db.commit() - await db.refresh(payout) - return await _build_out(payout, db) + return out # ── DELETE /hr/payouts/{id} ───────────────────────────────────────────────────