Skip to content

Add FormRequests + a Resource to the leave and attendance APIs (#34) - #5

Merged
HafizMMoaz merged 2 commits into
masterfrom
feat/34-formrequests-resources
Jul 23, 2026
Merged

Add FormRequests + a Resource to the leave and attendance APIs (#34)#5
HafizMMoaz merged 2 commits into
masterfrom
feat/34-formrequests-resources

Conversation

@HafizMMoaz

Copy link
Copy Markdown
Member

Second half of zerp-pk/zerp#34. Depends on zerp-pk/zerp#81 (the App\Http\Requests\ApiFormRequest base); merge that first.

What Scramble could and could not see

The controllers validated with inline Validator::make(...), which Scramble cannot read, so the request bodies at /docs/hrm were empty. Two write endpoints now take typed FormRequests, which Scramble does read:

  • Api/StoreLeaveRequest for POST leave-request
  • Api/ClockInOutRequest for POST clock-in-out

They extend the app's ApiFormRequest, so a validation failure keeps the exact {success, message, errors} 422 envelope the API already returned. Verified over real HTTP against the running app:

POST /api/hrm/clock-in-out  type=bogus
  422  {"success":false,"message":"Validation error","errors":{"type":["The selected type is invalid."]}}
POST /api/hrm/leave-request  (empty)
  422  {"success":false,"message":"Validation error","errors":{"leave_type_id":[...],"start_date":[...],"end_date":[...],"reason":[...]}}

The response side, stated plainly

The issue also asks to type controller returns as : JsonResource so Scramble infers response shapes. That does not work here, and I did not force it: every endpoint answers with the shared ApiResponseTrait envelope {success, message, data} via response()->json, which Scramble cannot see through. The only ways to enrich response schemas are to drop the envelope (breaks every existing mobile client) or add Scramble response annotations. Both are out of scope for a non-breaking change; the annotation route is a clean follow-up.

The Resource earns its place on correctness, not docs

LeaveApplicationResource replaces the leave shape that was hand-copied into both the list and the create response. The two copies had already drifted: the list fell back to avatar.png for a missing attachment, create fell back to ''. Both now use the list's fallback, since that is what a client sees on every later read. Confirmed the resolved output keeps all 11 original keys and the same attachment URL when one is present:

KEYS: id,employee_id,start_date,end_date,total_days,status,reason,approver_comment,leave_type_id,attachment,created_by
attachment present -> http://localhost:8000/storage/media/uploads/leave/x.pdf
attachment missing -> http://localhost:8000/storage/media/avatar.png

Behavior notes

  • StoreLeaveRequest types attachment as nullable|file. The endpoint only ever reads it via hasFile(), so a stray string was silently ignored before and is now a clean 422. Slightly stricter, and it is what makes the OpenAPI body show a file upload.
  • create's missing-attachment response changes from '' to the avatar.png URL, matching the list. This is the drift fix, called out so it is not a surprise.
  • No package test suite exists yet (that is [zerp] Module packages ship with zero automated tests and no CI zerp#48), so verification is the HTTP smoke run above plus the resolved-resource key check.

Same pattern now applies cleanly to lead / taskly / support-ticket.

🤖 Generated with Claude Code

The API controllers validated with inline Validator::make, which Scramble
cannot read, so the request bodies at /docs/hrm came out empty. Two write
endpoints now take typed FormRequests that extend the app's ApiFormRequest,
so Scramble infers the request schema and the validation-failure envelope is
unchanged:

- StoreLeaveRequest for POST leave-request (no employee_id, files leave for
  the authenticated user; attachment typed as a file)
- ClockInOutRequest for POST clock-in-out

LeaveApplicationResource replaces the leave shape that was hand-copied into
both the list and create responses. The two copies had drifted: the list
fell back to avatar.png for a missing attachment, create fell back to an
empty string. Both now use the list's fallback, which is what a client sees
on later reads. Output keys are otherwise identical.

Response schemas at /docs stay opaque because every endpoint answers with the
shared {success, message, data} envelope, which Scramble cannot see through.
Enriching those means either dropping the envelope, which breaks existing
clients, or adding response annotations, a separate follow-up.
@HafizMMoaz
HafizMMoaz requested a review from a team as a code owner July 23, 2026 20:10
@HafizMMoaz
HafizMMoaz merged commit a71d3a8 into master Jul 23, 2026
2 checks passed
@HafizMMoaz
HafizMMoaz deleted the feat/34-formrequests-resources branch July 23, 2026 20:13
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.

1 participant