Skip to content

fix: correct existing time entries through versioned requests (#43) - #48

Open
patrickschiller wants to merge 6 commits into
mainfrom
fix/43-existing-entry-correction
Open

patrickschiller wants to merge 6 commits into
mainfrom
fix/43-existing-entry-correction

Conversation

@patrickschiller

@patrickschiller patrickschiller commented Nov 7, 2026 •

Copy link
Copy Markdown
Owner

Fixes #43.

Abhängigkeit und Reihenfolge

Depends on #46 und #47. Basis ist der unabhängig akzeptierte #41-Head
dbe68f57a93ba26bdc315d31fd4b313586a4337b. Der PR zielt bewusst auf main,
damit sämtliche bestehenden CI-Jobs laufen; gegen main ist der Diff
kumulativ #42 + #41 + #43.

Vorgesehene Reihenfolge: #46 → #47 → dieser PR. Kein Merge und kein
Auto-Merge. Der obere Branch kann alle drei Pakete bereits gemeinsam testen.

Nur #43: Commit 34a9b5094568fffd990fa0827e6e9f8c28c13209,
24 Dateien, +3402/−83. Kumulativ gegen main: 37 Dateien, +8959/−407.

Umsetzung #43

  • Explizite Auswahl fehlende Buchung oder bestehende Buchung korrigieren.
    Berechtigte eigene, abgeschlossene, nicht verworfene Team-Buchungen sind direkt
    auswählbar; Zielwerte werden einschließlich Sekunden/DST-Vorkommen vorbelegt.
    Beschäftigte und Genehmigende sehen Vorher/Vorschlag, lokale Zeit mit Offset,
    Bruttodifferenz, Ziel-ID und gebundene Originalrevision.
  • Ziel-ID und erwartete Zielrevision bilden ein Paar. Der Server erfasst selbst
    den unveränderlichen Originalsnapshot. Fremde/offene/verworfene/abgelehnte/
    Solo-Ziele und unvollständige/gefälschte Bindungen werden abgewiesen.
    Identität stammt aus dem JWT, nicht aus Body-/Query-Mitarbeiterfeldern.
  • Draft-Speichern/Wiedereinreichen aus [bug] Bearbeiten von Anträgen #42 erhält und revalidiert dieselbe
    Zielbindung und Originalversion; kein stilles Retargeting oder Auffrischen
    unter einer alten Freigabe. Stale-Versionen verlangen Prüfung und einen neuen
    Antrag auf dem aktuellen Buchungsstand.
  • Ausschließlich die unveränderte konkrete Ziel-ID ist vom TimeEntry-Overlap
    ausgenommen. Alle anderen Buchungen bleiben geprüft; kein Tagesüberschreiben.
    Bereits materialisierte genehmigte Zeitkorrekturanträge reservieren nicht
    zusätzlich ihren alten Zeitraum — die tatsächlichen Buchungen sind maßgeblich.
  • Alle finalen Approval-Routen aktualisieren dieselbe Buchung gemeinsam mit
    Request-Entscheidung und Audit in einer Transaktion. Keine neue Doppelbuchung.
    Gemeinsame Sperrreihenfolge, Pflichtrevision und atomarer Versionsvergleich
    schützen gegen Clock-/Split-/Metadaten-/[bug] Genehmigung von Buchungen außerhalb der Rahmenzeit #41-Freigaben, konkurrierende Anträge,
    Wiederholung und Rollback nach bereits ausgeführtem Update.
  • Gezielte Korrekturen erfordern den aktuellen zugewiesenen aktiven Manager;
    Selbst-/Fremdfreigabe ist ausgeschlossen. Vorgeschlagene Außenrahmenwerte
    erzwingen zusätzlich HR; alte Buchungsfreigaben autorisieren keine neuen
    Zeiten. Erst die letzte erforderliche Stufe wendet die Änderung an.
  • Projekt/Auftrag, Tätigkeit, Notiz, Abrechenbarkeit, Capture-Gruppe und gespeicherte
    Pausenpolitik bleiben erhalten; Summaries werden neu berechnet. Ursprüngliche
    Auditdaten bleiben bestehen; neues Vorher/Nachher-Audit enthält tatsächlichen
    Akteur, Zeit und Request-FK. Antragsberechtigte sehen es über einen eigenen
    Read-Endpunkt; [bug] Genehmigung von Buchungen außerhalb der Rahmenzeit #41-Verlauf zeigt den verknüpften Korrekturantrag.
  • Bereits angewendete gezielte Korrekturen können nicht durch bloßes
    Request-Storno irreführend als rückgängig dargestellt werden.
  • Fehlende-Buchung-Verhalten und bestehende Solo-Owner-Korrekturberechtigungen
    bleiben getrennt erhalten. DE/EN, benutzergebundene Query-Caches,
    Realtime-Invalidierung, synchroner OpenAPI-/Client-Vertrag.
  • Additive Migration 20261107040000_targeted_time_corrections; keine
    Alt-Migration geändert, keine erfundenen Ziel-/Auditlinks für Bestandsdaten.

Lokale Verifikation

Isolierter PostgreSQL-16-Container mit ausschließlich synthetischen Datenbanken;
keine vorhandene Datenbank zurückgesetzt. pnpm 9.15.9, vollständige Testläufe
zusätzlich unter CI-Node 20.20.2.

Gate Ergebnis
Neue gezielte Korrektur-API-/Service-Regressionen 35/35 bestanden
TZ=Europe/Berlin pnpm nx e2e api-e2e unter Node 20.20.2 366/366 Tests, 39 Suites bestanden
Fünf gezielte UI-/i18n-/DST-Testdateien 68/68 bestanden
TZ=UTC pnpm nx run-many -t test -p web,shared --run --skip-nx-cache unter Node 20.20.2 Web 247/247, Shared 88/88 bestanden, ohne Cache
pnpm nx run-many -t typecheck,lint -p api,web,shared,api-e2e Alle vier Typechecks/Lint erfolgreich, keine neuen Warnungen
pnpm nx run-many -t build -p api,web,shared, getrennt von Typechecks Alle Builds einschließlich PWA erfolgreich
pnpm verify:api / git diff --check Erfolgreich
Akzeptiertes #41-Schema → Altantrag/Audit-Sentinels → neue Migration → Upgrade-Smoke Erfolgreich, bestehende Daten/Actor/Snapshots bleiben erhalten

Belegt sind 08–16→08–17 und 09–16 mit gleicher ID/stabiler Anzahl, echte
Pausen-/Saldodifferenzen, Gruppensnapshots, Rechte/Modus, unveränderliche
reason-only Drafts, Sekunden/DST, konkurrierende unterschiedliche Anträge und
tatsächlicher Rollback nach bereits erfolgtem Entry-Update für alle finalen Routen.

Nachtest und Grenzen

Deutsche Anleitung, Paket #43: isoliertes Setup, synthetische Rollen,
reproduzierbare Originalbuchungen, Positiv-/Negativ-/Konkurrenzfälle, Erwartungen
und tatsächliche Ergebnisse
.

Die UI-Regressionen sind React-Testing-Library-Tests; der dokumentierte manuelle
Docker-/Browser-Durchlauf wurde nicht als durchgeführt behauptet.

Nur #42/#41/#43. #45 und #44 nicht begonnen. Kein Release, Tag, Versionsbump,
Merge, Deployment oder Release-Workflow.

GitHub-Gates auf 34a9b5094568fffd990fa0827e6e9f8c28c13209 vollständig grün:

  • CI-Lauf:
    build-test-lint, api-e2e, database-upgrade und
    terminal-pin-browser erfolgreich.
  • CI-API: 366/366 Tests, 39 Suites; pnpm verify:api erfolgreich.
  • CI-Web: 247/247 Tests, 35 Dateien; vier Projekt-Typechecks und relevante
    Builds erfolgreich.
  • DCO
    erfolgreich; verlangter Signed-off-by- und exakter Co-Author-Trailer vorhanden.

Reopen returned drafts with their values and revision reason. Add owner-only versioned editing/resubmission, shared validation, balance/overlap self-exclusion, transactional concurrency guards, employee names, synchronized API contracts and regression/manual acceptance coverage.

Co-authored-by: patrickschiller <39913537+patrickschiller@users.noreply.github.com>
Signed-off-by: Patrick Schiller <39913537+patrickschiller@users.noreply.github.com>
Keep persisted timestamps unchanged until their time field is edited. Resolve wall-clock validation and payloads to identical instants, require explicit ambiguous-time choices, reject clock-change gaps, and cover seconds, both fold occurrences and reason-only save/resubmit cycles.

Co-authored-by: patrickschiller <39913537+patrickschiller@users.noreply.github.com>
Signed-off-by: Patrick Schiller <39913537+patrickschiller@users.noreply.github.com>
Keep the English DST selection regression independent of jsdom persisted locale on Node 20. Verify all 208 web tests with Node 20.20.2 and document the CI follow-up.

Co-authored-by: patrickschiller <39913537+patrickschiller@users.noreply.github.com>
Signed-off-by: Patrick Schiller <39913537+patrickschiller@users.noreply.github.com>
Add scoped, versioned TimeEntry review with distinct current-manager and HR stages, durable decision audit, legacy pending support and conservative edit invalidation. Surface employee guidance, reviewer actions and history in German/English, synchronize API contracts, and verify additive database upgrades and security/concurrency regressions. Based on accepted #42; no release or merge.

Co-authored-by: patrickschiller <39913537+patrickschiller@users.noreply.github.com>
Signed-off-by: Patrick Schiller <39913537+patrickschiller@users.noreply.github.com>
Bind correction requests to an owned eligible entry ID and original revision with immutable server snapshots. Revalidate targets, overlaps and required manager/HR stages, then update the same entry and linked audit atomically at final approval. Retain draft precision, metadata and break policies; add target selection/diffs, upgrade safety and focused rollback/concurrency regressions. Cumulative on accepted #42 and #41; no release or merge.

Co-authored-by: patrickschiller <39913537+patrickschiller@users.noreply.github.com>
Signed-off-by: Patrick Schiller <39913537+patrickschiller@users.noreply.github.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 7, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-07T03:07:00.187830Z 34a9b50 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 34a9b50945

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

private dto(row: ReviewEntry, actor: Employee): TimeEntryApprovalDto {
const state = frameApprovalState(row);
return {
entry: toTimeEntryDto(row),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Calculate approval summaries using the full capture group

For split bookings with a captureGroupId, this calls toTimeEntryDto without overriding its per-entry summary, so the new approval screen displays incorrect break deductions and net time. For example, two four-hour segments under the existing six-hour/30-minute break policy each display zero break instead of their allocated 15 minutes. TimeEntryApprovalRow renders these values to both employees and reviewers, contradicting the booking and account totals. Load all capture-group members, including those outside the approval-list filter, and use calculateCaptureSummaries when building these DTOs.

Useful? React with 👍 / 👎.

Distinguish forbidden foreign targets from ignored body employee identities; eligible own targets remain valid under the authenticated identity.

Co-authored-by: patrickschiller <39913537+patrickschiller@users.noreply.github.com>
Signed-off-by: Patrick Schiller <39913537+patrickschiller@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

[bug] Zeitkorrekturen funktionieren nicht

1 participant