# Route Spec

## Route ID
`notifications-device-token-post`

## Endpoint
`POST /api/v1/notifications/device-tokens`

## Human Description
Registers or refreshes the current signed-in user's Firebase Cloud Messaging token for this Android or iOS installation. Registration is idempotent. If Firebase reuses or rotates a token that was previously attached to another Duuble account on the same installation, ownership is atomically reassigned to the current user.

## Authentication
- Required: `yes`
- Minimum product state: Level 2, registered with completed public profile basics. Phone confirmation and contact synchronization are not required.

## Request
### Headers
- `Content-Type: application/json`

### Body
```json
{"token": "fcm-registration-token", "platform": "android"}
```

### Validation Rules
- `token`: required Firebase registration token, 16-4096 characters, with no whitespace or control characters.
- `platform`: required; exactly `android` or `ios`.
- The raw token is never returned or logged. The server stores a SHA-256 hash for identity/indexing plus the token needed for FCM delivery.
- At most five current tokens are retained per user. Tokens not refreshed for 60 days are stale and are pruned; the app refreshes registration at activation/resume and on Firebase rotation.

## Responses
### Success: `200 OK`
```json
{"success": true, "message": "Notification device registered", "data": {"registered": true}}
```

### Error: `401 Unauthorized`
```json
{"success": false, "error": {"code": "UNAUTHORIZED", "message": "Authentication required.", "details": {}}}
```

### Error: `403 Forbidden`
When returned:
- The authenticated user has not completed Level-2 public profile basics.

```json
{"success": false, "error": {"code": "FORBIDDEN", "message": "Complete profile basics before registering notifications on this device.", "details": {}}}
```

### Error: `422 Unprocessable Entity`
```json
{"success": false, "error": {"code": "VALIDATION_FAILED", "message": "Please fix highlighted fields.", "details": {}}}
```

## Idempotency and Retries
- Idempotent: `yes` for the same user/token/platform.
- Retry after transient network or server failures. Firebase token refresh must call this route again.

## Data & Caching Dependencies
- **Spanner Tables:** `notification_device_tokens (Read/Write)`
- **Firebase:** Firebase Cloud Messaging registration token.

## Side Effects
- Upserts the token for the current user and platform.
- Removes any previous ownership of the same token before assigning it to the current user.
- Prunes stale registrations and oldest registrations beyond the five-device cap.
