Files
alrahma_sunday_school_api/docs/controller_plan.md
T
2026-06-04 02:24:41 -04:00

2094 lines
175 KiB
Markdown

# API Controller Plan
Generated from the uploaded `Api(1).zip` controller tree. This is a controller-by-controller implementation and hardening plan, not a routing map, because no route file was included. Yes, apparently we are deriving architecture from controllers now, because civilization is fragile.
- Controller files found: **124**
- Scope: `Api/**/*.php` files ending in `Controller.php`
- Default standard for every controller: validate with FormRequest or explicit validator, keep business logic in services, return consistent JSON envelopes, enforce auth/permissions, log failures without PII, and cover endpoints with feature tests.
## Global cleanup plan
1. **Normalize namespaces and duplicates.** There are root controllers and module controllers with overlapping names, especially `BaseApiController`, `RolePermissionController`, `RoleSwitcherController`, `StatsController`, and `UserController`. Decide which are canonical and deprecate the rest.
2. **Make controllers thin.** Anything doing calculations, scans, finance state changes, reporting, or multi-table writes belongs in a service/action class.
3. **Standardize response shape.** Use one success/error format, predictable status codes, and resource classes for payloads.
4. **Permission matrix.** For each endpoint, define roles allowed, ownership rules, and school/tenant scoping. Write denied-path tests first, because hope is not access control.
5. **Audit mutating operations.** Store actor, before/after, timestamp, and reason for attendance, finance, grades, family/student/staff changes.
6. **Test by risk.** Finance, auth, attendance, grading, and mass communication get transaction/idempotency/authorization tests before cosmetic endpoints.
## Table of contents
- [Administrator](#administrator) (8)
- [Assignment](#assignment) (1)
- [Attendance](#attendance) (6)
- [AttendanceTracking](#attendancetracking) (1)
- [Auth](#auth) (7)
- [BadgeScan](#badgescan) (1)
- [Badges](#badges) (1)
- [Certificates](#certificates) (1)
- [ClassPreparation](#classpreparation) (1)
- [ClassProgress](#classprogress) (1)
- [Classes](#classes) (1)
- [Communication](#communication) (1)
- [CompetitionScores](#competitionscores) (1)
- [Core](#core) (1)
- [Discounts](#discounts) (1)
- [Documentation](#documentation) (2)
- [Email](#email) (3)
- [Exams](#exams) (1)
- [Expenses](#expenses) (1)
- [ExtraCharges](#extracharges) (1)
- [Family](#family) (2)
- [Finance](#finance) (14)
- [Frontend](#frontend) (4)
- [Grading](#grading) (2)
- [Incidents](#incidents) (1)
- [Inventory](#inventory) (5)
- [Messaging](#messaging) (2)
- [Notifications](#notifications) (1)
- [Parents](#parents) (5)
- [PrintRequests](#printrequests) (1)
- [Public](#public) (1)
- [Reports](#reports) (4)
- [Root](#root) (6)
- [Scores](#scores) (9)
- [Settings](#settings) (6)
- [Staff](#staff) (3)
- [Students](#students) (1)
- [Subjects](#subjects) (1)
- [Support](#support) (2)
- [System](#system) (9)
- [Ui](#ui) (1)
- [Users](#users) (1)
- [Utilities](#utilities) (2)
## Administrator
### AdministratorAbsenceController
**File:** `Api/Administrator/AdministratorAbsenceController.php`
**Purpose:** manage school identity and operations workflow for administrator absence.
**Public methods:** `index()`, `store(Request $request)`
**Detected dependencies:** Services: `AdministratorAbsenceService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission.
### AdministratorDashboardController
**File:** `Api/Administrator/AdministratorDashboardController.php`
**Purpose:** manage school identity and operations workflow for administrator dashboard.
**Public methods:** `metrics()`, `userSearch(Request $request)`
**Detected dependencies:** Services: `AdministratorDashboardService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### AdministratorEnrollmentController
**File:** `Api/Administrator/AdministratorEnrollmentController.php`
**Purpose:** manage school identity and operations workflow for administrator enrollment.
**Public methods:** `index(Request $request)`, `newStudents()`, `updateStatuses(Request $request)`
**Detected dependencies:** Services: `AdministratorEnrollmentService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
### AdministratorNotificationController
**File:** `Api/Administrator/AdministratorNotificationController.php`
**Purpose:** manage school identity and operations workflow for administrator notification.
**Public methods:** `alerts()`, `saveAlerts(Request $request)`, `printRecipients()`, `savePrintRecipients(Request $request)`
**Detected dependencies:** Services: `AdministratorNotificationService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Validate file type, size, storage path, and access ownership.
- Generated documents need reproducible inputs and predictable naming.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### AdministratorPromotionController
**File:** `Api/Administrator/AdministratorPromotionController.php`
**Purpose:** manage school identity and operations workflow for administrator promotion.
**Public methods:** `index(AdminListPromotionsRequest $request)`, `show(int $promotionId)`, `summary(AdminListPromotionsRequest $request)`, `evaluate(EvaluateEligibilityRequest $request)`, `updateStatus(UpdatePromotionStatusRequest $request, int $promotionId)`, `setDeadline(SetEnrollmentDeadlineRequest $request, ?int $promotionId = null)`, `sendReminder(SendReminderRequest $request, int $promotionId)`, `dispatchScheduledReminders()`, `reminders(int $promotionId)`, `audit(int $promotionId)`, `expireDeadlines()`, `adminCompleteEnrollment(ParentEnrollmentStepRequest $request, int $promotionId)`, `levelProgressions()`, `upsertLevelProgression(UpsertLevelProgressionRequest $request)`, `seedLevelProgressions()`
**Detected dependencies:** Services: `LevelProgressionService`, `PromotionAuditService`, `PromotionEligibilityService`, `PromotionEnrollmentService`, `PromotionQueryService`, `PromotionReminderService`, `PromotionStatusService` | Requests: `AdminListPromotionsRequest`, `EvaluateEligibilityRequest`, `ParentEnrollmentStepRequest`, `SendReminderRequest`, `SetEnrollmentDeadlineRequest`, `UpdatePromotionStatusRequest`, `UpsertLevelProgressionRequest` | Resources: `LevelProgressionResource`, `PromotionAuditLogResource`, `PromotionReminderResource`, `StudentPromotionResource` | Models: `PromotionAuditLog`, `PromotionReminderLog`, `StudentPromotionRecord`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Mutating endpoints need request validation, service-layer ownership, and database transactions where multiple rows change.
- This controller is large enough to hide bugs. Split orchestration from business logic before it becomes archaeology.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record.
### AdministratorTeacherSubmissionController
**File:** `Api/Administrator/AdministratorTeacherSubmissionController.php`
**Purpose:** manage school identity and operations workflow for administrator teacher submission.
**Public methods:** `index()`, `notify(Request $request)`
**Detected dependencies:** Services: `AdministratorTeacherSubmissionService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
### EmergencyContactController
**File:** `Api/Administrator/EmergencyContactController.php`
**Purpose:** manage school identity and operations workflow for emergency contact.
**Public methods:** `index(Request $request)`, `show(EmergencyContactParentRequest $request, int $contactId)`, `update(EmergencyContactUpdateRequest $request, int $contactId)`, `destroy(EmergencyContactParentRequest $request, int $contactId)`
**Detected dependencies:** Services: `EmergencyContactCrudService`, `EmergencyContactDirectoryService` | Requests: `EmergencyContactParentRequest`, `EmergencyContactUpdateRequest` | Resources: `EmergencyContactGroupResource`, `EmergencyContactResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### TeacherClassAssignmentController
**File:** `Api/Administrator/TeacherClassAssignmentController.php`
**Purpose:** manage school identity and operations workflow for teacher class assignment.
**Public methods:** `index(TeacherAssignmentListRequest $request)`, `store(TeacherAssignmentStoreRequest $request)`, `destroy(TeacherAssignmentDeleteRequest $request)`
**Detected dependencies:** Services: `TeacherAssignmentService` | Requests: `TeacherAssignmentDeleteRequest`, `TeacherAssignmentListRequest`, `TeacherAssignmentStoreRequest` | Resources: `TeacherAssignmentResource`, `TeacherClassResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; delete success, already deleted, protected record.
## Assignment
### AssignmentApiController
**File:** `Api/Assignment/AssignmentApiController.php`
**Purpose:** serve assignment api API responsibilities.
**Public methods:** `index(Request $request)`, `store(Request $request)`, `classAssignmentData()`
**Detected dependencies:** Services: `AssignmentService` | Resources: `AssignmentOverviewResource`, `AssignmentSectionResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission.
## Attendance
### AdminAttendanceApiController
**File:** `Api/Attendance/AdminAttendanceApiController.php`
**Purpose:** manage attendance workflow for admin attendance api.
**Public methods:** `dailyData(Request $request)`, `updateManagement(UpdateAttendanceManagementRequest $request)`, `addEntry(AdminAddAttendanceEntryRequest $request)`
**Detected dependencies:** Services: `AttendanceQueryService`, `AttendanceService` | Requests: `AdminAddAttendanceEntryRequest`, `UpdateAttendanceManagementRequest` | Resources: `DailyAttendanceResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; update authorization, partial payload, concurrency/transaction rollback.
### AttendanceCommentTemplateController
**File:** `Api/Attendance/AttendanceCommentTemplateController.php`
**Purpose:** manage attendance workflow for attendance comment template.
**Public methods:** `bootstrapUrls()`, `index(Request $request)`, `listData(Request $request)`, `show(int $id)`, `store(Request $request)`, `update(Request $request, int $id)`, `destroy(int $id)`, `legacySave(Request $request)`, `legacyDelete(Request $request)`
**Detected dependencies:** Services: `ApplicationUrlService`, `AttendanceCommentTemplateService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Mutating endpoints need request validation, service-layer ownership, and database transactions where multiple rows change.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### EarlyDismissalsController
**File:** `Api/Attendance/EarlyDismissalsController.php`
**Purpose:** manage attendance workflow for early dismissals.
**Public methods:** `index(Request $request)`, `studentOptions()`, `store(Request $request)`, `uploadSignature(Request $request)`
**Detected dependencies:** Models: `Configuration`, `EarlyDismissalSignature`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Extract business logic into service/action classes if the controller currently queries models or mutates state directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission.
### LateSlipLogsController
**File:** `Api/Attendance/LateSlipLogsController.php`
**Purpose:** manage attendance workflow for late slip logs.
**Public methods:** `index(LateSlipLogIndexRequest $request)`, `show(int $id)`, `destroy(int $id)`
**Detected dependencies:** Services: `LateSlipLogCommandService`, `LateSlipLogQueryService` | Requests: `LateSlipLogIndexRequest` | Resources: `LateSlipLogCollection`, `LateSlipLogResource` | Models: `LateSlipLog`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; delete success, already deleted, protected record.
### StaffAttendanceApiController
**File:** `Api/Attendance/StaffAttendanceApiController.php`
**Purpose:** manage attendance workflow for staff attendance api.
**Public methods:** `monthData(Request $request)`, `admins(Request $request)`, `saveAdmins(SaveAdminAttendanceRequest $request)`, `saveCell(SaveStaffAttendanceCellRequest $request)`, `monthCsv(Request $request)`
**Detected dependencies:** Services: `StaffAttendanceService` | Requests: `SaveAdminAttendanceRequest`, `SaveStaffAttendanceCellRequest` | Resources: `AdminAttendanceResource`, `StaffMonthResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; update authorization, partial payload, concurrency/transaction rollback.
### TeacherAttendanceApiController
**File:** `Api/Attendance/TeacherAttendanceApiController.php`
**Purpose:** manage attendance workflow for teacher attendance api.
**Public methods:** `grid(Request $request)`, `form(Request $request)`, `submit(TeacherSubmitAttendanceRequest $request)`
**Detected dependencies:** Services: `AttendanceQueryService`, `AttendanceService` | Requests: `TeacherSubmitAttendanceRequest` | Resources: `TeacherAttendanceFormResource`, `TeacherGridResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission.
## AttendanceTracking
### AttendanceTrackingController
**File:** `Api/AttendanceTracking/AttendanceTrackingController.php`
**Purpose:** manage attendance workflow for attendance tracking.
**Public methods:** `pendingViolations(Request $request)`, `notifiedViolations(Request $request)`, `studentCase(int $studentId, Request $request)`, `record(Request $request)`, `sendAutoEmails(Request $request)`, `compose(Request $request)`, `sendManualEmail(Request $request)`, `parentsInfo(Request $request)`, `saveNotificationNote(Request $request)`
**Detected dependencies:** Services: `AttendanceTrackingService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Auth
### AuthController
**File:** `Api/Auth/AuthController.php`
**Purpose:** handle authentication/authorization workflow for auth.
**Public methods:** `login(Request $request, ApiLoginSecurityService $security)`, `refresh(Request $request)`, `me()`, `logout(Request $request)`
**Detected dependencies:** Services: `ApiLoginSecurityService` | Models: `User`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: happy path, unauthorized path, invalid input, service exception; role matrix: allowed, denied, expired session.
### AuthSessionController
**File:** `Api/Auth/AuthSessionController.php`
**Purpose:** handle authentication/authorization workflow for auth session.
**Public methods:** `loginMask(Request $request)`, `login(LoginSessionRequest $request)`, `logout(Request $request)`, `selectRole(Request $request)`, `setRole(SetRoleSessionRequest $request)`
**Detected dependencies:** Services: `ApplicationUrlService`, `ApiLoginSecurityService`, `AuthSessionService` | Requests: `LoginSessionRequest`, `SetRoleSessionRequest` | Models: `User`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- This controller is large enough to hide bugs. Split orchestration from business logic before it becomes archaeology.
- Feature tests: happy path, unauthorized path, invalid input, service exception; role matrix: allowed, denied, expired session.
### IpBanController
**File:** `Api/Auth/IpBanController.php`
**Purpose:** handle authentication/authorization workflow for ip ban.
**Public methods:** `index(IpBanIndexRequest $request)`, `show(int $id)`, `ban(IpBanRequest $request)`, `unban(IpUnbanRequest $request)`
**Detected dependencies:** Services: `IpBanCommandService`, `IpBanQueryService` | Requests: `IpBanIndexRequest`, `IpBanRequest`, `IpUnbanRequest` | Resources: `IpBanCollection`, `IpBanResource` | Models: `IpAttempt`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; role matrix: allowed, denied, expired session.
### RegisterController
**File:** `Api/Auth/RegisterController.php`
**Purpose:** handle authentication/authorization workflow for register.
**Public methods:** `captcha()`, `store(Request $request)`
**Detected dependencies:** Services: `CodeIgniterApiRegistrationService`, `RegistrationCaptchaService`, `RegistrationService` | Resources: `RegisterResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: create/submit validation, happy path, duplicate submission; role matrix: allowed, denied, expired session.
### RolePermissionController
**File:** `Api/Auth/RolePermissionController.php`
**Purpose:** handle authentication/authorization workflow for role permission.
**Public methods:** `roles(RoleListRequest $request)`, `showRole(int $roleId)`, `storeRole(RoleStoreRequest $request)`, `updateRole(RoleUpdateRequest $request, int $roleId)`, `deleteRole(int $roleId)`, `users(UserRoleListRequest $request)`, `assignRoles(AssignUserRolesRequest $request, int $userId)`, `permissions()`, `showPermission(int $permissionId)`, `storePermission(PermissionStoreRequest $request)`, `updatePermission(PermissionUpdateRequest $request, int $permissionId)`, `deletePermission(int $permissionId)`, `rolePermissions(int $roleId)`, `updateRolePermissions(RolePermissionUpdateRequest $request, int $roleId)`
**Detected dependencies:** Services: `PermissionCrudService`, `RoleAssignmentService`, `RoleCrudService`, `RolePermissionService`, `RoleQueryService` | Requests: `AssignUserRolesRequest`, `PermissionStoreRequest`, `PermissionUpdateRequest`, `RoleListRequest`, `RolePermissionUpdateRequest`, `RoleStoreRequest`, `RoleUpdateRequest`, `UserRoleListRequest` | Resources: `PermissionResource`, `RolePermissionResource`, `RoleResource`, `UserWithRolesResource` | Models: `Permission`, `Role`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: update authorization, partial payload, concurrency/transaction rollback; role matrix: allowed, denied, expired session.
### RoleSwitcherController
**File:** `Api/Auth/RoleSwitcherController.php`
**Purpose:** handle authentication/authorization workflow for role switcher.
**Public methods:** `index()`, `switch(RoleSwitchRequest $request)`
**Detected dependencies:** Services: `RoleSwitchService` | Requests: `RoleSwitchRequest`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; role matrix: allowed, denied, expired session.
### SessionTimeoutController
**File:** `Api/Auth/SessionTimeoutController.php`
**Purpose:** handle authentication/authorization workflow for session timeout.
**Public methods:** `getTimeoutConfig()`, `checkTimeout(Request $request)`, `pingActivity(Request $request)`
**Detected dependencies:** Services: `ApplicationUrlService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Feature tests: happy path, unauthorized path, invalid input, service exception; role matrix: allowed, denied, expired session.
## BadgeScan
### BadgeScanController
**File:** `Api/BadgeScan/BadgeScanController.php`
**Purpose:** serve badge scan API responsibilities.
**Public methods:** `scan(Request $request)`, `logs()`
**Detected dependencies:** Services: `BadgeScanService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Badges
### BadgeController
**File:** `Api/Badges/BadgeController.php`
**Purpose:** serve badge API responsibilities.
**Public methods:** `generatePdf(Request $request)`, `printStatus(Request $request)`, `logPrint(Request $request)`, `formData(Request $request)`
**Detected dependencies:** Services: `BadgeFormDataService`, `BadgePdfService`, `BadgePrintLogService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Certificates
### CertificateController
**File:** `Api/Certificates/CertificateController.php`
**Purpose:** serve certificate API responsibilities.
**Public methods:** `formOptions(Request $request)`, `generate(Request $request)`
**Detected dependencies:** Services: `CertificatePdfService` | Models: `Configuration`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## ClassPreparation
### ClassPreparationController
**File:** `Api/ClassPreparation/ClassPreparationController.php`
**Purpose:** serve class preparation API responsibilities.
**Public methods:** `index(ClassPreparationIndexRequest $request)`, `markPrinted(ClassPreparationMarkPrintedRequest $request)`, `saveAdjustments(ClassPreparationAdjustmentRequest $request)`, `print(ClassPreparationPrintRequest $request)`, `stickerCounts(Request $request)`, `studentsByClass(Request $request, int $classSectionId)`
**Detected dependencies:** Services: `ClassRosterService`, `StickerCountService`, `ClassPreparationService` | Requests: `ClassPreparationAdjustmentRequest`, `ClassPreparationIndexRequest`, `ClassPreparationMarkPrintedRequest`, `ClassPreparationPrintRequest` | Resources: `ClassPreparationPrintResource`, `ClassPreparationResultResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Validate file type, size, storage path, and access ownership.
- Generated documents need reproducible inputs and predictable naming.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
## ClassProgress
### ClassProgressController
**File:** `Api/ClassProgress/ClassProgressController.php`
**Purpose:** serve class progress API responsibilities.
**Public methods:** `meta(ClassProgressMetaRequest $request)`, `legacySubmitForm(ClassProgressMetaRequest $request)`, `index(ClassProgressIndexRequest $request)`, `store(ClassProgressStoreRequest $request)`, `show(ClassProgressReport $class_progress)`, `update(ClassProgressUpdateRequest $request, ClassProgressReport $class_progress)`, `destroy(ClassProgressReport $class_progress)`, `downloadAttachment(int $attachment)`, `downloadLegacyAttachment(ClassProgressReport $class_progress)`
**Detected dependencies:** Services: `ClassProgressAttachmentService`, `ClassProgressMetaService`, `ClassProgressMutationService`, `ClassProgressQueryService` | Requests: `ClassProgressIndexRequest`, `ClassProgressMetaRequest`, `ClassProgressStoreRequest`, `ClassProgressUpdateRequest` | Resources: `ClassProgressGroupCollection`, `ClassProgressReportResource`, `ClassProgressShowResource` | Models: `ClassProgressAttachment`, `ClassProgressReport`, `Configuration`, `User`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
## Classes
### ClassController
**File:** `Api/Classes/ClassController.php`
**Purpose:** serve class API responsibilities.
**Public methods:** `index(ClassSectionIndexRequest $request)`, `show(ClassSection $classSection)`, `store(ClassSectionStoreRequest $request)`, `update(ClassSectionUpdateRequest $request, ClassSection $classSection)`, `destroy(ClassSection $classSection)`, `attendance(Request $request, int $classSectionId)`, `seedDefaults()`
**Detected dependencies:** Services: `ClassAttendanceService`, `ClassSectionCommandService`, `ClassSectionQueryService`, `ClassSectionSeedService` | Requests: `ClassSectionIndexRequest`, `ClassSectionStoreRequest`, `ClassSectionUpdateRequest` | Resources: `ClassAttendanceResource`, `ClassSectionCollection`, `ClassSectionResource` | Models: `ClassSection`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
## Communication
### CommunicationController
**File:** `Api/Communication/CommunicationController.php`
**Purpose:** serve communication API responsibilities.
**Public methods:** `options()`, `families(int $studentId)`, `guardians(int $familyId)`, `preview(Request $request)`, `send(Request $request)`
**Detected dependencies:** Services: `CommunicationFamilyService`, `CommunicationPreviewService`, `CommunicationSendService`, `CommunicationStudentService`, `CommunicationTemplateService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## CompetitionScores
### CompetitionScoresController
**File:** `Api/CompetitionScores/CompetitionScoresController.php`
**Purpose:** manage academic scoring/grading workflow for competition scores.
**Public methods:** `index(Request $request)`, `edit(Request $request, int $id)`, `save(Request $request, int $id)`
**Detected dependencies:** Services: `CompetitionScoresContextService`, `CompetitionScoresQueryService`, `CompetitionScoresRosterService`, `CompetitionScoresSaveService` | Models: `Competition`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission.
## Core
### BaseApiController
**File:** `Api/Core/BaseApiController.php`
**Purpose:** shared API response, validation, auth, and compatibility foundation.
**Public methods:** _No public endpoint methods detected._
**Detected dependencies:** Models: `User`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Extract business logic into service/action classes if the controller currently queries models or mutates state directly.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- This controller is large enough to hide bugs. Split orchestration from business logic before it becomes archaeology.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Discounts
### DiscountController
**File:** `Api/Discounts/DiscountController.php`
**Purpose:** serve discount API responsibilities.
**Public methods:** `options()`, `apply(ApplyDiscountVoucherRequest $request)`, `listVouchers()`, `storeVoucher(StoreDiscountVoucherRequest $request)`, `updateVoucher(UpdateDiscountVoucherRequest $request, int $id)`, `showVoucher(int $id)`, `deleteVoucher(int $id)`
**Detected dependencies:** Services: `DiscountApplyService`, `DiscountContextService`, `DiscountParentService`, `DiscountVoucherService` | Requests: `ApplyDiscountVoucherRequest`, `StoreDiscountVoucherRequest`, `UpdateDiscountVoucherRequest` | Resources: `DiscountParentResource`, `DiscountVoucherResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Documentation
### ApiDocsAdminController
**File:** `Api/Documentation/ApiDocsAdminController.php`
**Purpose:** serve api docs admin API responsibilities.
**Public methods:** `index()`, `public()`
**Detected dependencies:** Services: `ApiDocsService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
### DocsCatalogController
**File:** `Api/Documentation/DocsCatalogController.php`
**Purpose:** serve docs catalog API responsibilities.
**Public methods:** `index(Request $request)`, `ui()`, `swagger()`, `swaggerMergedJson()`
**Detected dependencies:** Services: `DocsCatalogService`, `OpenApiRouteExporter`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Validate file type, size, storage path, and access ownership.
- Generated documents need reproducible inputs and predictable naming.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
## Email
### BroadcastEmailController
**File:** `Api/Email/BroadcastEmailController.php`
**Purpose:** serve broadcast email API responsibilities.
**Public methods:** `options()`, `send(Request $request)`, `uploadImage(Request $request)`
**Detected dependencies:** Services: `BroadcastEmailComposerService`, `BroadcastEmailDispatchService`, `BroadcastEmailImageService`, `BroadcastEmailRecipientService`, `BroadcastEmailSenderOptionsService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### EmailController
**File:** `Api/Email/EmailController.php`
**Purpose:** serve email API responsibilities.
**Public methods:** `senders()`, `send(EmailSendRequest $request)`
**Detected dependencies:** Services: `EmailAttachmentService`, `EmailDispatchService`, `EmailSenderOptionsService` | Requests: `EmailSendRequest` | Resources: `EmailSenderResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### EmailExtractorController
**File:** `Api/Email/EmailExtractorController.php`
**Purpose:** serve email extractor API responsibilities.
**Public methods:** `emails()`, `compare(EmailExtractorCompareRequest $request)`
**Detected dependencies:** Services: `EmailExtractorService` | Requests: `EmailExtractorCompareRequest` | Resources: `EmailExtractorCompareResource`, `EmailExtractorEmailsResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Exams
### ExamDraftController
**File:** `Api/Exams/ExamDraftController.php`
**Purpose:** serve exam draft API responsibilities.
**Public methods:** `teacherIndex()`, `teacherStore(ExamDraftTeacherStoreRequest $request)`, `adminIndex()`, `adminUploadLegacy(ExamDraftAdminLegacyRequest $request)`, `adminReview(ExamDraftAdminReviewRequest $request)`
**Detected dependencies:** Services: `ExamDraftAdminService`, `ExamDraftTeacherService` | Requests: `ExamDraftAdminLegacyRequest`, `ExamDraftAdminReviewRequest`, `ExamDraftTeacherStoreRequest` | Resources: `ExamDraftResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Expenses
### ExpenseController
**File:** `Api/Expenses/ExpenseController.php`
**Purpose:** serve expense API responsibilities.
**Public methods:** `options()`, `index()`, `show(int $id)`, `store(StoreExpenseRequest $request)`, `update(UpdateExpenseRequest $request, int $id)`, `updateStatus(UpdateExpenseStatusRequest $request, int $id)`
**Detected dependencies:** Services: `ExpenseContextService`, `ExpenseQueryService`, `ExpenseReceiptService`, `ExpenseRetailorService`, `ExpenseStaffService`, `ExpenseStatusService`, `ExpenseWriteService` | Requests: `StoreExpenseRequest`, `UpdateExpenseRequest`, `UpdateExpenseStatusRequest` | Resources: `ExpenseResource`, `ExpenseStaffResource` | Models: `Expense`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Mutating endpoints need request validation, service-layer ownership, and database transactions where multiple rows change.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback.
## ExtraCharges
### ExtraChargesController
**File:** `Api/ExtraCharges/ExtraChargesController.php`
**Purpose:** manage finance workflow for extra charges, with money-state integrity as the main risk.
**Public methods:** `list(Request $request)`, `options(Request $request)`, `parentOptions(Request $request)`, `invoicesForParent(Request $request)`, `store(StoreExtraChargeRequest $request)`, `update(UpdateExtraChargeRequest $request, int $id)`, `void(int $id)`, `reverse(int $id)`
**Detected dependencies:** Services: `ExtraChargesChargeService`, `ExtraChargesContextService`, `ExtraChargesInvoiceService`, `ExtraChargesListService`, `ExtraChargesMetaService`, `ExtraChargesParentService` | Requests: `StoreExtraChargeRequest`, `UpdateExtraChargeRequest` | Resources: `ExtraChargeInvoiceOptionResource`, `ExtraChargeParentOptionResource`, `ExtraChargeResource` | Models: `AdditionalCharge`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; idempotency and ledger/audit consistency.
## Family
### FamilyAdminController
**File:** `Api/Family/FamilyAdminController.php`
**Purpose:** manage school identity and operations workflow for family admin.
**Public methods:** `index(FamilyAdminIndexRequest $request)`, `search(FamilyAdminSearchRequest $request)`, `card(FamilyAdminCardRequest $request)`, `composeEmail(FamilyComposeEmailRequest $request)`
**Detected dependencies:** Services: `FamilyNotificationService`, `FamilyQueryService` | Requests: `FamilyAdminCardRequest`, `FamilyAdminIndexRequest`, `FamilyAdminSearchRequest`, `FamilyComposeEmailRequest` | Resources: `FamilyResource`, `FamilySearchItemResource` | Models: `Configuration`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
### FamilyController
**File:** `Api/Family/FamilyController.php`
**Purpose:** manage school identity and operations workflow for family.
**Public methods:** `familiesByStudent(FamiliesByStudentRequest $request, int $studentId)`, `guardiansByFamily(GuardiansByFamilyRequest $request, int $familyId)`, `bootstrap(FamilyBootstrapRequest $request)`, `attachSecondByUser(FamilyAttachSecondByUserRequest $request)`, `attachSecondByEmail(FamilyAttachSecondByEmailRequest $request)`, `setPrimaryHome(FamilySetPrimaryHomeRequest $request)`, `setGuardianFlags(FamilySetGuardianFlagsRequest $request)`, `unlinkGuardian(FamilyUnlinkGuardianRequest $request)`, `unlinkStudent(FamilyUnlinkStudentRequest $request)`, `importSecondParentsFromLegacy(FamilyImportLegacyRequest $request)`
**Detected dependencies:** Services: `FamilyMutationService`, `FamilyQueryService` | Requests: `FamiliesByStudentRequest`, `FamilyAttachSecondByEmailRequest`, `FamilyAttachSecondByUserRequest`, `FamilyBootstrapRequest`, `FamilyImportLegacyRequest`, `FamilySetGuardianFlagsRequest`, `FamilySetPrimaryHomeRequest`, `FamilyUnlinkGuardianRequest`… | Resources: `FamilyGuardianResource`, `FamilyResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Finance
### ChargeController
**File:** `Api/Finance/ChargeController.php`
**Purpose:** manage finance workflow for charge, with money-state integrity as the main risk.
**Public methods:** `index(ChargeListRequest $request)`, `storeExtra(StoreExtraChargeRequest $request)`, `storeEvent(StoreEventChargeRequest $request)`, `cancelExtra(int $id)`, `applyExtra(ApplyExtraChargeRequest $request, int $id)`, `cancelEvent(Request $request, int $id)`, `markEventPaid(MarkEventChargePaidRequest $request, int $id)`
**Detected dependencies:** Services: `ChargeService` | Requests: `ApplyExtraChargeRequest`, `ChargeListRequest`, `MarkEventChargePaidRequest`, `StoreEventChargeRequest`, `StoreExtraChargeRequest` | Resources: `ChargeActionResource`, `ChargeListResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; idempotency and ledger/audit consistency.
### FeeCalculationController
**File:** `Api/Finance/FeeCalculationController.php`
**Purpose:** manage finance workflow for fee calculation, with money-state integrity as the main risk.
**Public methods:** `refund(FeeRefundRequest $request)`, `tuitionTotal(FeeTuitionTotalRequest $request)`, `tuitionBreakdown(FeeTuitionBreakdownRequest $request)`, `familyBalance(FeeFamilyBalanceRequest $request)`
**Detected dependencies:** Services: `BalanceCalculationService`, `FeeRefundCalculatorService`, `FeeStudentFeeService`, `TuitionCalculationService` | Requests: `FeeFamilyBalanceRequest`, `FeeRefundRequest`, `FeeTuitionBreakdownRequest`, `FeeTuitionTotalRequest` | Resources: `FeeFamilyBalanceResource`, `FeeRefundResource`, `FeeTuitionBreakdownResource`, `FeeTuitionTotalResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: happy path, unauthorized path, invalid input, service exception; idempotency and ledger/audit consistency.
### FinancialController
**File:** `Api/Finance/FinancialController.php`
**Purpose:** manage finance workflow for financial, with money-state integrity as the main risk.
**Public methods:** `report(FinancialReportRequest $request)`, `summary(FinancialSummaryRequest $request)`, `unpaidParents(FinancialUnpaidParentsRequest $request)`, `downloadCsv(FinancialReportRequest $request)`, `downloadPdf(FinancialReportRequest $request)`
**Detected dependencies:** Services: `FinancialPdfReportService`, `FinancialReportService`, `FinancialSchoolYearService`, `FinancialSummaryService`, `FinancialUnpaidParentsService` | Requests: `FinancialReportRequest`, `FinancialSummaryRequest`, `FinancialUnpaidParentsRequest` | Resources: `FinancialReportResource`, `FinancialSummaryResource`, `FinancialUnpaidParentResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Validate file type, size, storage path, and access ownership.
- Generated documents need reproducible inputs and predictable naming.
- Feature tests: happy path, unauthorized path, invalid input, service exception; idempotency and ledger/audit consistency.
### InvoiceController
**File:** `Api/Finance/InvoiceController.php`
**Purpose:** manage finance workflow for invoice, with money-state integrity as the main risk.
**Public methods:** `management(InvoiceManagementRequest $request)`, `generate(Request $request)`, `byParent(InvoiceParentRequest $request, int $parentId)`, `parentPayment(InvoiceParentRequest $request)`, `updateStatus(InvoiceStatusRequest $request, int $invoiceId)`, `unpaid()`, `pdf(int $invoiceId)`
**Detected dependencies:** Services: `InvoiceGenerationService`, `InvoiceManagementService`, `InvoicePaymentService`, `InvoicePdfService` | Requests: `InvoiceManagementRequest`, `InvoiceParentRequest`, `InvoiceStatusRequest` | Resources: `InvoiceManagementParentResource`, `InvoiceResource` | Models: `Invoice`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception; idempotency and ledger/audit consistency.
### PaymentController
**File:** `Api/Finance/PaymentController.php`
**Purpose:** manage finance workflow for payment, with money-state integrity as the main risk.
**Public methods:** `store(Request $request)`, `byParent(PaymentByParentRequest $request, int $parentId)`, `updateBalance(Request $request, int $paymentId)`
**Detected dependencies:** Services: `PaymentBalanceService`, `PaymentLookupService`, `PaymentPlanService` | Requests: `PaymentByParentRequest` | Resources: `PaymentResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: create/submit validation, happy path, duplicate submission; idempotency and ledger/audit consistency.
### PaymentEventChargesController
**File:** `Api/Finance/PaymentEventChargesController.php`
**Purpose:** manage finance workflow for payment event charges, with money-state integrity as the main risk.
**Public methods:** `index(PaymentEventChargesListRequest $request)`, `store(Request $request)`, `enrolledStudents(PaymentEventChargesListRequest $request, int $parentId)`
**Detected dependencies:** Services: `PaymentEventChargesService` | Requests: `PaymentEventChargesListRequest`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; idempotency and ledger/audit consistency.
### PaymentManualController
**File:** `Api/Finance/PaymentManualController.php`
**Purpose:** manage finance workflow for payment manual, with money-state integrity as the main risk.
**Public methods:** `search(Request $request)`, `suggest(Request $request)`, `record(PaymentManualUpdateRequest $request, int $invoiceId)`, `edit(PaymentManualEditRequest $request, int $paymentId)`, `file(Request $request, string $filename)`
**Detected dependencies:** Services: `PaymentManualService` | Requests: `PaymentManualEditRequest`, `PaymentManualUpdateRequest`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception; idempotency and ledger/audit consistency.
### PaymentNotificationController
**File:** `Api/Finance/PaymentNotificationController.php`
**Purpose:** manage finance workflow for payment notification, with money-state integrity as the main risk.
**Public methods:** `index(PaymentNotificationListRequest $request)`, `send(PaymentNotificationSendRequest $request)`
**Detected dependencies:** Services: `PaymentNotificationService` | Requests: `PaymentNotificationListRequest`, `PaymentNotificationSendRequest` | Resources: `PaymentNotificationLogResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; idempotency and ledger/audit consistency.
### PaymentTransactionController
**File:** `Api/Finance/PaymentTransactionController.php`
**Purpose:** manage finance workflow for payment transaction, with money-state integrity as the main risk.
**Public methods:** `store(Request $request)`, `byPayment(int $paymentId)`, `updateStatus(Request $request, string $transactionId)`
**Detected dependencies:** Services: `PaymentTransactionService` | Resources: `PaymentTransactionResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: create/submit validation, happy path, duplicate submission; idempotency and ledger/audit consistency.
### PaypalPaymentController
**File:** `Api/Finance/PaypalPaymentController.php`
**Purpose:** manage finance workflow for paypal payment, with money-state integrity as the main risk.
**Public methods:** `redirect()`, `create(int $paymentId)`, `execute(PaypalExecuteRequest $request)`, `cancel()`
**Detected dependencies:** Services: `PaypalPaymentService` | Requests: `PaypalExecuteRequest`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: create/submit validation, happy path, duplicate submission; idempotency and ledger/audit consistency.
### PaypalTransactionsController
**File:** `Api/Finance/PaypalTransactionsController.php`
**Purpose:** manage finance workflow for paypal transactions, with money-state integrity as the main risk.
**Public methods:** `index(PaypalTransactionsListRequest $request)`, `downloadCsv(PaypalTransactionsListRequest $request)`
**Detected dependencies:** Services: `PaypalTransactionsService` | Requests: `PaypalTransactionsListRequest` | Resources: `PaypalTransactionResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; idempotency and ledger/audit consistency.
### PurchaseOrderController
**File:** `Api/Finance/PurchaseOrderController.php`
**Purpose:** manage finance workflow for purchase order, with money-state integrity as the main risk.
**Public methods:** `index(PurchaseOrderIndexRequest $request)`, `options()`, `show(int $id)`, `store(Request $request)`, `receive(Request $request, int $id)`, `cancel(int $id)`
**Detected dependencies:** Services: `PurchaseOrderCreateService`, `PurchaseOrderQueryService`, `PurchaseOrderReceiveService`, `PurchaseOrderStatusService` | Requests: `PurchaseOrderIndexRequest` | Resources: `PurchaseOrderItemResource`, `PurchaseOrderResource` | Models: `PurchaseOrder`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; idempotency and ledger/audit consistency.
### RefundController
**File:** `Api/Finance/RefundController.php`
**Purpose:** manage finance workflow for refund, with money-state integrity as the main risk.
**Public methods:** `index(RefundIndexRequest $request)`, `show(int $refundId)`, `store(RefundStoreRequest $request)`, `update(RefundDecisionRequest $request, int $refundId)`, `destroy(int $refundId)`, `approve(int $refundId)`, `reject(RefundRejectRequest $request, int $refundId)`, `recordPayment(RefundPaymentRequest $request, int $refundId)`, `recalculateOverpayments(RefundRecalculateRequest $request)`, `parentBalances(int $parentId)`
**Detected dependencies:** Services: `RefundDecisionService`, `RefundOverpaymentService`, `RefundPayoutService`, `RefundQueryService`, `RefundRequestService`, `RefundSummaryService` | Requests: `RefundDecisionRequest`, `RefundIndexRequest`, `RefundPaymentRequest`, `RefundRecalculateRequest`, `RefundRejectRequest`, `RefundStoreRequest` | Resources: `RefundResource` | Models: `Configuration`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record; idempotency and ledger/audit consistency.
### ReimbursementController
**File:** `Api/Finance/ReimbursementController.php`
**Purpose:** manage finance workflow for reimbursement, with money-state integrity as the main risk.
**Public methods:** `underProcessing(ReimbursementUnderProcessingRequest $request)`, `markDonation(Request $request)`, `createBatch(Request $request)`, `updateBatchAssignment(ReimbursementBatchAssignmentRequest $request)`, `lockBatch(ReimbursementBatchLockRequest $request)`, `uploadBatchAdminFile(ReimbursementBatchAdminFileRequest $request)`, `serveAdminCheckFile(FileNameRequest $request, string $name, string $mode = 'inline')`, `index(ReimbursementIndexRequest $request)`, `sendBatchEmail(ReimbursementBatchEmailRequest $request)`, `export(ReimbursementExportRequest $request)`, `exportBatch(ReimbursementExportBatchRequest $request)`, `store(Request $request)`, `process(ReimbursementProcessRequest $request)`, `reimbursedExpenses()`, `update(Request $request, int $id)`
**Detected dependencies:** Services: `FileServeService`, `ReimbursementBatchAssignmentService`, `ReimbursementBatchService`, `ReimbursementContextService`, `ReimbursementCrudService`, `ReimbursementDonationService`, `ReimbursementEmailService`, `ReimbursementExportService`… | Requests: `FileNameRequest`, `ReimbursementBatchAdminFileRequest`, `ReimbursementBatchAssignmentRequest`, `ReimbursementBatchEmailRequest`, `ReimbursementBatchLockRequest`, `ReimbursementExportBatchRequest`, `ReimbursementExportRequest`, `ReimbursementIndexRequest`… | Resources: `ReimbursementBatchResource`, `ReimbursementExpenseResource`, `ReimbursementRecipientResource`, `ReimbursementResource`, `ReimbursementUnderProcessingItemResource` | Models: `Reimbursement`, `ReimbursementBatch`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; idempotency and ledger/audit consistency.
## Frontend
### FrontendController
**File:** `Api/Frontend/FrontendController.php`
**Purpose:** serve frontend API responsibilities.
**Public methods:** `index()`, `facility()`, `team()`, `callToAction()`, `testimonial()`, `notFound()`, `fetchUser()`
**Detected dependencies:** Services: `FrontendPageService` | Resources: `FrontendPageResource`, `FrontendUserResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
### InfoIconController
**File:** `Api/Frontend/InfoIconController.php`
**Purpose:** serve info icon API responsibilities.
**Public methods:** `profileIcon()`
**Detected dependencies:** Services: `ProfileIconService` | Resources: `ProfileIconResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### LandingPageController
**File:** `Api/Frontend/LandingPageController.php`
**Purpose:** serve landing page API responsibilities.
**Public methods:** `index(LandingTeacherRequest $request)`, `teacher(LandingTeacherRequest $request)`, `parent()`, `administrator()`, `admin()`, `student()`, `guest()`
**Detected dependencies:** Services: `LandingPageService` | Requests: `LandingTeacherRequest` | Resources: `LandingPageResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
### PageController
**File:** `Api/Frontend/PageController.php`
**Purpose:** serve page API responsibilities.
**Public methods:** `privacyPolicy()`, `termsOfService()`, `helpCenter()`, `submitContact(ContactSubmitRequest $request)`
**Detected dependencies:** Services: `ContactSubmissionService`, `StaticPageService` | Requests: `ContactSubmitRequest` | Resources: `ContactSubmissionResource`, `PageContentResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Grading
### GradingController
**File:** `Api/Grading/GradingController.php`
**Purpose:** manage academic scoring/grading workflow for grading.
**Public methods:** `overview(GradingOverviewRequest $request)`, `show(GradingScoreShowRequest $request, string $type, int $classSectionId, int $studentId)`, `update(GradingScoreUpdateRequest $request)`, `toggleLock(GradingLockRequest $request)`, `lockAll(GradingLockAllRequest $request)`, `refresh(GradingRefreshRequest $request)`, `placement(PlacementRequest $request)`, `updatePlacementLevel(PlacementLevelRequest $request)`, `updatePlacementLevels(PlacementLevelsRequest $request)`, `createPlacementBatch(PlacementBatchRequest $request)`, `showPlacementBatch(int $batchId)`, `updatePlacementBatch(PlacementBatchUpdateRequest $request, int $batchId)`, `belowSixty(BelowSixtyListRequest $request)`, `belowSixtyEmail(BelowSixtyEmailRequest $request)`, `sendBelowSixtyEmail(BelowSixtySendRequest $request)`, `updateBelowSixtyStatus(BelowSixtyStatusRequest $request)`, `belowSixtyMeeting(BelowSixtyMeetingRequest $request)`, `saveBelowSixtyMeeting(BelowSixtyMeetingSaveRequest $request)`
**Detected dependencies:** Services: `GradingBelowSixtyService`, `GradingLockService`, `GradingOverviewService`, `GradingPlacementService`, `GradingRefreshService`, `GradingScoreService` | Requests: `BelowSixtyEmailRequest`, `BelowSixtyMeetingRequest`, `BelowSixtyMeetingSaveRequest`, `BelowSixtySendRequest`, `BelowSixtyStatusRequest`, `BelowSixtyListRequest`, `GradingLockAllRequest`, `GradingLockRequest`… | Resources: `BelowSixtyStudentResource`, `GradingScoreResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: show success, missing record, unauthorized record; update authorization, partial payload, concurrency/transaction rollback.
### HomeworkTrackingController
**File:** `Api/Grading/HomeworkTrackingController.php`
**Purpose:** manage academic scoring/grading workflow for homework tracking.
**Public methods:** `index(HomeworkTrackingRequest $request)`
**Detected dependencies:** Services: `HomeworkTrackingService` | Requests: `HomeworkTrackingRequest` | Resources: `HomeworkTrackingTeacherResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Validate file type, size, storage path, and access ownership.
- Generated documents need reproducible inputs and predictable naming.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
## Incidents
### IncidentController
**File:** `Api/Incidents/IncidentController.php`
**Purpose:** serve incident API responsibilities.
**Public methods:** `current()`, `formMeta()`, `history(IncidentListRequest $request)`, `processed(IncidentListRequest $request)`, `analysis(IncidentListRequest $request)`, `studentsByGrade(int $gradeId)`, `store(Request $request)`, `updateState(IncidentStateRequest $request, int $incidentId)`, `close(Request $request, int $incidentId)`, `cancel(IncidentCancelRequest $request, int $incidentId)`
**Detected dependencies:** Services: `CurrentIncidentService`, `IncidentAnalysisService`, `IncidentHistoryService` | Requests: `IncidentCancelRequest`, `IncidentCloseRequest`, `IncidentListRequest`, `IncidentStateRequest` | Resources: `IncidentAnalysisStudentResource`, `IncidentGradeResource`, `IncidentResource`, `IncidentStudentOptionResource` | Models: `Configuration`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Mutating endpoints need request validation, service-layer ownership, and database transactions where multiple rows change.
- Feature tests: create/submit validation, happy path, duplicate submission.
## Inventory
### InventoryCategoryController
**File:** `Api/Inventory/InventoryCategoryController.php`
**Purpose:** provide CRUD API endpoints for inventory category.
**Public methods:** `index(InventoryCategoryIndexRequest $request)`, `store(InventoryCategoryStoreRequest $request)`, `update(InventoryCategoryUpdateRequest $request, int $id)`, `destroy(int $id)`
**Detected dependencies:** Services: `InventoryCategoryService` | Requests: `InventoryCategoryIndexRequest`, `InventoryCategoryStoreRequest`, `InventoryCategoryUpdateRequest` | Resources: `InventoryCategoryResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### InventoryController
**File:** `Api/Inventory/InventoryController.php`
**Purpose:** serve inventory API responsibilities.
**Public methods:** `index(InventoryItemIndexRequest $request)`, `show(int $id)`, `store(InventoryItemStoreRequest $request)`, `update(InventoryItemUpdateRequest $request, int $id)`, `destroy(int $id)`, `audit(InventoryAuditRequest $request, int $id)`, `adjust(InventoryAdjustRequest $request, int $id)`, `summary(string $type)`, `summaryAll()`, `teacherDistribution(InventoryTeacherDistributionRequest $request)`, `teacherDistributionStore(InventoryTeacherDistributionStoreRequest $request)`
**Detected dependencies:** Services: `InventoryItemService`, `InventorySummaryService`, `InventoryTeacherDistributionService` | Requests: `InventoryAdjustRequest`, `InventoryAuditRequest`, `InventoryItemIndexRequest`, `InventoryItemStoreRequest`, `InventoryItemUpdateRequest`, `InventoryTeacherDistributionRequest`, `InventoryTeacherDistributionStoreRequest` | Resources: `InventoryItemResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Mutating endpoints need request validation, service-layer ownership, and database transactions where multiple rows change.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### InventoryMovementController
**File:** `Api/Inventory/InventoryMovementController.php`
**Purpose:** serve inventory movement API responsibilities.
**Public methods:** `index(InventoryMovementIndexRequest $request)`, `store(InventoryMovementStoreRequest $request)`, `update(InventoryMovementUpdateRequest $request, int $id)`, `destroy(int $id)`, `bulkDelete(InventoryMovementBulkDeleteRequest $request)`
**Detected dependencies:** Services: `InventoryMovementService` | Requests: `InventoryMovementBulkDeleteRequest`, `InventoryMovementIndexRequest`, `InventoryMovementStoreRequest`, `InventoryMovementUpdateRequest` | Resources: `InventoryMovementResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### SupplierController
**File:** `Api/Inventory/SupplierController.php`
**Purpose:** provide CRUD API endpoints for supplier.
**Public methods:** `index(SupplierIndexRequest $request)`, `store(SupplierStoreRequest $request)`, `update(SupplierUpdateRequest $request, int $id)`, `destroy(int $id)`
**Detected dependencies:** Services: `SupplierService` | Requests: `SupplierIndexRequest`, `SupplierStoreRequest`, `SupplierUpdateRequest` | Resources: `SupplierResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### SupplyCategoryController
**File:** `Api/Inventory/SupplyCategoryController.php`
**Purpose:** provide CRUD API endpoints for supply category.
**Public methods:** `index()`, `store(SupplyCategoryStoreRequest $request)`, `update(SupplyCategoryUpdateRequest $request, int $id)`, `destroy(int $id)`
**Detected dependencies:** Services: `SupplyCategoryService` | Requests: `SupplyCategoryStoreRequest`, `SupplyCategoryUpdateRequest` | Resources: `SupplyCategoryResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
## Messaging
### MessagesController
**File:** `Api/Messaging/MessagesController.php`
**Purpose:** serve messages API responsibilities.
**Public methods:** `index(MessageIndexRequest $request)`, `inbox(MessageIndexRequest $request)`, `sent(MessageIndexRequest $request)`, `drafts(MessageIndexRequest $request)`, `trash(MessageIndexRequest $request)`, `show(int $id)`, `store(MessageSendRequest $request)`, `receive()`, `recipients(string $type)`, `update(MessageUpdateRequest $request, int $id)`, `destroy(int $id)`
**Detected dependencies:** Services: `MessageCommandService`, `MessageQueryService`, `MessageRecipientService` | Requests: `MessageIndexRequest`, `MessageSendRequest`, `MessageUpdateRequest` | Resources: `MessageCollection`, `MessageResource`, `RecipientResource` | Models: `Message`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### WhatsappController
**File:** `Api/Messaging/WhatsappController.php`
**Purpose:** serve whatsapp API responsibilities.
**Public methods:** `index(WhatsappLinkIndexRequest $request)`, `show(int $linkId)`, `store(WhatsappLinkStoreRequest $request)`, `update(WhatsappLinkUpdateRequest $request, int $linkId)`, `destroy(int $linkId)`, `parentContacts(WhatsappParentContactsRequest $request)`, `parentContactsByClass(WhatsappParentContactsByClassRequest $request)`, `sendInvites(WhatsappInviteSendRequest $request)`, `updateMembership(WhatsappMembershipUpdateRequest $request)`
**Detected dependencies:** Services: `WhatsappContactService`, `WhatsappContextService`, `WhatsappInviteService`, `WhatsappLinkService`, `WhatsappMembershipService` | Requests: `WhatsappInviteSendRequest`, `WhatsappLinkIndexRequest`, `WhatsappLinkStoreRequest`, `WhatsappLinkUpdateRequest`, `WhatsappMembershipUpdateRequest`, `WhatsappParentContactsByClassRequest`, `WhatsappParentContactsRequest` | Resources: `WhatsappClassSectionContactResource`, `WhatsappGroupLinkCollection`, `WhatsappGroupLinkResource`, `WhatsappParentContactResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
## Notifications
### NotificationController
**File:** `Api/Notifications/NotificationController.php`
**Purpose:** serve notification API responsibilities.
**Public methods:** `index(NotificationIndexRequest $request)`, `show(int $notificationId)`, `store(NotificationSendRequest $request)`, `update(NotificationUpdateRequest $request, int $notificationId)`, `destroy(int $notificationId)`, `restore(int $notificationId)`, `markRead(int $notificationId)`, `active(NotificationActiveRequest $request)`, `deleted(NotificationDeletedRequest $request)`
**Detected dependencies:** Services: `NotificationActiveService`, `NotificationDeletedService`, `NotificationManagementService`, `NotificationReadService`, `NotificationSendService`, `NotificationShowService`, `NotificationUserListService` | Requests: `NotificationActiveRequest`, `NotificationDeletedRequest`, `NotificationIndexRequest`, `NotificationSendRequest`, `NotificationUpdateRequest` | Resources: `NotificationResource`, `UserNotificationResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
## Parents
### AuthorizedUserInviteController
**File:** `Api/Parents/AuthorizedUserInviteController.php`
**Purpose:** handle authentication/authorization workflow for authorized user invite.
**Public methods:** `confirm(Request $request)`, `setPasswordForm(Request $request, int $authorizedUserId)`, `savePassword(Request $request, int $authorizedUserId)`
**Detected dependencies:** Services: `AuthorizedUsersManagementService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception; role matrix: allowed, denied, expired session.
### AuthorizedUsersController
**File:** `Api/Parents/AuthorizedUsersController.php`
**Purpose:** handle authentication/authorization workflow for authorized users.
**Public methods:** `index()`, `show(int $id)`, `store(StoreAuthorizedUserRequest $request)`, `update(UpdateAuthorizedUserRequest $request, int $id)`, `destroy(int $id)`
**Detected dependencies:** Services: `AuthorizedUsersManagementService` | Requests: `StoreAuthorizedUserRequest`, `UpdateAuthorizedUserRequest` | Models: `AuthorizedUser`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record; role matrix: allowed, denied, expired session.
### ParentAttendanceReportController
**File:** `Api/Parents/ParentAttendanceReportController.php`
**Purpose:** manage attendance workflow for parent attendance report.
**Public methods:** `form()`, `submit(ParentAttendanceReportSubmitRequest $request)`, `list(ParentAttendanceReportListRequest $request)`, `checkExisting(ParentAttendanceReportCheckRequest $request)`, `update(ParentAttendanceReportUpdateRequest $request, int $reportId)`
**Detected dependencies:** Services: `ParentAttendanceReportService` | Requests: `ParentAttendanceReportSubmitRequest`, `ParentAttendanceReportListRequest`, `ParentAttendanceReportCheckRequest`, `ParentAttendanceReportUpdateRequest` | Resources: `ParentAttendanceReportResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback.
### ParentController
**File:** `Api/Parents/ParentController.php`
**Purpose:** manage school identity and operations workflow for parent.
**Public methods:** `attendance(ParentAttendanceRequest $request)`, `invoices(ParentInvoiceRequest $request)`, `enrollments(ParentEnrollmentRequest $request)`, `updateEnrollments(ParentEnrollmentActionRequest $request)`, `registration()`, `storeRegistration(ParentRegistrationRequest $request)`, `updateStudent(ParentStudentUpdateRequest $request, int $studentId)`, `deleteStudent(int $studentId)`, `emergencyContacts()`, `storeEmergencyContact(ParentEmergencyContactRequest $request)`, `updateEmergencyContact(ParentEmergencyContactRequest $request, int $contactId)`, `profile()`, `updateProfile(ParentProfileUpdateRequest $request)`, `events()`, `updateParticipation(ParentEventParticipationRequest $request)`
**Detected dependencies:** Services: `ParentAttendanceService`, `ParentEmergencyContactService`, `ParentEnrollmentService`, `ParentEventParticipationService`, `ParentInvoiceService`, `ParentProfileService`, `ParentRegistrationService` | Requests: `ParentAttendanceRequest`, `ParentEnrollmentActionRequest`, `ParentEnrollmentRequest`, `ParentEmergencyContactRequest`, `ParentEventParticipationRequest`, `ParentInvoiceRequest`, `ParentProfileUpdateRequest`, `ParentRegistrationRequest`… | Resources: `ParentAttendanceResource`, `ParentEmergencyContactResource`, `ParentStudentResource`, `InvoiceResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### ParentPromotionController
**File:** `Api/Parents/ParentPromotionController.php`
**Purpose:** manage school identity and operations workflow for parent promotion.
**Public methods:** `overview(ParentPromotionOverviewRequest $request)`, `show(int $promotionId)`, `start(int $promotionId)`, `updateSteps(ParentEnrollmentStepRequest $request, int $promotionId)`, `submit(int $promotionId)`
**Detected dependencies:** Services: `PromotionEnrollmentService`, `PromotionQueryService` | Requests: `ParentEnrollmentStepRequest`, `ParentPromotionOverviewRequest` | Resources: `StudentPromotionResource` | Models: `Student`, `StudentPromotionRecord`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission.
## PrintRequests
### PrintRequestsController
**File:** `Api/PrintRequests/PrintRequestsController.php`
**Purpose:** serve print requests API responsibilities.
**Public methods:** `teacher()`, `admin()`, `store(Request $request)`, `teacherUpdate(Request $request, int $id)`, `adminStatus(Request $request, int $id)`, `destroy(int $id)`, `copy(int $id)`, `handCopy(Request $request)`, `download(int $id)`
**Detected dependencies:** Services: `PrintRequestsPortalService` | Models: `PrintRequest`, `User`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: create/submit validation, happy path, duplicate submission; delete success, already deleted, protected record.
## Public
### PublicWinnersController
**File:** `Api/Public/PublicWinnersController.php`
**Purpose:** serve public winners API responsibilities.
**Public methods:** `competitionIndex()`, `competitionShow(int $id)`
**Detected dependencies:** Services: `PublicWinnersPortalService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Reports
### FilesController
**File:** `Api/Reports/FilesController.php`
**Purpose:** serve files API responsibilities.
**Public methods:** `receipt(FileNameRequest $request, string $name)`, `reimb(FileNameRequest $request, string $name)`, `earlyDismissalSignature(FileNameRequest $request, string $name)`, `examDraftTeacher(FileNameRequest $request, string $name)`, `examDraftFinal(FileNameRequest $request, string $name)`
**Detected dependencies:** Services: `ExamDraftDownloadNameService`, `FileServeService` | Requests: `FileNameRequest` | Resources: `FileMetaResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### ReportCardsController
**File:** `Api/Reports/ReportCardsController.php`
**Purpose:** serve report cards API responsibilities.
**Public methods:** `meta(ReportCardMetaRequest $request)`, `completeness(ReportCardCompletenessRequest $request)`, `acknowledgement(Request $request)`, `studentReport(ReportCardPdfRequest $request, int $studentId)`, `classReport(ReportCardPdfRequest $request, int $classSectionId)`
**Detected dependencies:** Services: `ReportCardService` | Requests: `ReportCardCompletenessRequest`, `ReportCardMetaRequest`, `ReportCardPdfRequest` | Resources: `ReportCardAcknowledgementResource`, `ReportCardClassSectionResource`, `ReportCardCompletenessStudentResource`, `ReportCardStudentMetaResource` | Models: `Configuration`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Validate file type, size, storage path, and access ownership.
- Generated documents need reproducible inputs and predictable naming.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### SlipPrinterController
**File:** `Api/Reports/SlipPrinterController.php`
**Purpose:** serve slip printer API responsibilities.
**Public methods:** `print(SlipPrintRequest $request)`, `preview(SlipPreviewRequest $request)`, `logs(SlipLogListRequest $request)`, `reprint(SlipReprintRequest $request)`
**Detected dependencies:** Services: `SlipPrinterService` | Requests: `SlipLogListRequest`, `SlipPreviewRequest`, `SlipPrintRequest`, `SlipReprintRequest` | Resources: `LateSlipLogResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### StickersController
**File:** `Api/Reports/StickersController.php`
**Purpose:** serve stickers API responsibilities.
**Public methods:** `formData(StickerFormDataRequest $request)`, `studentsByClass(StickerStudentsByClassRequest $request)`, `print(StickerPrintRequest $request)`
**Detected dependencies:** Services: `StickerPresetService`, `StickerPrintService`, `StickerQueryService` | Requests: `StickerFormDataRequest`, `StickerPrintRequest`, `StickerStudentsByClassRequest` | Resources: `StickerClassSectionResource`, `StickerPresetResource`, `StickerStudentResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Validate file type, size, storage path, and access ownership.
- Generated documents need reproducible inputs and predictable naming.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Root
### BaseApiController
**File:** `Api/BaseApiController.php`
**Purpose:** shared API response, validation, auth, and compatibility foundation.
**Public methods:** _No public endpoint methods detected._
**Detected dependencies:** Models: `User`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Extract business logic into service/action classes if the controller currently queries models or mutates state directly.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- This controller is large enough to hide bugs. Split orchestration from business logic before it becomes archaeology.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### RolePermissionController
**File:** `Api/RolePermissionController.php`
**Purpose:** handle authentication/authorization workflow for role permission.
**Public methods:** `roles(RoleListRequest $request)`, `showRole(int $roleId)`, `storeRole(RoleStoreRequest $request)`, `updateRole(RoleUpdateRequest $request, int $roleId)`, `deleteRole(int $roleId)`, `users(UserRoleListRequest $request)`, `assignRoles(AssignUserRolesRequest $request, int $userId)`, `permissions()`, `showPermission(int $permissionId)`, `storePermission(PermissionStoreRequest $request)`, `updatePermission(PermissionUpdateRequest $request, int $permissionId)`, `deletePermission(int $permissionId)`, `rolePermissions(int $roleId)`, `updateRolePermissions(RolePermissionUpdateRequest $request, int $roleId)`
**Detected dependencies:** Services: `PermissionCrudService`, `RoleAssignmentService`, `RoleCrudService`, `RolePermissionService`, `RoleQueryService` | Requests: `AssignUserRolesRequest`, `PermissionStoreRequest`, `PermissionUpdateRequest`, `RoleListRequest`, `RolePermissionUpdateRequest`, `RoleStoreRequest`, `RoleUpdateRequest`, `UserRoleListRequest` | Resources: `PermissionResource`, `RolePermissionResource`, `RoleResource`, `UserWithRolesResource` | Models: `Permission`, `Role`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: update authorization, partial payload, concurrency/transaction rollback; role matrix: allowed, denied, expired session.
### RoleSwitcherController
**File:** `Api/RoleSwitcherController.php`
**Purpose:** handle authentication/authorization workflow for role switcher.
**Public methods:** `index()`, `switch(RoleSwitchRequest $request)`
**Detected dependencies:** Services: `RoleSwitchService` | Requests: `RoleSwitchRequest`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; role matrix: allowed, denied, expired session.
### ScannerController
**File:** `Api/ScannerController.php`
**Purpose:** serve scanner API responsibilities.
**Public methods:** `process(Request $request)`
**Detected dependencies:** Models: `AttendanceData`, `AttendanceDay`, `AttendanceRecord`, `Configuration`, `CurrentFlag`, `LateSlipLog`, `Payment`, `SemesterScore`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Extract business logic into service/action classes if the controller currently queries models or mutates state directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Feature tests: create/submit validation, happy path, duplicate submission.
### StatsController
**File:** `Api/StatsController.php`
**Purpose:** provide CRUD API endpoints for stats.
**Public methods:** `index()`
**Detected dependencies:** Models: `Stats`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Extract business logic into service/action classes if the controller currently queries models or mutates state directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
### UserController
**File:** `Api/UserController.php`
**Purpose:** serve user API responsibilities.
**Public methods:** `index(UserListRequest $request)`, `store(UserStoreRequest $request)`, `update(UserUpdateRequest $request, int $userId)`, `destroy(int $userId)`, `loginActivity(LoginActivityRequest $request)`
**Detected dependencies:** Services: `LoginActivityService`, `UserListService`, `UserManagementService` | Requests: `LoginActivityRequest`, `UserListRequest`, `UserStoreRequest`, `UserUpdateRequest` | Resources: `LoginActivityResource`, `UserWithRolesResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
## Scores
### FinalController
**File:** `Api/Scores/FinalController.php`
**Purpose:** manage academic scoring/grading workflow for final.
**Public methods:** `index(Request $request)`, `update(ScoreUpdateRequest $request)`, `bySchoolYear(Request $request)`
**Detected dependencies:** Services: `ExamScoreService`, `SemesterScoreService` | Requests: `ScoreUpdateRequest` | Resources: `ScoreStudentResource` | Models: `Student`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; update authorization, partial payload, concurrency/transaction rollback.
### HomeworkController
**File:** `Api/Scores/HomeworkController.php`
**Purpose:** manage academic scoring/grading workflow for homework.
**Public methods:** `index(Request $request)`, `update(ScoreUpdateRequest $request)`, `addColumn(ScoreAddColumnRequest $request)`, `bySchoolYear(Request $request)`
**Detected dependencies:** Services: `HomeworkScoreService`, `SemesterScoreService` | Requests: `ScoreAddColumnRequest`, `ScoreUpdateRequest` | Resources: `ScoreStudentResource` | Models: `Student`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; update authorization, partial payload, concurrency/transaction rollback.
### MidtermController
**File:** `Api/Scores/MidtermController.php`
**Purpose:** manage academic scoring/grading workflow for midterm.
**Public methods:** `index(Request $request)`, `update(ScoreUpdateRequest $request)`, `bySchoolYear(Request $request)`
**Detected dependencies:** Services: `ExamScoreService`, `SemesterScoreService` | Requests: `ScoreUpdateRequest` | Resources: `ScoreStudentResource` | Models: `Student`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; update authorization, partial payload, concurrency/transaction rollback.
### ParticipationController
**File:** `Api/Scores/ParticipationController.php`
**Purpose:** manage academic scoring/grading workflow for participation.
**Public methods:** `index(Request $request)`, `update(ScoreUpdateRequest $request)`, `bySchoolYear(Request $request)`
**Detected dependencies:** Services: `ParticipationScoreService`, `SemesterScoreService` | Requests: `ScoreUpdateRequest` | Resources: `ScoreStudentResource` | Models: `Student`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; update authorization, partial payload, concurrency/transaction rollback.
### ProjectController
**File:** `Api/Scores/ProjectController.php`
**Purpose:** manage academic scoring/grading workflow for project.
**Public methods:** `index(Request $request)`, `update(ScoreUpdateRequest $request)`, `addColumn(ScoreAddColumnRequest $request)`, `bySchoolYear(Request $request)`
**Detected dependencies:** Services: `ProjectScoreService`, `SemesterScoreService` | Requests: `ScoreAddColumnRequest`, `ScoreUpdateRequest` | Resources: `ScoreStudentResource` | Models: `Student`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; update authorization, partial payload, concurrency/transaction rollback.
### QuizController
**File:** `Api/Scores/QuizController.php`
**Purpose:** manage academic scoring/grading workflow for quiz.
**Public methods:** `index(Request $request)`, `update(ScoreUpdateRequest $request)`, `addColumn(ScoreAddColumnRequest $request)`, `bySchoolYear(Request $request)`
**Detected dependencies:** Services: `QuizScoreService`, `SemesterScoreService` | Requests: `ScoreAddColumnRequest`, `ScoreUpdateRequest` | Resources: `ScoreStudentResource` | Models: `Student`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; update authorization, partial payload, concurrency/transaction rollback.
### ScoreCommentController
**File:** `Api/Scores/ScoreCommentController.php`
**Purpose:** manage academic scoring/grading workflow for score comment.
**Public methods:** `index(ScoreCommentListRequest $request)`, `store(ScoreCommentSaveRequest $request)`, `update(ScoreCommentUpdateRequest $request)`
**Detected dependencies:** Services: `ScoreCommentService` | Requests: `ScoreCommentListRequest`, `ScoreCommentSaveRequest`, `ScoreCommentUpdateRequest` | Resources: `ScoreCommentResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Mutating endpoints need request validation, service-layer ownership, and database transactions where multiple rows change.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback.
### ScoreController
**File:** `Api/Scores/ScoreController.php`
**Purpose:** manage academic scoring/grading workflow for score.
**Public methods:** `overview(ScoreOverviewRequest $request)`, `lock(ScoreLockRequest $request)`, `studentScores(ScoreStudentRequest $request)`
**Detected dependencies:** Services: `ScoreDashboardService` | Requests: `ScoreLockRequest`, `ScoreOverviewRequest`, `ScoreStudentRequest` | Resources: `ScoreStudentResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### ScorePredictorController
**File:** `Api/Scores/ScorePredictorController.php`
**Purpose:** manage academic scoring/grading workflow for score predictor.
**Public methods:** `index(ScorePredictorRequest $request)`
**Detected dependencies:** Services: `ScorePredictorService` | Requests: `ScorePredictorRequest` | Resources: `ScorePredictorStudentResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Validate file type, size, storage path, and access ownership.
- Generated documents need reproducible inputs and predictable naming.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
## Settings
### ConfigurationAdminController
**File:** `Api/Settings/ConfigurationAdminController.php`
**Purpose:** serve configuration admin API responsibilities.
**Public methods:** `index()`, `store(ConfigurationStoreRequest $request)`, `update(ConfigurationUpdateRequest $request, int $id)`, `destroy(int $id)`, `getByKey(string $configKey)`
**Detected dependencies:** Services: `ConfigurationService` | Requests: `ConfigurationStoreRequest`, `ConfigurationUpdateRequest` | Resources: `ConfigurationResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### EventController
**File:** `Api/Settings/EventController.php`
**Purpose:** serve event API responsibilities.
**Public methods:** `index(EventIndexRequest $request)`, `show(int $eventId)`, `store(EventStoreRequest $request)`, `update(EventUpdateRequest $request, int $eventId)`, `destroy(int $eventId)`, `charges(EventChargeIndexRequest $request)`, `updateCharges(EventChargeUpdateRequest $request, int $eventId)`, `studentsWithCharges(EventStudentsWithChargesRequest $request)`
**Detected dependencies:** Services: `EventCategoryService`, `EventChargeQueryService`, `EventChargeService`, `EventListService`, `EventManagementService`, `EventStudentChargeService` | Requests: `EventChargeIndexRequest`, `EventChargeUpdateRequest`, `EventIndexRequest`, `EventStoreRequest`, `EventStudentsWithChargesRequest`, `EventUpdateRequest` | Resources: `EventChargeResource`, `EventResource`, `EventStudentChargeResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Money operations must be idempotent, auditable, and transaction-safe.
- Never trust client-calculated totals; recompute server-side.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### PolicyController
**File:** `Api/Settings/PolicyController.php`
**Purpose:** serve policy API responsibilities.
**Public methods:** `school(PolicyShowRequest $request)`, `picture(PolicyShowRequest $request)`
**Detected dependencies:** Services: `PolicyContentService` | Requests: `PolicyShowRequest` | Resources: `PolicyResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### PreferencesController
**File:** `Api/Settings/PreferencesController.php`
**Purpose:** serve preferences API responsibilities.
**Public methods:** `index(PreferencesIndexRequest $request)`, `show()`, `showForUser(int $userId)`, `store(PreferencesUpsertRequest $request)`, `updateForUser(PreferencesUpsertRequest $request, int $userId)`, `destroy(int $userId)`
**Detected dependencies:** Services: `PreferencesCommandService`, `PreferencesQueryService` | Requests: `PreferencesIndexRequest`, `PreferencesUpsertRequest` | Resources: `PreferencesCollection`, `PreferencesResource` | Models: `Preferences`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; delete success, already deleted, protected record.
### SchoolCalendarController
**File:** `Api/Settings/SchoolCalendarController.php`
**Purpose:** serve school calendar API responsibilities.
**Public methods:** `options(SchoolCalendarOptionsRequest $request)`, `index(SchoolCalendarIndexRequest $request)`, `teacherCalendarLegacy(SchoolCalendarIndexRequest $request)`, `show(int $eventId)`, `store(SchoolCalendarStoreRequest $request)`, `update(SchoolCalendarUpdateRequest $request, int $eventId)`, `destroy(int $eventId)`
**Detected dependencies:** Services: `SchoolCalendarContextService`, `SchoolCalendarFormatterService`, `SchoolCalendarMeetingService`, `SchoolCalendarMutationService`, `SchoolCalendarQueryService` | Requests: `SchoolCalendarIndexRequest`, `SchoolCalendarOptionsRequest`, `SchoolCalendarStoreRequest`, `SchoolCalendarUpdateRequest` | Resources: `SchoolCalendarEventDetailResource`, `SchoolCalendarEventResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Mutating endpoints need request validation, service-layer ownership, and database transactions where multiple rows change.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### SettingsController
**File:** `Api/Settings/SettingsController.php`
**Purpose:** provide CRUD API endpoints for settings.
**Public methods:** `index()`, `update(SettingsUpdateRequest $request)`
**Detected dependencies:** Services: `SettingsService` | Requests: `SettingsUpdateRequest` | Resources: `SettingsResource` | Models: `Setting`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; update authorization, partial payload, concurrency/transaction rollback.
## Staff
### StaffController
**File:** `Api/Staff/StaffController.php`
**Purpose:** manage school identity and operations workflow for staff.
**Public methods:** `index(StaffIndexRequest $request)`, `show(int $id)`, `store(StaffStoreRequest $request)`, `update(StaffUpdateRequest $request, int $id)`, `destroy(int $id)`
**Detected dependencies:** Services: `StaffCommandService`, `StaffQueryService` | Requests: `StaffIndexRequest`, `StaffStoreRequest`, `StaffUpdateRequest` | Resources: `StaffCollection`, `StaffResource` | Models: `Staff`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
### TeacherController
**File:** `Api/Staff/TeacherController.php`
**Purpose:** manage school identity and operations workflow for teacher.
**Public methods:** `classes(TeacherClassViewRequest $request)`, `switchClass(TeacherSwitchClassRequest $request)`, `absenceForm()`, `submitAbsence(TeacherAbsenceSubmitRequest $request)`
**Detected dependencies:** Services: `TeacherAbsenceService`, `TeacherDashboardService` | Requests: `TeacherAbsenceSubmitRequest`, `TeacherClassViewRequest`, `TeacherSwitchClassRequest` | Resources: `TeacherAbsenceResource`, `TeacherClassResource`, `TeacherStudentResource` | Models: `User`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### TimeOffNotificationController
**File:** `Api/Staff/TimeOffNotificationController.php`
**Purpose:** manage school identity and operations workflow for time off notification.
**Public methods:** `notify(string $token)`
**Detected dependencies:** Services: `EmailDispatchService`, `StaffTimeOffLinkService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Students
### StudentController
**File:** `Api/Students/StudentController.php`
**Purpose:** manage school identity and operations workflow for student.
**Public methods:** `assignments(StudentAssignmentListRequest $request)`, `index(Request $request)`, `scoreCardSelectable(Request $request)`, `show(int $studentId)`, `store(Request $request)`, `assignClass(StudentAssignClassRequest $request)`, `removeClass(StudentRemoveClassRequest $request)`, `removed(StudentAssignmentListRequest $request)`, `setActive(StudentSetActiveRequest $request)`, `autoDistribute(StudentAutoDistributeRequest $request)`, `promotionTotals(StudentPromotionTotalsRequest $request)`, `update(StudentUpdateRequest $request, int $studentId)`, `destroy(int $studentId)`, `classes(Request $request, int $studentId)`, `assignClassForStudent(Request $request, int $studentId)`, `removeClassForStudent(int $studentId, int $classSectionId)`, `promote(Request $request, int $studentId)`, `attendance(Request $request, int $studentId)`, `incidents(Request $request, int $studentId)`, `scores(Request $request, int $studentId)`, `notes(int $studentId)`, `parents(int $studentId)`, `emergencyContacts(int $studentId)`, `addEmergencyContact(Request $request, int $studentId)`, `updateEmergencyContact(Request $request, int $studentId, int $contactId)`, `updateBadgeScan(Request $request, int $studentId)`, `uploadPhoto(Request $request, int $studentId)`, `photo(int $studentId)`, `scoreCard(int $studentId)`
**Detected dependencies:** Services: `StudentAssignmentService`, `StudentAutoDistributionService`, `StudentDirectoryService`, `StudentProfileService`, `StudentScoreCardService`, `StudentStatusService` | Requests: `StudentAssignClassRequest`, `StudentAssignmentListRequest`, `StudentAutoDistributeRequest`, `StudentPromotionTotalsRequest`, `StudentRemoveClassRequest`, `StudentSetActiveRequest`, `StudentUpdateRequest` | Resources: `StudentAssignmentResource`, `StudentClassSectionResource`, `StudentRemovedResource`, `StudentScoreCardRowResource` | Models: `AttendanceRecord`, `ClassSection`, `EmergencyContact`, `Incident`, `SemesterScore`, `Student`, `StudentClass`, `User`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Attendance changes need actor, timestamp, school term, and edit history.
- Define conflict behavior for duplicate scans or same-day edits.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
## Subjects
### SubjectCurriculumController
**File:** `Api/Subjects/SubjectCurriculumController.php`
**Purpose:** provide CRUD API endpoints for subject curriculum.
**Public methods:** `index()`, `show(int $id)`, `store(SubjectCurriculumStoreRequest $request)`, `update(SubjectCurriculumUpdateRequest $request, int $id)`, `destroy(int $id)`
**Detected dependencies:** Services: `SubjectCurriculumService` | Requests: `SubjectCurriculumStoreRequest`, `SubjectCurriculumUpdateRequest` | Resources: `SubjectClassResource`, `SubjectCurriculumResource` | Models: `SubjectCurriculum`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
## Support
### ContactController
**File:** `Api/Support/ContactController.php`
**Purpose:** serve contact API responsibilities.
**Public methods:** `send(ContactSendRequest $request)`
**Detected dependencies:** Services: `ContactMessageService` | Requests: `ContactSendRequest` | Resources: `ContactMessageResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### SupportController
**File:** `Api/Support/SupportController.php`
**Purpose:** serve support API responsibilities.
**Public methods:** `index(SupportRequestIndexRequest $request)`, `store(SupportRequestStoreRequest $request)`, `teacher()`
**Detected dependencies:** Services: `SupportRequestService` | Requests: `SupportRequestIndexRequest`, `SupportRequestStoreRequest` | Resources: `SupportRequestCollection`, `SupportRequestResource` | Models: `SupportRequest`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; create/submit validation, happy path, duplicate submission.
## System
### AccessDeniedController
**File:** `Api/System/AccessDeniedController.php`
**Purpose:** serve access denied API responsibilities.
**Public methods:** `accessDenied()`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Extract business logic into service/action classes if the controller currently queries models or mutates state directly.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### DashboardController
**File:** `Api/System/DashboardController.php`
**Purpose:** serve dashboard API responsibilities.
**Public methods:** `route()`
**Detected dependencies:** Services: `DashboardRouteService` | Resources: `DashboardRouteResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### DashboardRedirectController
**File:** `Api/System/DashboardRedirectController.php`
**Purpose:** serve dashboard redirect API responsibilities.
**Public methods:** `dashboard()`
**Detected dependencies:** Services: `ApplicationUrlService`, `DashboardRouteService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### DatabaseHealthController
**File:** `Api/System/DatabaseHealthController.php`
**Purpose:** provide CRUD API endpoints for database health.
**Public methods:** `index()`
**Detected dependencies:** Services: `DatabaseHealthService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
### HealthController
**File:** `Api/System/HealthController.php`
**Purpose:** provide CRUD API endpoints for health.
**Public methods:** `index()`
**Detected dependencies:** Services: `HealthCheckService`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
### NavBuilderController
**File:** `Api/System/NavBuilderController.php`
**Purpose:** serve nav builder API responsibilities.
**Public methods:** `menu()`, `data()`, `store(NavItemStoreRequest $request)`, `destroy(int $id)`, `reorder(NavItemReorderRequest $request)`
**Detected dependencies:** Services: `NavBuilderService`, `NavbarService` | Requests: `NavItemReorderRequest`, `NavItemStoreRequest` | Resources: `NavBuilderDataResource`, `NavItemResource` | Models: `NavItem`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: create/submit validation, happy path, duplicate submission; delete success, already deleted, protected record.
### SchoolIdController
**File:** `Api/System/SchoolIdController.php`
**Purpose:** serve school id API responsibilities.
**Public methods:** `assign(SchoolIdAssignRequest $request)`, `generateStudent()`, `generateUser()`
**Detected dependencies:** Services: `SchoolIdAssignmentService`, `SchoolIdGenerationService` | Requests: `SchoolIdAssignRequest` | Resources: `SchoolIdResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### SemesterRangeController
**File:** `Api/System/SemesterRangeController.php`
**Purpose:** serve semester range API responsibilities.
**Public methods:** `schoolYearRange(SchoolYearRangeRequest $request)`, `semesterRange(SemesterRangeRequest $request)`, `normalize(SemesterNormalizeRequest $request)`, `resolve(SemesterResolveRequest $request)`
**Detected dependencies:** Services: `SemesterRangeService` | Requests: `SchoolYearRangeRequest`, `SemesterNormalizeRequest`, `SemesterRangeRequest`, `SemesterResolveRequest` | Resources: `SemesterRangeResource`, `SemesterResolveResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### StatsController
**File:** `Api/System/StatsController.php`
**Purpose:** provide CRUD API endpoints for stats.
**Public methods:** `index()`
**Detected dependencies:** Models: `Stats`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Extract business logic into service/action classes if the controller currently queries models or mutates state directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Rate-limit sends and record delivery state; retries must not spam families into oblivion.
- Sanitize templates and recipient selection.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping.
## Ui
### UiController
**File:** `Api/Ui/UiController.php`
**Purpose:** serve ui API responsibilities.
**Public methods:** `style(UiStyleRequest $request)`
**Detected dependencies:** Services: `UiStyleService` | Requests: `UiStyleRequest` | Resources: `UiStyleResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
## Users
### UserController
**File:** `Api/Users/UserController.php`
**Purpose:** serve user API responsibilities.
**Public methods:** `index(UserListRequest $request)`, `store(UserStoreRequest $request)`, `show(int $userId)`, `update(UserUpdateRequest $request, int $userId)`, `destroy(int $userId)`, `loginActivity(LoginActivityRequest $request)`
**Detected dependencies:** Services: `LoginActivityService`, `UserListService`, `UserManagementService` | Requests: `LoginActivityRequest`, `UserListRequest`, `UserStoreRequest`, `UserUpdateRequest` | Resources: `LoginActivityResource`, `UserWithRolesResource` | Models: `User`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Authorization boundaries are the product, not decoration. Test forbidden paths first.
- Avoid leaking whether accounts, roles, or sessions exist unless intended.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: list/filter pagination, empty result, invalid filter, tenant scoping; show success, missing record, unauthorized record; create/submit validation, happy path, duplicate submission; update authorization, partial payload, concurrency/transaction rollback; delete success, already deleted, protected record.
## Utilities
### PhoneFormatterController
**File:** `Api/Utilities/PhoneFormatterController.php`
**Purpose:** serve phone formatter API responsibilities.
**Public methods:** `format(PhoneFormatRequest $request)`
**Detected dependencies:** Services: `PhoneFormatterService` | Requests: `PhoneFormatRequest` | Resources: `PhoneFormatResource`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Keep validation in existing FormRequest classes; check required fields, enum values, date ranges, IDs, file constraints, and cross-field rules.
- Keep controller as orchestration only; move rules/calculation/query composition into the detected service layer and unit-test those services directly.
- Scope every query by school/tenant and role. Humans love accidental data leaks.
- Protect PII in logs, exports, and error payloads.
- Feature tests: happy path, unauthorized path, invalid input, service exception.
### ProofreadController
**File:** `Api/Utilities/ProofreadController.php`
**Purpose:** serve proofread API responsibilities.
**Public methods:** `check(Request $request)`
**Plan**
- Define endpoint contract for each public method: request fields, response resource, status codes, and failure shape.
- Add dedicated FormRequest classes where this still uses raw `Request`; inline validation is a trap wearing a tiny fake mustache.
- Extract business logic into service/action classes if the controller currently queries models or mutates state directly.
- Feature tests: happy path, unauthorized path, invalid input, service exception.