# User, Profile, and Dashboard Operations

## Purpose

Phase 9 activates the authenticated Mini App bootstrap, dashboard, and profile read/update APIs. It also adds read-only Admin user inspection. All identity, money, eligibility, and maintenance decisions remain server-controlled.

The phase deliberately does not post ledger transactions, complete tasks, activate referrals, claim free rewards, or create withdrawals. Those mutations belong to later phases and must use their own transaction, idempotency, and authorization contracts.

## Endpoints

| Method | Path                          | Authentication        | Additional control                       |
| ------ | ----------------------------- | --------------------- | ---------------------------------------- |
| GET    | `/api/v1/bootstrap`           | Telegram user session | Available during maintenance             |
| GET    | `/api/v1/dashboard`           | Telegram user session | Maintenance and account-ban gates        |
| GET    | `/api/v1/profile`             | Telegram user session | Maintenance and account-ban gates        |
| PATCH  | `/api/v1/profile`             | Telegram user session | CSRF, sensitive rate limit, feature flag |
| GET    | `/api/v1/admin/users`         | Admin session         | Admin IP policy and `users.view`         |
| GET    | `/api/v1/admin/users/:userId` | Admin session         | Admin IP policy, `users.view`, audit     |

`userId` is the public 26-character identifier. Internal database IDs are never accepted from clients.

## Bootstrap response

The bootstrap endpoint assembles:

- Public app name, language, date, timezone, and approved support/legal URLs.
- Active settlement-currency display metadata.
- Active managed links that pass the deployment URL allowlist.
- A validated theme token set, or a safe built-in fallback.
- Deterministic user-scoped feature flags.
- Current maintenance state and public message.
- Current user profile, active scoped restrictions, and unread notification count.
- A server UTC timestamp.

The shared public configuration is cached for 60 seconds. Maintenance state is cached for only three seconds. Redis cache failures are logged and fail open to authoritative database reads; they never turn a cached client value into authority.

## Dashboard response

The dashboard is an aggregation read model. It returns:

- Available, held, and lifetime-earned minor-unit balance projections.
- Settlement currency metadata.
- Current local-day task progress, calculated with IANA timezone boundaries and queried in UTC.
- Referral counts.
- Unread notification count.
- Up to five recent posted transactions affecting the user's available account.
- Up to five safe task previews without destination URLs.
- Optional free-reward availability preview.
- A server UTC timestamp.

All `BIGINT` IDs, amounts, and potentially large counters are returned as decimal strings. Currency decimals describe presentation only; no floating-point balance arithmetic is performed.

The balance snapshot is a read-optimized projection. It is not the ledger authority and cannot be written by this API. Phase 10 owns ledger posting and reconciliation behavior.

## Profile ownership

Telegram owns the user's Telegram ID, first name, last name, username, language code, premium marker, and related Telegram profile state. Those values are synchronized only by a successfully validated Telegram authentication exchange.

The user may update only:

```json
{
  "country_code": "BD",
  "preferred_language": "bn",
  "timezone": "Asia/Dhaka"
}
```

Every field is optional, but at least one must be supplied. A `null` value clears that preference. Country codes are normalized to uppercase, languages must be enabled by public settings, and timezones must be recognized IANA timezones.

The service validates settings and feature flags before opening the write transaction. Inside the transaction it locks the current user row, updates only `country_code` and the allowlisted preference JSON, and records activity containing changed field names only—not preference values.

## Theme and URL safety

Theme JSON is reduced to a closed schema:

- `light` and `dark` palettes with eight named colors each.
- Hex, `rgb[a]`, or `hsl[a]` color forms containing only bounded CSS-value characters.
- Radius from `0` through `32px`.
- Blur mode `controlled` or `none`.
- Boolean reduced-motion preference.

An invalid theme falls back as a whole. Settings and managed links are emitted only when their HTTPS URL passes the deployment-owned domain allowlist. Security origins and primary domains remain deployment configuration, never runtime Admin settings.

## Maintenance behavior

Health, CSRF issuance, authentication, bootstrap, and the exact configured Telegram webhook path remain reachable during maintenance. This lets clients authenticate and receive the maintenance screen while Telegram delivery continues. Other user business endpoints return `MAINTENANCE_ACTIVE`.

An authenticated Admin may access Admin routes during a maintenance window only when the authoritative window explicitly allows Admin access. Client headers cannot create that permission.

## Admin inspection

Admin user inspection is read-only in Phase 9. It provides paginated prefix search, account status filtering, profile data, task/referral/session counts, active restrictions, and currency wallet projections.

- Search input is escaped and passed as SQL parameters.
- Pagination values are validated, capped at 100, and parameterized.
- Telegram IDs and financial values remain decimal strings.
- The detail controller supplies immutable audit context for the PII read.
- No balance, status, ban, session, or Telegram identity mutation exists in this phase.

## Operational checks

```bash
npm run test:unit
npm run test:integration
npm run test:security
npm run check
```

Run the APIs only after migrations and seeds have been applied to the intended Oracle MySQL database. No live database or Telegram environment is required for the automated Phase 9 suite.
