# Filament Admin Specification

## Panel & Security
- Panel: Filament v3; requires PHP ext-intl
- Auth: `auth` + `role:admin` on panel and resources
- Navigation: group by domains (Users/Plans/Content/AI/Ads/Growth/Payments/Support)

## Global Pages
- Dashboard: KPI cards (CTR 7d, Saved%, D1 Activation, Payment success), recent errors (AI/provider, webhook, payments), quick links.
- Settings: feature toggles (phone/channel gate), channels [{title, chat_id, link}], phone_gate_policy, webhook test, membership test.

## Resources (Fields, Tables, Filters, Actions)

### Users
- Fields: tg_id (readonly), city_id (select searchable), role (enum), plan (string), notif_level (enum), created_at
- Table: id, tg_id, city, role, plan, created_at
- Filters: role, city
- Actions: assign role, change city, view events

### Plans
- Fields: key (unique), name, amount_irr, duration_days, is_active
- Table: key, name, amount_irr, duration_days, is_active

### Subscriptions
- Fields: user_id (rel), plan_id (rel), plan (string), starts_at, ends_at, status
- Table: user, plan, status, ends_at

### Payments
- Fields: user_id, plan_id, gateway, ref, amount, status, payload_json
- Table: user, plan, amount, status, ref, created_at
- Filters: status
- Actions: mark failed/ok (admin override), view subscription

### MenuItems
- Fields: key, title, emoji, enabled, ord, visible_roles(json)
- Table: key, title, enabled, ord

### PromptConfigs
- Fields: module, model, temperature, top_p, enable_file_search
- Table: module, model, enable_file_search

### Settings (Feature Toggles & Bot Config)
- Fields:
  - require_phone_verification (bool)
  - require_channel_membership (bool)
  - channels (JSON array of {title, chat_id, link}) — order matters; up to N items
  - phone_gate_policy (enum: hard_gate|soft_gate) — hard_gate blocks all features; soft_gate allows read-only subset
- Actions: add/remove channel; test membership for a sample user (diagnostic)
- Notes: use existing `app/Filament/Pages/Settings.php` as the home for these toggles; persist in a simple key/value store or a config table.

### Push Campaigns
- Fields: key, name, payload_json (template), schedule_json, status
- Actions: schedule, send now, preview keyboard
- Telemetry: delivered, opens, clicks (7d)

### Diagnostics
- Telegram: test send message to chat_id, show last webhook errors, verify membership for configured channels.
- Payments: verify by authority, list stale/pending, reconcile now.

### VectorStores / VectorFiles
- VectorStores: name, openai_vector_store_id, is_active
- VectorFiles: vector_store_id, openai_file_id, tag, status
- Actions: attach file, detach file, refresh status

### Opportunities
- Fields: source, code, brand, model, trim, year, km, city_id, price, body_status, link, contact_ref, score, reasons_json, status
- Table: brand, model, year, city, price, score, status, pushed_at
- Filters: city, brand, model, score range, status
- Actions: approve, schedule push, archive

### FeaturedAds
- Fields: title, description, price, city, link, target_roles(json), target_cities(json), scheduled_at, status
- Table: title, city, price, status, scheduled_at
- Actions: push now, schedule

### ScrapeProfiles
- Fields: name, url, class_name, element_id, city, keywords, enabled
- Table: name, city, enabled
- Actions: test profile (returns sample_count)

### Experiments / Assignments
- Experiments: key, variant_keys(json), is_active
- Assignments: user_id, experiment_id, variant_key, assigned_at

### PushCampaigns / PushLogs
- Campaigns: key, name, payload_json, schedule_json, status
- Logs: user_id, campaign_id, sent_at, delivered_at, opened_at, clicked_cta_at
- Widgets: CTR 7d by campaign

### Addons / UserAddons
- Addons: key, name, entitlements_json, is_active
- UserAddons: user_id, addon_id, starts_at, ends_at, status

### Trials / WalletLedger
- Trials: user_id, status, started_at, ends_at, penalty_points
- WalletLedger: user_id, type, amount_irr, reason, created_at

### Referrals / Cancellations
- ReferralLinks: user_id, code
- ReferralEvents: link_id, user_id, type, meta_json
- Cancellations: user_id, status, reason, selected_offer

### Support Tickets
- Tickets: user_id, subject, body, status, admin_replied_at, admin_last_reply_text
- Actions: reply, close

## KPI Widgets
- CTR 7d per campaign: clicks/delivered
- Saved/Delivered 7d: saved_ads / delivered
- D1 Activation: users with ≥3 distinct events in 24h of first event
- Payment success 7d: ok / (ok + failed)
