docs: add ADMIN.md — comprehensive admin panel guide

Covers all 10 admin sections: Dashboard, Marketplace (new), Leads,
Suppliers, Flags, Feedback, Emails (sent log, inbox, compose, audiences),
pSEO Engine, SEO Hub, CMS (Templates, Scenarios, Articles), Tasks, Users.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Deeman
2026-02-25 09:44:33 +01:00
parent db14684667
commit 607dc35a9d

208
docs/ADMIN.md Normal file
View File

@@ -0,0 +1,208 @@
# Admin Panel Guide
The admin panel lives at `/admin/` and is restricted to users whose email is in `ADMIN_EMAILS`.
Dev shortcut: `GET /auth/dev-login?email=<admin-email>` (DEBUG mode only).
Sidebar navigation (left to right in layout):
**Dashboard → Marketplace → Leads → Suppliers → Flags → Feedback → Emails → pSEO → SEO**
CMS sections (Templates, Scenarios, Articles) are linked from the sidebar too.
---
## Dashboard `/admin/`
Quick-glance overview: user count, lead funnel summary, recent tasks, and credit economy totals. Entry point for everything else.
---
## Marketplace `/admin/marketplace`
Single-screen health view for the two-sided market. Useful for daily ops check and spotting stalled leads or low supplier engagement.
**Lead Funnel** (top cards)
| Card | Meaning |
|------|---------|
| Total Leads | All quote-type leads ever submitted |
| Verified New | Verified leads with status `new` — ready to be unlocked by a supplier |
| Unlocked | Distinct leads that have at least one `lead_forward` record |
| Won | Leads with status `closed_won` |
| Conversion Rate | Won ÷ Total |
**Credit Economy**
| Card | Meaning |
|------|---------|
| Issued | Sum of all positive credit ledger entries (purchases + refills) |
| Consumed | Credits spent on lead unlocks (absolute value of `lead_unlock` entries) |
| Outstanding | Current `credit_balance` sum across all paid-tier suppliers |
| 30-day Burn | Credits consumed in the last 30 days |
**Supplier Engagement**
| Card | Meaning |
|------|---------|
| Active | Paid-tier suppliers with `credit_balance > 0` |
| Avg Unlocks | Average lead forwards per active supplier |
| Response Rate | Forwards where `status != 'sent'` ÷ total forwards |
**Feature Flags**`lead_unlock` and `supplier_signup` toggles are inline on this page. Clicking saves immediately and refreshes (no full-page reload). Also accessible at `/admin/flags`.
**Activity Stream** — HTMX partial loaded on page open, showing the last 50 events across three tables: new leads, lead unlocks, credit ledger entries. Three dot colours: blue = lead created, green = unlock, amber = credit event.
---
## Leads `/admin/leads`
**List view** (`/admin/leads`)
Summary cards at top: total leads / new+unverified / hot pipeline credits / forward rate.
Filters (HTMX live — updates table without page reload):
- **Search** — matches `contact_name`, `contact_email`, `contact_company`
- **Status** — new / pending_verification / contacted / forwarded / closed_won / closed_lost
- **Heat** — hot / warm / cool
- **Country** — ISO country code
- **Period** pills — Today / 7d / 30d / All
**Detail view** (`/admin/leads/<id>`)
Full lead record including all extended quote fields (build context, glass type, lighting, location status, financing, services needed, notes).
Inline HTMX actions (no full-page reload):
- **Status change** — dropdown + save button → swaps the status badge in place
- **Forward to supplier** — select supplier + send → appends row to forward history table
Forward history table shows: supplier name, current forward status, credit cost, sent timestamp.
**Create lead** (`/admin/leads/new`) — manual lead entry for phone/offline enquiries.
**Heat scoring** — set automatically on submission: hot = 35 credits (≥6 courts + confirmed budget + short timeline), warm = 20, cool = 8.
---
## Suppliers `/admin/suppliers`
**List view** — search by name/email, filter by tier (free/basic/growth/pro) and country. Table shows tier badge, credit balance, and listing status.
**Detail view** (`/admin/suppliers/<id>`)
- Adjust credit balance (add or subtract, reason logged to `credit_ledger`)
- Change subscription tier
- View all lead forwards for this supplier with forward statuses
- Impersonate supplier (enter their session to debug dashboard issues)
**Create supplier** (`/admin/suppliers/new`) — manual supplier onboarding.
---
## Feature Flags `/admin/flags`
Toggle on/off without redeploy. Current flags:
| Flag | Controls |
|------|---------|
| `markets` | Market score pages visible to public |
| `payments` | Paddle checkout enabled |
| `planner_export` | PDF export tab visible in planner |
| `supplier_signup` | Supplier signup wizard accessible |
| `lead_unlock` | Suppliers can unlock leads (spend credits) |
Flags can also be toggled inline on the Marketplace dashboard for the two most-used flags.
---
## Feedback `/admin/feedback`
All submissions from the on-page feedback widget (thumbs up/down + optional text). Filterable by page and rating. Rate-limited to 1 per IP per page per hour.
---
## Emails
### Sent Log `/admin/emails`
Every outgoing email recorded in `email_sent`. Filter by type (magic_link, lead_forward, weekly_digest, etc.), delivery event (delivered/bounced/opened/clicked), or free-text search on recipient/subject.
Clicking a row opens the **detail view** — shows metadata, Resend delivery event timeline, and a sandboxed HTML preview of the message body fetched live from Resend API.
### Inbox `/admin/emails/inbox`
Inbound emails received via Resend inbound routing. Unread count shown as a badge in the sidebar. Detail view renders the HTML body in a sandboxed iframe with an inline reply form.
### Compose `/admin/emails/compose`
Send one-off transactional or plain emails. Select from-address (leads@, hello@, etc.) and optionally wrap in the branded email shell.
### Audiences `/admin/emails/audiences`
Lists all Resend audiences (waitlist, planner nurture, etc.) with contact counts. Drill into an audience to view contacts and remove individuals.
---
## pSEO Engine `/admin/pseo`
Operational visibility for the programmatic SEO content pipeline. Four sub-tabs:
**Content Gaps** — for each template, shows DuckDB serving rows that have no matching article in the requested language. Use this to prioritise what to generate next.
**Health Checks** — per-article sanity checks:
- hreflang orphans (EN article exists, DE missing)
- missing HTML build files on disk
- broken `[scenario:slug]` references in article markdown
**Freshness** — compares `_serving_meta.json` export timestamp vs `MAX(updated_at)` across articles per template. Status: 🟢 Fresh / 🟡 Stale / 🟣 No articles / ⚫ No data.
**Jobs** — live generation job monitor. Progress bars poll every 2s while jobs run. Error drilldown via `<details>` on failed jobs.
Generation is triggered from the **Templates** section (see below) — pSEO Engine is read-only observability.
---
## SEO Hub `/admin/seo`
Aggregated SEO metrics from Google Search Console, Bing Webmaster Tools, and Umami. Three tabs:
- **Search** — keyword performance (impressions, clicks, CTR, position) synced daily
- **Funnel** — Umami pageview → planner → quote conversion funnel
- **Scorecard** — per-article GSC impressions/clicks overlay on article metadata
**Sync** button triggers an immediate background sync of all configured sources (otherwise syncs daily via scheduler).
Requires `GSC_CLIENT_SECRETS_JSON`, `GSC_PROPERTY_URL`, `BING_API_KEY`, and `UMAMI_*` env vars.
---
## CMS
### Templates `/admin/templates`
Each template = a Jinja2 Markdown template file + a DuckDB data source query. Templates produce articles at scale.
Actions per template:
- **Edit** — modify template body, data query, or metadata
- **Preview** — render a single row through the template without saving
- **Generate** — bulk generate articles for all (or specific) data rows; runs as background task; progress visible in pSEO Engine → Jobs
### Scenarios `/admin/scenarios`
Public scenario cards shown on the landing page (e.g. "6-court indoor club in Munich"). Each has a name, description, financial state blob (pre-fills the planner), and a live PDF preview.
### Articles `/admin/articles`
Generated article records. Filter by template, language, country, published status.
Per-article actions: **Edit** markdown inline, **Publish/Unpublish** (HTMX, no page reload), **Rebuild HTML** (re-runs Markdown → HTML without re-generating content), **Delete**.
**Rebuild All** button at top re-processes every published article's Markdown into HTML — use after template or CSS changes.
---
## Tasks `/admin/tasks`
Worker queue state. Shows pending / running / failed tasks with payload and error log. Actions: **Retry** (re-enqueues), **Delete** (removes from queue).
Failed tasks do not auto-retry — manual retry is intentional so you can inspect the error first.
---
## Users `/admin/users`
List all users (search by email/name). Detail view shows role, subscription state, scenarios, and recent activity. **Impersonate** button logs you in as that user — "Stop impersonating" in the top bar returns you to your admin session.