# `BaseApiController` plan

## Scope
- **Controller**: `app/Http/Controllers/Api/Core/BaseApiController.php`
- **Purpose**: shared API conveniences:
  - Standard success/error JSON envelope helpers
  - Request payload normalization (JSON body vs query/form)
  - Validation helper compatible with legacy-style rules
  - Lightweight pagination helper for arrays/query builders
  - Current-user resolution helpers (id + role list)

## Key responsibilities
### Response helpers
- `success($data, $message, $code)` → `{ status:true, message, data }`
- `error($message, $code, $errors?)` → `{ status:false, message, errors? }`
- Convenience wrappers:
  - `respondSuccess`, `respondCreated`, `respondDeleted`, `respondError`, `respondValidationError`

### Request normalization
- Stores the underlying Laravel request as `laravelRequest`.
- Wraps it in `request adapter` as `$this->request` for compatibility patterns.
- `payloadData()`:
  - Uses JSON-decoded body when present and valid
  - Falls back to merged query + form data

### Validation
- `validateRequest($data, $rules)`:
  - Normalizes legacy-like rule strings into Laravel rules via `normalizeRules()`.
  - Saves validator to `$this->validator`.
  - Returns `[]` on success, or `errors()->toArray()` on failure.
- `validate($rules)` validates against `payloadData()` and returns boolean.

### Pagination
- `paginate($source, $page, $perPage)` supports:
  - Eloquent builder / query builder
  - Plain arrays
  - Returns `{ data: [...], pagination:{ current_page, per_page, total, total_pages } }`

### Current user helpers
- `getCurrentUserId()` resolves authenticated id from multiple sources.
- `getCurrentUser()`:
  - Loads `User` row
  - Computes display name
  - Loads roles via `user_roles`/`roles` join (best-effort; logs error and returns `roles: []` if it fails)

## Usage guidance (project conventions)
- **Controllers extending `BaseApiController`** should prefer:
  - `respondSuccess`/`respondError` for consistent envelopes where possible.
  - Returning explicit `{ ok: true }` shapes only when required for legacy client compatibility.
- **Validation**:
  - Prefer dedicated `FormRequest` classes for new endpoints.
  - Use `validateRequest/normalizeRules` only for legacy/bridge use cases.

## Test plan (unit)
- `normalizeRules()` conversions:
  - `max_length[n]` → `max:n`, `min_length[n]` → `min:n`, `valid_email` → `email`, `permit_empty` → `nullable`, `is_unique[t.c]` → `unique:t,c`, etc.
- `payloadData()`:
  - JSON body takes precedence when valid
  - Falls back to query+form when no JSON
- `paginate()`:
  - Eloquent builder: returns expected total + slices
  - Array source: returns expected slice
- `getCurrentUser()`:
  - No auth → `null`
  - Role query failure → returns user with empty roles and logs error
