Skip to content

fix(tms): validate worker PTO and move creation from REST to GraphQL - #567

Open
emoss08 wants to merge 3 commits into
masterfrom
claude/worker-pto-validation-b1j99m
Open

fix(tms): validate worker PTO and move creation from REST to GraphQL#567
emoss08 wants to merge 3 commits into
masterfrom
claude/worker-pto-validation-b1j99m

Conversation

@emoss08

@emoss08 emoss08 commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Description

Two related fixes to the worker PTO create path:

  1. Validationworkerptoservice.Create carried a // TODO: Validate PTO data and the REST handler bound the request body straight into the entity, so a PTO row could be created with no worker, an empty reason, or an end date at or before its start. Create now runs the domain Validate and returns the field-level MultiError before touching the repository. The driver-portal path (RequestMyPTO) already validated before calling Create, so it is unaffected.

  2. REST → GraphQL — even with validation, POST /worker-pto/ let a caller with create permission set any valid status, including Approved — skipping the approval flow and its notifications. The endpoint is removed; creation is now a createWorkerPTO mutation whose input carries only workerId, type, startDate, endDate, and reason. The resolver forces Status: Requested and takes tenant scoping from the auth context, so every PTO enters the approval workflow. The client gains the CreateWorkerPto operation and a createWorkerPTO wrapper beside the existing approve/reject mutations.

No UI called the removed REST endpoint, and the OpenAPI spec never documented it (the handler had no swagger annotations), so nothing else changes.

Related Issue or Discussion

Follow-up from the codebase audit driving PRs #557#564; the REST→GraphQL move was requested by the maintainer after the status hole was flagged.

Type of Change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Tests
  • Build, CI, or infrastructure

Scope

  • services/tms/internal/core/services/workerptoservice/ — validation gate in Create + new service tests
  • services/tms/internal/api/graphql/schema/worker.graphqlsCreateWorkerPTOInput + createWorkerPTO mutation; regenerated generated/, gqlmodel/, resolver stub
  • services/tms/internal/api/graphql/resolver/worker.resolvers.goCreateWorkerPto resolver
  • services/tms/internal/api/handlers/workerptohandler/handler.go — REST create route and handler removed
  • client/packages/graphql/CreateWorkerPto operation + regenerated artifacts (schema, persisted documents, operation catalog)
  • client/apps/web/src/lib/graphql/worker-mutations.tscreateWorkerPTO wrapper

Validation

  • cd services/tms && go build ./... && go vet ./internal/api/... and go test ./internal/api/... ./internal/core/services/workerptoservice/ — all pass
  • Validation rejection test demonstrated red against the pre-change service (fails without the gate), then green
  • go run github.com/99designs/gqlgen generate and pnpm --filter @trenova/graphql codegen run to parity with CI's codegen checks
  • pnpm --filter @trenova/graphql typecheck && pnpm --filter @trenova/web typecheck — clean; pnpm --filter @trenova/web lint shows only pre-existing warnings in unrelated files
  • OpenAPI unchanged (the removed endpoint was never annotated)

Deployment Notes

Breaking for any external API client that POSTed /worker-pto/ directly: creation must now go through the createWorkerPTO GraphQL mutation, and creating pre-approved PTO is no longer possible — every request enters the approval flow as Requested. No migrations or config changes.

Checklist

  • I kept the change focused and reviewable.
  • I followed AGENTS.md, CLAUDE.md, and existing repository patterns.
  • I added or updated tests for behavior changes, or explained why tests are not applicable.
  • I updated relevant documentation, examples, migrations, or configuration.
  • I did not include secrets, credentials, private customer data, unrelated refactors, or placeholder code.

🤖 Generated with Claude Code

https://claude.ai/code/session_015houJkqb8SuqPW4YpLoWCq


Generated by Claude Code

claude added 3 commits August 31, 2026 20:40
workerptoservice.Create carried a TODO instead of validation, and the
REST POST /worker-pto/ handler binds the request body straight into the
entity, so a PTO row could be created with no worker, an empty reason,
or an end date at or before its start date. Create now runs the domain
Validate and returns the field-level MultiError before touching the
repository. The driver-portal path already validated before calling
Create, so it is unaffected.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015houJkqb8SuqPW4YpLoWCq
POST /worker-pto/ bound the request body straight into the entity,
which let a caller with create permission set any status — including
Approved, skipping the approval flow and its notifications. The
endpoint is gone; creation now goes through a createWorkerPTO GraphQL
mutation whose input carries only workerId, type, dates, and reason,
with the resolver forcing status to Requested and tenant scoping from
the auth context, so every PTO enters the approval workflow.

Client side adds the CreateWorkerPto operation and a createWorkerPTO
wrapper beside the existing approve/reject mutations, and regenerates
the GraphQL artifacts. No UI called the removed REST endpoint, and the
OpenAPI spec never documented it, so nothing else changes.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015houJkqb8SuqPW4YpLoWCq
@cloudflare-workers-and-pages

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
trenova-dash b146f1b Aug 31 2026, 10:23 PM

@cloudflare-workers-and-pages

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
trenova b146f1b Aug 31 2026, 10:23 PM

@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 59 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 41ae816c-67d7-4296-9a6d-31ac4bfc344f

📥 Commits

Reviewing files that changed from the base of the PR and between 4851f67 and b146f1b.

⛔ Files ignored due to path filters (5)
  • client/packages/graphql/src/generated/gql.ts is excluded by !**/generated/**
  • client/packages/graphql/src/generated/graphql.ts is excluded by !**/generated/**
  • client/packages/graphql/src/generated/operation-catalog.json is excluded by !**/generated/**
  • client/packages/graphql/src/generated/persisted-documents.json is excluded by !**/generated/**
  • services/tms/internal/api/graphql/generated/generated.go is excluded by !**/generated/**
📒 Files selected for processing (10)
  • client/apps/web/src/lib/graphql/worker-mutations.ts
  • client/packages/graphql/src/operations/worker/page.graphql
  • client/packages/graphql/src/schema.graphql
  • services/tms/internal/api/graphql/gqlmodel/models_gen.go
  • services/tms/internal/api/graphql/persisted-documents.json
  • services/tms/internal/api/graphql/resolver/worker.resolvers.go
  • services/tms/internal/api/graphql/schema/worker.graphqls
  • services/tms/internal/api/handlers/workerptohandler/handler.go
  • services/tms/internal/core/services/workerptoservice/service.go
  • services/tms/internal/core/services/workerptoservice/service_test.go

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

emoss08 commented Aug 31, 2026

Copy link
Copy Markdown
Owner Author

Standing down on the Workers Builds failures (trenova, trenova-dash): although this PR touches client code, the same deploy checks have failed identically on every recent commit regardless of content — including Go-only PRs #557#566 and master merges — so this is the pre-existing environment issue, not this diff. Locally, pnpm --filter @trenova/graphql typecheck, pnpm --filter @trenova/web typecheck, and pnpm --filter @trenova/web lint are all clean on this branch. Build logs are only visible in the Cloudflare dashboard, so no fix can be ported from here.


Generated by Claude Code

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.

2 participants