feat(timesheets): draft state + withdraw endpoint (PMS-183) #157

Merged
longjacksonle merged 1 commit from feat/pms-183-timesheet-withdraw into main 2026-06-11 04:57:00 +02:00

What

Backend half of PMS-183: a real draft -> submit -> approve timesheet lifecycle, plus a withdraw endpoint so a submitted (not-yet-approved) timesheet can be pulled back to draft.

Changes

  • Migration 033: widens the time_entries.approval_status CHECK to include 'draft' and makes it the column default. A freshly logged entry now starts unsubmitted instead of immediately pending approval. Existing rows are left untouched (no in-flight approval disturbed).
  • Week summary (GET /timesheets) now reports 'draft' for an unsubmitted week instead of folding it into 'pending', and the empty-week fallback is 'draft'.
  • New endpoint POST /api/v1/timesheets/{user_id}/{week_start}/withdraw:
    • Moves the week's still-pending entries back to 'draft'.
    • Owner-only (admins may target anyone, mirroring submit).
    • 409 Conflict once any entry in the week is approved (an approved week has already gated billing).

Tests

  • service_desk_time_slice_happy_path: extended to cover withdraw -> draft, resubmit -> pending, and a withdraw-after-approve -> 409.
  • approved_time_rolls_into_actuals (projects): now submits before approving, since an entry no longer auto-starts pending.
  • Full suite green except two pre-existing settings.rs failures (billing module-seed) that fail identically on main and are unrelated to this change.

Pairs with a mokosh-apps PR adding the submit-confirmation modal (certification checkbox) and the Withdraw action.

🤖 Generated with Claude Code

## What Backend half of PMS-183: a real `draft -> submit -> approve` timesheet lifecycle, plus a withdraw endpoint so a submitted (not-yet-approved) timesheet can be pulled back to draft. ## Changes - **Migration 033**: widens the `time_entries.approval_status` CHECK to include `'draft'` and makes it the column default. A freshly logged entry now starts **unsubmitted** instead of immediately `pending` approval. Existing rows are left untouched (no in-flight approval disturbed). - **Week summary** (`GET /timesheets`) now reports `'draft'` for an unsubmitted week instead of folding it into `'pending'`, and the empty-week fallback is `'draft'`. - **New endpoint** `POST /api/v1/timesheets/{user_id}/{week_start}/withdraw`: - Moves the week's still-`pending` entries back to `'draft'`. - **Owner-only** (admins may target anyone, mirroring submit). - **409 Conflict** once any entry in the week is `approved` (an approved week has already gated billing). ## Tests - `service_desk_time_slice_happy_path`: extended to cover `withdraw -> draft`, resubmit `-> pending`, and a withdraw-after-approve `-> 409`. - `approved_time_rolls_into_actuals` (projects): now submits before approving, since an entry no longer auto-starts `pending`. - Full suite green except two pre-existing `settings.rs` failures (billing module-seed) that fail identically on `main` and are unrelated to this change. Pairs with a mokosh-apps PR adding the submit-confirmation modal (certification checkbox) and the Withdraw action. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(timesheets): draft state + withdraw endpoint for timesheets (PMS-183)
All checks were successful
E2E (staging) / Playwright against staging (pull_request) Successful in 40s
Check / fmt + clippy + compile + tests (pull_request) Successful in 2m15s
Create release / Create release from merged PR (pull_request) Has been skipped
Build OCI container / Build and push mokosh-api image (push) Successful in 7m10s
e75bdf96ef
Give time entries a real draft -> submit -> approve lifecycle. Migration 033 widens the approval_status CHECK to include 'draft' and makes it the default, so a freshly logged entry starts unsubmitted instead of immediately pending approval (existing rows are left untouched). The week summary now reports 'draft' for an unsubmitted week instead of folding it into 'pending'. Add POST /timesheets/{user_id}/{week_start}/withdraw: it moves the week's still-pending entries back to draft so the owner can edit and resubmit, is owner-only (admins may target anyone, like submit), and 409s once any entry in the week is approved. The projects actuals test now submits before approving (the entry no longer auto-starts pending), and the time-tracking happy path covers withdraw -> resubmit and the approved-week 409.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/pms-183-timesheet-withdraw 2026-06-11 04:57:00 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-server!157
No description provided.