update api and add more features
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# `ParentPromotionController` plan
|
||||
|
||||
## Scope
|
||||
- **Controller**: `app/Http/Controllers/Api/Parents/ParentPromotionController.php`
|
||||
- **Purpose**: parent portal endpoints for promotion + enrollment workflow.
|
||||
- **Primary dependencies**:
|
||||
- `App\Services\Promotions\PromotionEnrollmentService`
|
||||
- `App\Services\Promotions\PromotionQueryService`
|
||||
- **Models**:
|
||||
- `App\Models\StudentPromotionRecord`
|
||||
- `App\Models\Student` (ownership verification fallback)
|
||||
|
||||
## Routes
|
||||
All routes are under `v1` + `parents` group:
|
||||
- Base prefix: `... /api/v1/parents/promotions`
|
||||
- Group middleware: `parent.access`
|
||||
|
||||
Endpoints:
|
||||
- `GET /api/v1/parents/promotions/` → `overview`
|
||||
- `GET /api/v1/parents/promotions/{promotionId}` → `show`
|
||||
- `POST /api/v1/parents/promotions/{promotionId}/start` → `start`
|
||||
- `PATCH /api/v1/parents/promotions/{promotionId}/steps` → `updateSteps`
|
||||
- `POST /api/v1/parents/promotions/{promotionId}/submit` → `submit`
|
||||
|
||||
## Authentication & authorization
|
||||
- Parent context resolved via `parentIdOrUnauthorized()`:
|
||||
- prefers request attribute `primary_parent_id` (set by `parent.access`)
|
||||
- falls back to `auth()->id()`
|
||||
- Ownership is enforced in `loadOwnedRecord()`:
|
||||
- Primary check: `StudentPromotionRecord.parent_id == parentId`
|
||||
- Fallback: loads `Student.parent_id` for the record’s `student_id`
|
||||
- If not owned: returns `403` `{ ok:false, message:"You are not authorised..." }`
|
||||
|
||||
## Requests/validation
|
||||
- `overview`: `ParentPromotionOverviewRequest` (optional `next_school_year`)
|
||||
- `updateSteps`: `ParentEnrollmentStepRequest` (`steps()` accessor provides structured step payload)
|
||||
|
||||
## Response shapes
|
||||
- `overview`:
|
||||
- `{ ok:true, records, next_school_year, message }`
|
||||
- Note: `records` are returned as provided by `PromotionEnrollmentService::overviewForParent(...)` (already shaped for the client)
|
||||
- `show` / `start` / `updateSteps` / `submit`:
|
||||
- `{ ok:true, data: StudentPromotionResource(...) }`
|
||||
|
||||
## State transitions (high-level)
|
||||
- `start` → `PromotionEnrollmentService::startEnrollment(...)`
|
||||
- `updateSteps` → `PromotionEnrollmentService::updateSteps(...)`
|
||||
- `submit` → `PromotionEnrollmentService::submitEnrollment(...)`
|
||||
- Conflicts (invalid transition / deadline / status) surface as `409` with `{ ok:false, message }`.
|
||||
|
||||
## Error handling expectations
|
||||
- Unauthorized → `401` `{ ok:false, message:"Unauthorized." }`
|
||||
- Record not found → `404` `{ ok:false, message:"Promotion record not found." }`
|
||||
- Not owned → `403` `{ ok:false, message:"You are not authorised..." }`
|
||||
- Invalid transition → `409` `{ ok:false, message }`
|
||||
|
||||
## Test plan (feature)
|
||||
- Ownership:
|
||||
- Parent cannot access another parent’s record (403).
|
||||
- Record with mismatched `parent_id` but student belongs to parent passes ownership check.
|
||||
- Happy path:
|
||||
- `overview` returns list for parent.
|
||||
- `start` moves record to started state and returns updated resource.
|
||||
- `updateSteps` persists steps and returns updated resource.
|
||||
- `submit` transitions to submitted state.
|
||||
- Conflict cases:
|
||||
- Submitting without required steps → 409.
|
||||
- Past deadline → 409 (as enforced by service).
|
||||
|
||||
Reference in New Issue
Block a user