# ParentAuth Module — Architecture Map

> **Last updated:** 2026-06-13
> **Status:** Living document

---

## 1. Purpose & Responsibilities

The ParentAuth module handles **authentication for the parent-facing mobile API**. It provides:

- Phone + PIN login
- OTP-based login (request + verify)
- Token refresh (revoke old, issue new)
- Logout (token revocation)

It does **NOT** manage:
- Parent registration (ParentPortal handles that via admin)
- API business logic (ParentApi handles that)
- Token validation per request (ParentApiAuthMiddleware handles that)

---

## 2. Directory & File Structure

```
app/Modules/ParentAuth/
├── bootstrap.php                              # Empty (no events/permissions needed)
├── ApiRoutes.php                              # 5 API auth routes
├── Controllers/
│   └── Api/
│       └── ParentTokenController.php          # Login, OTP, refresh, logout
└── Services/
    └── ParentAuthService.php                  # Auth logic: find, verify, token CRUD
```

---

## 3. Database Schema

### 3.1 `parent_tokens` Table

| Column | Type | Nullable | Key | Notes |
|--------|------|----------|-----|-------|
| id | int unsigned | NO | PRI | auto_increment |
| parent_id | bigint unsigned | NO | MUL | FK to parent_accounts |
| token | varchar(64) | NO | UNI | 32-byte hex token |
| name | varchar(100) | NO | | Default: 'mobile' |
| device_info | varchar(255) | YES | | Device description |
| push_token | varchar(500) | YES | | Push notification token |
| device_platform | varchar(10) | YES | | 'ios' or 'android' |
| last_used_at | datetime | YES | | Updated by middleware |
| expires_at | datetime | YES | MUL | Token expiry (90 days) |
| is_revoked | tinyint(1) | NO | | Default: 0 |
| created_at | datetime | NO | | |

### 3.2 Auth columns on `parent_accounts`

| Column | Type | Purpose |
|--------|------|---------|
| phone | varchar(30) | Login identifier |
| pin_hash | varchar(255) | Hashed PIN for login |
| otp_code | varchar(6) | Current OTP |
| otp_expires_at | datetime | OTP valid until (5 min) |
| last_login_at | datetime | Updated on token creation |

---

## 4. Routes (5 total)

| Method | Path | Handler | Middleware |
|--------|------|---------|-----------|
| POST | /api/v1/parent/auth/login | ParentTokenController@login | cors |
| POST | /api/v1/parent/auth/otp/request | ParentTokenController@otpRequest | cors |
| POST | /api/v1/parent/auth/otp/verify | ParentTokenController@otpVerify | cors |
| POST | /api/v1/parent/auth/refresh | ParentTokenController@refresh | cors, parent_auth |
| POST | /api/v1/parent/auth/logout | ParentTokenController@logout | cors, parent_auth |

---

## 5. Cross-Module Dependencies

| Module | Dependency |
|--------|-----------|
| ParentApi | Requires valid token issued by ParentAuth |
| ParentApiAuthMiddleware | Reads parent_tokens table |
| App Core | `setCurrentParent()` / `currentParent()` |

---

## 6. Token Security Model

| Property | Value |
|----------|-------|
| Token format | 64-char hex (32 random bytes) |
| TTL | 90 days (configurable: api.token.parent_ttl_hours) |
| Max tokens per parent | 5 |
| Eviction policy | Revoke oldest by last_used_at |
| OTP TTL | 5 minutes |
| OTP format | 6 digits zero-padded |
| PIN hashing | PHP password_verify (bcrypt) |
