# `AuthorizedUsersController` plan

## Scope
- **Controller**: `app/Http/Controllers/Api/Parents/AuthorizedUsersController.php`
- **Purpose**: parent CRUD for secondary “authorized users” attached to the parent account.
- **Primary dependency**: `App\Services\Parents\AuthorizedUsersManagementService`
- **Model**: `App\Models\AuthorizedUser`

## Routes
All routes are under `v1` + `parents` group:
- Base prefix: `GET/POST/PATCH/DELETE /api/v1/parents/...`
- Group middleware: `parent.access`

Endpoints:
- `GET /api/v1/parents/authorized-users` → `index`
- `GET /api/v1/parents/authorized-users/{id}` → `show`
- `POST /api/v1/parents/authorized-users` → `store`
- `PATCH /api/v1/parents/authorized-users/{id}` → `update`
- `DELETE /api/v1/parents/authorized-users/{id}` → `destroy`

## Authentication & authorization
- Requires authenticated parent context (effectively enforced by `parent.access` + `auth()` usage).
- Ownership check:
  - All record reads/writes are constrained to `AuthorizedUser.user_id = parentId`.

## Requests/validation
- `store`: `StoreAuthorizedUserRequest`
  - Reads validated `email` and lowercases/trims before invite.
- `update`: `UpdateAuthorizedUserRequest`
  - Supports email change; re-invites when email changed.

## Endpoint behavior
### `index`
- Returns all authorized users for the parent ordered by id.
- Response shape uses Base API envelope:
  - `{ status:true, message:"Success", data:[...] }`

### `show`
- Loads an authorized user row for this parent or returns 404.
- Response shape: Base API envelope with the model row.

### `store`
- Invites by email via `AuthorizedUsersManagementService::inviteByEmail($parentId, $email)`.
- If invite already existed / not newly created:
  - Returns `200` success with message explaining email sent conditionally.
- If created:
  - Returns `201` with created id.

### `update`
- If email provided:
  - Calls `changeEmailAndReinvite($row, $email)`
  - On invalid argument: returns `422` with error message
- If email not provided:
  - Returns success message (no-op update)

### `destroy`
- Deletes the owned record and returns success message.

## Error handling
- Unauthenticated → `401` Base API error `"Authentication required."`
- Not found → `404` Base API error `"Authorized user not found."`
- Invalid email change → `422` Base API error with exception message

## Test plan (feature)
- Auth required:
  - Unauthenticated requests → 401 for all endpoints.
- Ownership:
  - Parent cannot read/update/delete someone else’s authorized user (404).
- Store:
  - New email creates record → 201 + id.
  - Existing/duplicate invite path → 200 with “If the email belongs…” message.
- Update:
  - Email change triggers reinvite; invalid email triggers 422.
- Delete:
  - Owned record deleted; subsequent fetch returns 404.

