# RBAC & Auth Mapping

## spatie/permission Wiring
- Publish migrations: `php artisan vendor:publish --provider="Spatie\\Permission\\PermissionServiceProvider" --tag="migrations"`
- Migrate: `php artisan migrate`
- Model `User` uses `HasRoles`
- Seed roles: admin, operator, member
- Middleware: protect `/api/admin/*` and Filament with `auth` + `role:admin`

## Role Matrix (examples)
- admin: full access to all admin endpoints and Filament resources
- operator: limited access (e.g., content-only resources)
- member: no admin access; API consumer only

## Telegram → users Mapping
- On first contact (/start or webhook), upsert `users` row with `tg_id`
- Enrich with `city_id`, `role` (optional), `notif_level` during onboarding
- Use `users.id` as identity for quotas, ownership checks, events

## Phone Verification (Optional Gate)
- After onboarding, if enabled in Settings, request contact via ReplyKeyboard `request_contact=true`.
- Only accept contacts where `contact.user_id == from.id`.
- Normalize to E.164 and store in `users.phone` (or `users.phone_e164`).
- Event: `PhoneSubmitted` {last4, country?} (avoid storing redundant PII in events).
- Policy (Settings): `hard_gate` blocks features until phone stored; `soft_gate` allows a limited set.

## Ownership & Safety Checks
- Saved Ads: CRUD restricted to `user_id`
- Tickets: list/filter by `user_id`
- Payments: bind to authenticated/mapped user (not hardcoded `1`)

## Optional: API Token for Non-Telegram Clients
- If needed, add Sanctum/Passport for external admin CLI/API callers
