Screens — Manage App
Audience: Super admins — platform operations, tenant management, global configuration
Platform: Web only (Next.js)
Auth: super_admin role required
Status notation used throughout this doc:
- [Live] — built and working in
manage-dev.leadmetrics.ai(verified 2026-03-31) - [To Build] — specified but not yet implemented; part of the agent architecture layer
Sidebar Navigation
Collapsible — toggle button (< / > chevron) collapses to icon-only mode (w-16); expanded width is w-56. State is client-side only (resets on reload). Implemented in apps/manage/src/components/manage-sidebar.tsx — a "use client" component; NAV array lives there, not in the layout.
Screens
Platform Overview → /overview [To Build]
Tenants → /tenants [Live]
Users → /users [Live]
Agents → /agents [Live] (tabs: All Agents | Analytics)
Agent Chat → /chat [Live]
Skills → /skills [Live]
Content ▾
Blog Posts → /blog-posts [Live]
Social Posts → /social-posts [Live]
Templates ▾
Email → /templates/email [Live]
Telegram → /templates/telegram [Live]
Billing ▾
Invoices → /invoices [Live]
Plans → /plans [Live] ← full CRUD incl. create/edit/delete
Offerings → /plans/offerings [Live] ← create/edit/delete offerings
Regions → /plans/regions [Live] ← create/edit/delete regions
Credits & Usage → /usage [Live]
LLM Costs → /costs [Live]
Transactions → /transactions [Live]
Backlink Directories → /directories [Live]
Push Notifications → /push-notifications [Live]
Audit Logs → /audit-logs [Live]
System ▾
RAG & AI Config → /system/rag-config [To Build]
Help Center → /help [Live]Top bar [Live]: theme toggle (icon cycles light → dark → system) · notification bell (violet unread badge, full dropdown panel) · profile avatar dropdown (initials, name, email, “Super Admin” badge, Profile Settings link, Sign out). All in apps/manage/src/components/topbar.tsx.
Notification Dropdown [Live]
- Fetches from
GET /api/admin/notificationson mount (once per page load); no Socket.IO real-time (manage namespace does not broadcast per-tenant notification events) - Shows last 50 notifications across all tenants (super admin cross-tenant view)
- “Mark all read” →
POST /api/admin/notifications/read-all
API routes (Next.js proxy):
GET /api/admin/notifications→ proxies toGET /admin/v1/notificationsPOST /api/admin/notifications/read-all→ proxies toPOST /admin/v1/notifications/read-all
Backend routes (/admin/v1/, requireSuperAdmin):
GET /admin/v1/notifications— last 50 notifications across all tenants, newest firstPOST /admin/v1/notifications/read-all— marks all unread notifications as read platform-wide
Screen M1 — Platform Overview (/) [To Build]
Purpose: Real-time pulse of the entire platform — agent activity, LLM spend, queue health.
┌─────────────────────────────────────────────────────────────┐
│ Platform Overview Super Admin │
├──────────┬──────────┬──────────┬───────────────────────────┤
│ Tenants │ Active │ Total │ System Health │
│ Total │ Agents │ LLM Spend│ ✅ All services OK │
│ 24 │ 47 live │ $1,204 │ Queue: 12 jobs pending │
├──────────┴──────────┴──────────┴───────────────────────────┤
│ Tenant Activity (last 24h) Spend by Tenant │
│ ───────────────────────── ───────────────────── │
│ Acme Corp 14 activities Acme ████ $412 │
│ Globex 9 activities Globex ██ $204 │
│ Initech 3 activities Initech █ $88 │
└─────────────────────────────────────────────────────────────┘Live data: Agent counts and queue depths via SSE. Spend totals via polling.
Clicking a tenant row navigates to Tenant Detail (M3).
Screen M2 — Tenants (/tenants) [Live]
Purpose: Full list of all tenants. Currently the landing page after login.
Header
- Heading: “Tenants”
- Stat cards: Total · Active · Onboarding · Inactive (with counts)
- “Deleted Tenants” link button (→
/tenants/deleted) — neutral style, left of “Create Tenant” - ”+ New” button (→
/tenants/create) - Filter panel toggle
Table columns
| Column | Notes |
|---|---|
| Tenant Name | Avatar initials + name |
| Status | Active / Onboarding / Inactive badge |
| Source | Admin (manually created) · register (self-service) · Self |
| Country / Region | |
| Created At | |
| Actions | ... menu |
Row actions (...)
- View — navigate to Tenant Detail (M3)
- Suspend — confirmation dialog; blocks tenant access
- Change plan — plan change modal
- Impersonate — opens Dashboard as that tenant user for support debugging; action written to
audit_logs
Filter panel
Filters: Status · Source · Date range (created).
Screen M2d — Deleted Tenants (/tenants/deleted) [Live]
Purpose: Audit trail of all tenant deletion jobs — in-progress and completed.
Layout
"use client" page with IntersectionObserver infinite scroll (no page-number pagination).
Table columns
| Column | Notes |
|---|---|
| Tenant | Name |
| Requested By | Name of super admin who triggered deletion |
| Status | Colour badge: pending (yellow) · running (blue) · completed (green) · completed_with_errors (orange) · failed (red) |
| Progress | X / 9 steps completed counter |
| Requested | ISO date of the deletion request |
| Completed | ISO date of completion, or — |
Row click → /tenants/deleted/[deletionId] (M2d-detail).
Proxy route: GET /api/admin/tenant-deletions → GET /admin/v1/tenant-deletions?limit=30&cursor=.
Screen M2d-detail — Deletion Detail (/tenants/deleted/[deletionId]) [Live]
Purpose: Step-by-step log of a single tenant deletion job.
Server-rendered page; data fetched server-side via the API.
Header card
- Tenant name (h1) + Tenant ID in mono
- Status badge + “Run Cleanup” button (shown only when
status === "failed" | "completed_with_errors") - 4 info tiles: Requested By · Requested date · Duration · Job ID (last 8 chars)
- Red error banner if
errorMessageis set
Records Snapshot section
Grid of tiles (count + label) showing the record state at the time deletion was triggered. Keys: blogPosts, socialPosts, keywords, agentRuns, contacts, leads, reports, etc.
Deletion Steps table
| Column | Notes |
|---|---|
| # | Step icon: ○ pending · ◌ running · ✓ completed · ✗ failed · — skipped |
| Step | Label (bold) + step key below in mono |
| Status | Colour badge |
| Records | Count of records affected (or —) |
| Duration | Xms or X.Xs |
| Detail | Human-readable result message (e.g. “3 jobs removed”, “42 files deleted”) |
Run Cleanup button (DeletionCleanupButton.tsx): "use client" component. POSTs to /api/admin/tenant-deletions/[id]/cleanup, then calls router.refresh(). Only visible for failed or completed_with_errors status. Re-runs all 9 steps from scratch (deletes old step rows, creates fresh ones, re-enqueues job).
Proxy routes:
GET /api/admin/tenant-deletions/[id]→GET /admin/v1/tenant-deletions/:idPOST /api/admin/tenant-deletions/[id]/cleanup→POST /admin/v1/tenant-deletions/:id/cleanup
Screen M3 — Tenant Detail (/tenants/[tenantId]) [Live]
Purpose: Full visibility and control for a single tenant.
URL pattern: /tenants/[tenantId] (active tab stored in URL hash, e.g. #invoices)
Layout: Vertical sidebar nav on the left (w-44) + content panel (flex-1) — 19 tabs total.
Tabs
| # | Tab key | Content |
|---|---|---|
| 1 | progress | Month Progress panel |
| 2 | pipeline | Pipeline status panel |
| 3 | context | Read-only client context viewer; version picker (when >1 version); timeline + details sidebar; PDF download. Fetched from GET /api/admin/tenants/[tenantId]/context |
| 4 | strategy | Read-only strategy viewer; same layout as context with purple gradient. Fetched from GET /api/admin/tenants/[tenantId]/strategy |
| 5 | strategy_config | Per-tenant strategy writer input toggles. Fetched from GET/PUT /api/admin/tenants/[tenantId]/strategy-config |
| 6 | subscription_settings | Multi-row subscriptions table; per-row Edit, Lock/Unlock, Cancel; ”+ Add Subscription” button |
| 7 | invoices | Paginated invoice list (25/page) for this tenant; click row → /invoices/[id]; “Raise Invoice” slide-over; fetched from GET /api/admin/tenants/[tenantId]/invoices |
| 8 | usage | Credits & LLM tab — credit balance + adjust form + LLM spend breakdown + ledger table |
| 9 | activities | Paginated activity log (50/page) with Label, Type, Status, Agent Queue, Due Date, Created columns; fetched from GET /api/admin/activities?tenantId= |
| 10 | goals | Summary stat cards (Total/Ahead/On Track/Behind) + goal cards with progress bars; inline edit on hover; fetched from GET /api/dm/goals?tenantId= |
| 11 | users | All members of this tenant (via TenantMember); ”+ Add User” modal (Existing User search or New User form); static prop from server component |
| 12 | deliverables | Period picker + expandable deliverable type rows with item grid; fetched from GET /api/dm/deliverables?tenantId=&period=YYYY-MM |
| 13 | keywords | Infinite-scroll keyword list; fetched from GET /api/admin/tenant-keywords |
| 14 | keyword_groups | Infinite-scroll keyword groups; fetched from GET /api/admin/tenant-keyword-groups |
| 15 | reports | Infinite-scroll reports list; fetched from GET /api/admin/tenant-reports |
| 16 | audit_logs | Paginated audit trail (50/page); fetched from GET /api/admin/audit-logs?tenantId= |
| 17 | settings | General Settings form — Company (name, website, address, industry, country, timezone, currency) + Point of Contact + Automation (backlink auto-send toggle) |
| 18 | context_settings | Per-tenant context-file-writer input toggles — see Context Settings tab detail below |
| 19 | design_intelligence | Design Intelligence — 6 per-feature AI layer toggles; auto-saves on each toggle |
Tenant header
- Status badge — clickable dropdown (via
TenantStatusChanger) allowing transitions: onboarding→[suspended, cancelled]; active→[suspended, cancelled]; suspended→[active, cancelled]; cancelled→[active, suspended]. Status changes are written to audit log (tenant.status_changed). - Locked Out badge — shown if any subscription is locked out.
- Activate button — shown only when status is
onboarding; triggers the activation flow: sets tenant toactive, stampsbillingActivatedOn/startDateon the subscription (billing cycles start from this date), and writes atenant.activatedaudit log entry. No invoice is created here — the first invoice was already raised at tenant creation. - Delete Tenant button (
DeleteTenantButton.tsx) — red-bordered button in the top-right of the header card. Disabled (shows “Deleting…”) whentenant.status === "deleting". Click opens a confirmation modal requiring the user to type the exact tenant name. On confirm, POSTs to/api/admin/tenants/[tenantId]/delete, which triggers the 9-step background deletion job (see Screen M2d-detail). Redirects to/tenants/deleted/[deletionId]on success. The deletion is irreversible — all DB records, files, vectors, and search index documents are removed.
Subscriptions tab detail
Table columns: Name / Plan | Region | Price | Status | Start Date | Next Billing | Actions
Per-row actions:
- Edit — opens a right slide-over form (Name, Plan picker, Pay without TDS, Payment due days); writes
subscription.updatedaudit log - Lock — inline lock confirm row with optional reason field; writes
subscription.lockedaudit log - Unlock — confirm dialog; writes
subscription.unlockedaudit log - Cancel — confirm dialog; sets status to
cancelled; writessubscription.cancelledaudit log
Add Subscription — right slide-over with Name (required, e.g. “SAAS”, “Hosting”, “Managed Services”), Plan picker, Pay without TDS, Payment due days. Writes subscription.created audit log.
A tenant can have multiple active subscriptions simultaneously (e.g. SAAS + Hosting). Invoices can be raised against any specific active subscription.
Billing lifecycle: The first invoice is created at tenant creation (status
pending, duenow + paymentDueDays). The tenant stays inonboardinguntil manually activated via the Activate button. On activation,billingActivatedOnandstartDateare set on the subscription — the billing server picks these up to generate subsequent invoices from the next cycle onwards.
General Settings tab detail
Company section fields: Company Name (required) · Website · Address (multiline textarea) · Industry · Country · Timezone · Currency. Point of Contact section fields: Name · Email · Phone.
All four pickers (Industry, Country, Timezone, Currency) use a custom SearchableSelect component — click to open dropdown with inline search input, type to filter, click to select. Outside-click closes.
Automation section (added April 2026):
- Backlink Auto-Send — toggle switch (
backlinkAutoSendboolean). When ON, outreach emails drafted by the backlink-outreach-writer agent are sent automatically without requiring DM review. Default: OFF (DM reviews first).
Underlying Tenant model fields: name, website, address, pocName, pocEmail, pocPhone, timezone, country, currency, industry, backlinkAutoSend. (pocPhone, country, currency added April 2026; backlinkAutoSend added April 2026.)
API: PATCH /admin/v1/tenants/:tenantId — sparse update (only provided fields are changed). Server action: updateTenantSettings in actions.ts.
Context Settings tab detail
Controls which inputs the AI setup chain uses when building the tenant’s Client Context File. All four inputs default to true for every tenant. Changes are non-destructive — disabling an input does not delete data; it affects only the next generation run.
Stored as: Tenant.contextConfig Json? — a TenantContextConfig object. Parsed via resolveContextConfig() in setup.worker.ts, which fills in true defaults for any missing keys.
API: PATCH /admin/v1/tenants/:tenantId with { contextConfig: { ... } }. Server action: updateTenantSettings in actions.ts (passes Prisma.DbNull when null to satisfy Prisma’s nullable JSON constraint).
| Toggle | Field | Default | Effect when disabled |
|---|---|---|---|
| Live website crawl | enableWebCrawl | true | Client-researcher uses only the RAG knowledge base; no live crawling. Use for pre-launch tenants, JS-heavy sites, or clients with no public website. |
| Competitor research | enableCompetitorResearch | true | Competitor-researcher step is skipped entirely. Context file Competitive Landscape section will note that competitor research is not configured. |
| Brand voice section | enableBrandVoiceSection | true | Brand voice block is not appended to the context file after generation. Use when the tenant has not yet completed brand voice setup. |
| Key pages section | enableKeyPagesSection | true | Published blog posts and landing pages are not appended to the context file. Use for early-stage clients with no published content. |
Help topic: context-settings — opened via <HelpTrigger slug="context-settings" /> in ContextSettingsTab.tsx.
Goals tab detail — inline editing
Super admins can edit any goal directly without triggering approval resets. Hover a goal card → pencil icon appears → click to expand inline edit form with fields: Title · Target Value · Metric · Timeframe (months) · Channel · Deliverable Types (comma-separated). Save calls PATCH /admin/v1/goals/:goalId via updateGoal server action; local state updates optimistically.
Users tab detail — Add User modal
”+ Add User” button opens a modal with two modes:
- Existing User — searchable list of all platform users fetched from
GET /api/admin/users; select a user and role, callsassignExistingUserserver action (PATCH /admin/v1/users/:userIdwith{ tenantId }). - New User — form with Name / Email / Password / Role; calls
createUserForTenantserver action (POST /admin/v1/users).
Data source: The users list is sourced from
TenantMember, notUser.tenantId. DM reviewers and other cross-tenant users only appear if they have aTenantMemberrecord for this tenant.User.tenantIdreflects their primary/registration tenant and must never be used for membership queries.
Context / Strategy tabs detail
Both tabs are read-only (no approve or revise actions). Layout mirrors dashboard context/strategy pages:
- Hero card with gradient (blue = context, purple = strategy) and MarkdownRenderer content
- Version picker buttons (shown only when >1 version exists)
- Right sidebar with two sub-tabs: Timeline (log entries with actor + message) and Details (version history list)
- Download PDF button — uses
markedto render markdown → custom branded HTML →window.open()+window.print()
Proxy routes: GET /api/admin/tenants/[tenantId]/context and GET /api/admin/tenants/[tenantId]/strategy.
Upstream API: GET /admin/v1/tenants/:tenantId/context and GET /admin/v1/tenants/:tenantId/strategy — include logs and versions via Prisma include.
Strategy Config tab
[Live Apr 2026] Controls which data sources are fed to the strategy writer when generating or revising a strategy for this tenant. All flags default to ON — disable only when the specific input is known to be inaccurate or irrelevant.
Changes take effect on the next strategy run (generate or revision). They do not retroactively affect existing strategy versions.
| Toggle | What it controls | When to turn off |
|---|---|---|
| Baseline performance data | Injects manually entered metrics (monthly visitors, organic clicks, ad spend per platform, social followers) into the prompt | The client entered rough estimates or placeholder numbers during onboarding that would skew the strategy’s goal-setting |
| Knowledge base: brand docs | Runs a RAG search against brand voice, messaging, target audience, and product documents | New tenant with no uploaded brand documents — empty RAG results add noise |
| Knowledge base: competitor research | Runs a RAG search against competitor analysis and market positioning documents | The client is sensitive about competitor mentions appearing in their strategy document |
| Connected channel context | Fetches all OAuth-connected channels (isConnected: true) and tells Claude to prioritise them; also instructs Claude to flag any recommended channels that aren’t connected yet | Channels haven’t been connected yet but you want to run the strategy now — prevents Claude from noting missing connections as warnings |
Data flow: StrategyConfigTab.tsx → PUT /api/admin/tenants/[tenantId]/strategy-config proxy → PUT /admin/v1/tenants/:tenantId/strategy-config Fastify route → upserts TenantStrategyConfig row → strategy-writer worker reads flags at job start.
Where to find it: Manage → Tenants → [Tenant name] → Strategy Config (in the left tab nav, below Strategy).
Help topic: strategy-config — wired via <HelpTrigger slug="strategy-config" /> in StrategyConfigTab.tsx; covers all 4 toggles, their impact, and when to change each setting. Defined in apps/manage/src/app/(manage)/help/_data/index.ts.
Planned tabs to add [To Build]
- Config — plan, feature flags, allowed LLM providers, spending limits, deployment mode
- Agents — agent configs for this tenant; inherits from master (M5) with overrides highlighted
- Knowledge Base — dataset summary per tenant: file count, chunk count, embedding model, status; trigger re-index / clear
Knowledge Base tab detail (planned)
| Dataset | Files | Chunks | Embedding Model | Status |
|---|---|---|---|---|
| Client Documents | 3 | 29 | text-embed-3-small | ✅ |
| Website Content | 142 pages | 1,840 | text-embed-3-small | ✅ weekly crawl |
| Published Content | 24 | 312 | text-embed-3-small | ✅ auto |
| Competitor Research | 18 | 210 | nomic-embed-text | ✅ local |
Screen M4 — Global Invoices (/invoices) [Live]
Purpose: Invoice list across all tenants platform-wide.
Stats bar
Four stat cards at the top: Total Invoices · Pending · Paid · Overdue (counts from current filtered set).
Table columns
| Column | Notes |
|---|---|
| Name | ”TenantName – Mon YYYY” (period-based). Invoice number in mono below. Clicking navigates to detail page. |
| Net Payable | Formatted currency amount |
| Due Date | Formatted date |
| Status | Pill badge with dot (draft / pending / paid / overdue / void) |
| Billed On | Invoice issued date |
| Type | ”Subscription” or “One-time” |
| Actions | Eye icon (→ detail page) · Edit icon (→ status/notes slide-over) |
Search: by invoice number or tenant name. Filters: Status dropdown · Type dropdown.
Create Invoice button
”+ Create Invoice” button navigates to the dedicated Invoice Create page (M4c).
Screen M4c — Invoice Create (/invoices/create) [Live]
Purpose: Full-page form to create a new manual invoice for any tenant.
Breadcrumb: Invoices / Create Invoice
Sections
General Details
| Field | Notes |
|---|---|
| Tenant | Required dropdown; auto-fills subscription billing info on selection |
| Currency | Auto-filled from subscription (default INR) |
| Issued Date | Defaults to today |
| Due Date | Defaults to today + paymentDueDays from subscription |
| Period Start / End | Date pickers |
| Tax applicable? | Toggle; when on, shows Tax Type (Inclusive / Exclusive) |
| Notes | Optional textarea |
Billing Address — pre-filled from subscription billing fields if set; editable inline. Name · Address · City · State · Country · Postal.
Line Items — same Add Item modal as M4b (Pre-defined / Custom with Qty, Unit Price, SGST %, CGST %, Discount fields).
- Live summary: Subtotal → GST → Gross Amount → TDS → Net Payable
- Amounts entered in major units (₹), stored in minor units (paise × 100)
Subscription picker: When the selected tenant has multiple active subscriptions, a subscription dropdown is shown in General Details so the invoice can be associated with the correct subscription.
Submit: “Create Invoice” button — validates tenant + billing fields + ≥1 line item, generates invoice number (INV-YYYY-MM-XXXX, zero-padded sequence), creates DB record, redirects to M4a (detail page).
Validation errors appear inline. “This tenant has no subscription” shown if selected tenant is not yet active.
Screen M4a — Invoice Detail (/invoices/[invoiceId]) [Live]
Purpose: Full document-style view of a single invoice with timeline and reminder history.
Layout
Two-column: left = invoice document card; right = Details info + Timeline.
Breadcrumb: ← Invoices / INV-XXXX / Details
Top bar: Status pill · Print / PDF button · Reminders button (badge with count) · Edit Invoice link (→ M4b) · Cancel Invoice button (red, hidden if already void/paid).
Outstanding banner: For pending/overdue invoices — shows net payable amount + days remaining/overdue.
Invoice document card
- Invoice number heading + status badge
- Tenant name + billing period line
- Bill To section: billing address from subscription
- Plans table: Item / Amount / Tax / Total columns; line items rendered as rows
- Tax summary (right-aligned): Total → GST (%) → Gross Total → TDS (%) → Net Payable
- Notes (if set)
Details card (right)
Offering / Plan · Region · Issued date · Due date · Paid date (if paid).
Timeline card (right, data-testid="invoice-timeline")
Chronological events: Invoice created · Invoice issued · Payment due · Marked overdue (if applicable) · Payment received. Color-coded dots (green = paid, red = overdue, amber = due).
Print / PDF
“Print / PDF” button calls window.print(). Sidebar, top bar, outstanding banner, and right panel are hidden via print:hidden Tailwind classes. Invoice document card renders full-width with no borders/shadows for a clean PDF.
Cancel Invoice
“Cancel Invoice” button (shown only if status is not void or paid). Clicking opens a confirmation dialog:
- “This will permanently void the invoice. This cannot be undone.”
- “Yes, Cancel Invoice” / “Keep Invoice” buttons.
- On confirm: sets status to
void, writesinvoice.cancelledaudit log entry.
Reminders modal
Opened via “Reminders” button. Shows:
- Last Reminder card: date + time of most recent reminder sent
- Next Reminder card: scheduled next reminder date (or status message)
- Reminder History list: all reminders with type, channel, sent time, relative timestamp
- Send Now button: manually triggers a reminder email immediately (not shown if paid/void)
Screen M4b — Invoice Edit (/invoices/[invoiceId]/edit) [Live]
Purpose: Full edit form for an invoice — dates, billing address, line items, tax settings.
Breadcrumb: Invoices / INV-XXXX / Edit
Sections
General Details
| Field | Notes |
|---|---|
| Invoice Number | Read-only |
| Status | Dropdown: draft / pending / paid / overdue / void |
| Issued Date | Date picker |
| Due Date | Date picker |
| Period Start / End | Date pickers |
| Tax (GST) % | Number input |
| TDS % | Number input |
| Notes | Textarea |
Billing Address — updates subscription billing fields: Name · Address · City · State · Country · Postal.
Line Items — table with Description / Qty / Unit Price / Amount rows.
- “Add Item” button opens modal.
- Each row has a × remove button.
- Live amount summary (Subtotal → GST → Gross → TDS → Net Payable) updates as items change.
Add Item modal Toggle: Pre-defined (list of common item types) | Custom (free-text description). Fields: Qty · Unit Price · SGST % · CGST %.
Save Changes button: recalculates all amounts and redirects to detail page.
Screen M4p — Plans (/plans) [Live]
Purpose: List and manage all billing plans across offerings and regions.
Header
- Stat cards: Total Plans · Active Plans · Custom Plans · Total Tenants
- Buttons: Offerings (→
/plans/offerings) · Regions (→/plans/regions) · + New Plan (→/plans/new) - Filters: Offering dropdown · Region dropdown · “Custom plans only” checkbox
Table columns
| Column | Notes |
|---|---|
| Plan | Avatar initial + name; green if Custom offering, violet otherwise |
| Offering | Offering name |
| Region | Region name |
| Price | Formatted in major currency units + /mo or /yr |
| Tier | T{n} {label} badge (T0 Starter / T1 Pro / T2 Agency / T3 Enterprise) |
| Trial | Trial days or ”—“ |
| Tenants | Count with user icon |
| Status | Active / Inactive badge |
Row click navigates to plan detail.
Screen M4p-detail — Plan Detail (/plans/[planId]) [Live]
Purpose: Full details for a single billing plan including tenants on that plan.
Header
- Avatar initial + plan name + Custom badge (if applicable) + Active/Inactive badge + Tier badge
- Price in major units + billing cycle (right-aligned)
- Edit button →
/plans/[planId]/edit - Delete button — two-click confirm; disabled (with tooltip) if any tenants are subscribed
Info cards
Offering · Region · Trial days · Tenant count
Features section
Rendered as a grid of key/value pairs from plan.features JSON.
Tenants table
All tenants currently subscribed to this plan: Tenant name (link to detail) · Status · Subscription status badge · Start Date · Next Billing · View link.
Screen M4p-new — New Plan (/plans/new) [Live]
Purpose: Create a new billing plan.
Fields
| Field | Notes |
|---|---|
| Offering | Dropdown of all offerings |
| Region | Dropdown of all regions |
| Name | Text input |
| Description | Optional textarea |
| Price | Number input in major units (paise/fils handled automatically: stored × 100) |
| Billing Cycle | monthly / annual |
| Tier | 0 = Starter / 1 = Professional / 2 = Agency / 3 = Enterprise |
| Trial Days | Number, default 0 |
| Active | Checkbox, default true |
Features section
Structured inputs for common feature keys:
- Max Users, Max Agents (numbers)
- Credits / Month (number — drives monthly credit allocation via
plan.features.creditsPerMonth) - Highlights (dynamic list — add / remove string items)
Screen M4p-edit — Edit Plan (/plans/[planId]/edit) [Live]
Same fields as New Plan. Offering and Region are shown as read-only labels (cannot be changed after creation).
Screen M4p-offerings — Offerings (/plans/offerings) [Live]
Purpose: List and manage plan offerings (e.g. “Starter”, “Professional”, “Custom”).
Table: Name · Description · Plans count · Active status · Edit link · Delete button. Delete is blocked if offering has any plans.
Sub-pages: /plans/offerings/new (create) · /plans/offerings/[offeringId]/edit (edit).
Fields: Name (unique), Description, Active toggle.
Screen M4p-regions — Regions (/plans/regions) [Live]
Purpose: List and manage billing regions (e.g. “India”, “Middle East”).
Table: Code · Name · Currency · Tax% · TDS% · Active status · Edit link · Delete button. Delete is blocked if region has any plans.
Sub-pages: /plans/regions/new (create) · /plans/regions/[regionId]/edit (edit).
Fields: Name (unique), Code (2–5 chars, uppercase, immutable after creation), Currency, Currency Symbol, Tax %, TDS %, Active toggle.
Screen M5 — Global Users (/users) [Live]
Purpose: All human users across the entire platform.
Table of all users across all tenants with roles, tenant association, and status.
Screen M6 — Global Deliverables (/deliverables) [Live]
Purpose: Deliverable management across all tenants.
Table of all deliverables platform-wide.
Screen M7 — Master Agent Configs (/agents) [Live]
Purpose: Platform-wide agent configurations and run analytics. The page has two tabs: All Agents (config list) and Analytics (platform-wide run metrics).
All Agents tab (/agents):
- Stat cards: Total Agents · Free Tier · Pro Tier · Active
- Grouped by category: Setup / Strategy / Orchestration / SEO / Content / Reporting / Research / Reactive
- Columns: Agent name + description · Model · Plan badge · Status indicator · View link
Agent detail page (/agents/[agentId]):
- Header: name · plan badge · active status
- Active run banner (if agent is currently running — shows tenant + start time)
- Detail cards: Adapter (label + model ID) · Category · Role Identifier · Tenant Configs count
- Activity Overview —
AgentRunStatscomponent: 4 stat cards (Total Runs · Total Time · Total Cost · Avg Duration) + 30-day bar chart. Data fromGET /admin/v1/agents/:agentId/run-stats(cross-tenant aggregate). Bars: violet = completed only, amber = has failures, grey = no activity. Hover tooltip per day. - Mapped Skills section — shows skills currently mapped to this agent; “Add Skill” button opens a modal to search and select from the global skills library; individual skills can be removed with the × button
- System Prompt section (scrollable pre block)
- Run History table (last 10 runs with duration, cost, tools, adapter/model, status)
- “View all runs” link →
/agents/[agentId]/runs - Edit button →
/agents/[agentId]/edit
Agent edit page (/agents/[agentId]/edit):
- Fields: Name · Description · Adapter (dropdown: Claude Code / Codex / Gemini CLI) · Model (dropdown, auto-populated per adapter) · System Prompt · Plan Tier · Active toggle
- Changing adapter auto-resets model to the first model of the new adapter
- Adapter + model saved to
agent_config.adapter+agent_config.modelin DB
Analytics tab (/agents?tab=analytics) [Live]:
- Period selector: Today (1 day) / 7 Days / 30 Days / 90 Days
- Row 1 stat cards: Total Runs · Completed (with success %) · Failed (with running count) · Total Cost
- Row 2 stat cards: Total Time · Avg Duration · Active Agents in period · Avg Cost per Run
- Activity chart: bar chart per day over period (violet = clean, amber = has failures, grey = no activity); hover tooltips
- Adapter Usage breakdown: horizontal bar per adapter (Claude Code / Codex CLI / Gemini CLI) with run count, cost, % share
- Model Usage breakdown: horizontal bar per model with run count, cost, % share (up to 10 models)
- Top Agents table: Agent name + role · Runs · Completed · Failed · Success % (color-coded green/amber/red) · Total Cost · Avg Duration
- Data from
GET /api/admin/analytics/agents?period=→ proxies toGET /admin/v1/analytics/agents?period=
Agent runs page (/agents/[agentId]/runs):
- Filter bar: Status · Tenant search · From/To date · Sort (newest/oldest)
- Paginated table with cursor-based “Load more”: Tenant · Status · Task · Duration · Cost · Tools · Skills (⚡ N count) · Adapter / Model · Started
- URL-synced filter state
- Skills column shows
—for runs predating the skills logging feature - Adapter / Model column shows adapter label (Claude Code / Codex / Gemini CLI) with model ID below in mono;
—for older runs without adapter data
Agent run detail (/agents/[agentId]/runs/[runId]):
- Stat cards: Duration · Cost · Tool Calls
- Input section: task summary · dynamic context · system prompt
- Skills Injected card — chips showing each skill’s name, filename, and category badge; hidden when no skills were logged
- Error banner (if failed)
- Full output in scrollable pre block
Screen M8 — Global Skills (/skills) [Live]
Purpose: Platform-wide skill library. Skill files are written to the agent’s temp skill directory at execution time and passed to Claude Code via --add-dir.
Route: /skills (sidebar entry: Skills)
Skills list page (/skills):
- Stat cards: Total Skills · Active · Archived · Platform Defaults
- Filter bar: search (name/description/filename) · Category · Status · File Type · Sort · Order
- Table columns: Name (with
defaultbadge) · File (.md/.js/.sh badge + filename) · Category · Agents (count) · Status · Updated date · Edit link
Create page (/skills/new):
- Fields: Name · Category · Description · Filename (auto-generated from name) · File Type (.md / .js / .sh) · Content (monospace textarea, 24 rows) · Platform default checkbox
- Filename extension auto-updates when File Type changes
Edit page (/skills/[skillId]/edit):
- Same form pre-filled
- Archive / Restore toggle button (soft delete — sets status to “archived”, does not delete row)
Data model:
skill: id · name · description · filename · fileType · content · category · isDefault · status · createdAt · updatedAt
agent_skill: id · agentConfigId · skillId · createdAt [unique on (agentConfigId, skillId)]Execution flow: At agent job start, createSkillsDir(tenantId, agentRole) queries agent_skill for active skills mapped to that role and writes each file (filename + content) to the temp dir alongside the always-present search_knowledge.js.
Platform-seeded default skills (15 total):
| Skill | Category | Mapped to |
|---|---|---|
| Research Methodology Guide | Research | client-researcher, competitor-researcher, topic-researcher, research-note-writer |
| Competitor Analysis Framework | Research | competitor-researcher |
| Context File Structure | General | context-file-writer |
| Marketing Strategy Framework | Strategy | strategy-writer |
| Deliverable Types Reference | Strategy | deliverable-planner, activity-planner |
| SEO Writing Best Practices | SEO | blog-writer, keyword-researcher, content-brief-writer, landing-page-writer |
| Keyword Research Methodology | SEO | keyword-researcher, content-brief-writer |
| Content Brief Template | SEO | content-brief-writer, blog-writer |
| Social Media Platform Guide | Content | social-post-writer, social-calendar-planner |
| Ad Copy Frameworks | Content | google-ads-writer, meta-ads-writer |
| Email Copywriting Framework | Content | email-writer |
| Landing Page Conversion Principles | Content | landing-page-writer |
| GBP Post Best Practices | Content | gbp-post-writer |
| Reporting Standards Guide | Reporting | report-writer, ads-analyst, anomaly-detector |
| Review Response Guide | General | review-response-writer |
Tenant-specific skills are [To Build] — planned for the tenant Settings screen.
Screen M9 — LLM Providers (/providers) [To Build]
Purpose: Platform-wide LLM provider management and health monitoring.
| Provider | Status | API Key | Total Cost (Month) | Actions |
|---|---|---|---|---|
| Anthropic | ✅ OK | sk-…abc | $892 | Configure |
| OpenAI | ✅ OK | sk-…xyz | $312 | Configure |
| Ollama | ✅ Local | — | $0 | Configure |
Per-provider detail panel:
- Rate limit status (requests/min, tokens/min) — live
- Error rate (last 1h, last 24h)
- Model availability (which models are enabled platform-wide)
- Toggle enable/disable per plan tier (e.g. disable Claude Opus for Free plan tenants)
Screen M10 — Email Templates (/templates/email) [Live]
Purpose: Manage system email templates used for notifications and transactional emails.
Header
- “Templates (51)” — 51 templates in dev
- Filter button · ”+ Add” button
Table columns
| Column | Notes |
|---|---|
| Name | Template key (camelCase, e.g. invoiceDraftStatusMail) |
| Title | Human-readable subject/title |
| Type | Always email |
| Created On | Date |
| Actions | ... menu |
Observed templates (sample)
invoiceDraftStatusMail · clientReviewMail · clientRejectedMail · clientApprovedMail · autoApprovedMail · credentialMail · register · welcomeMailSelf · welcomeMailAdmin · userWelcomeMail · newLeadMail
Interactions
- Click row → right slide-over with template details and body preview
/templates/email/[name]direct URL returns 404 — not yet implemented; use slide-over
Screen M11 — Activity Templates (/templates/activity) [Live — partial]
Purpose: Platform-wide activity templates used to generate recurring activities for tenants.
Current state [Live]
- “Activity Templates (1703)” — flat table
- Columns: Channel · Title · Description · Type · Frequency · Due Days ·
...actions - Filter button · Import button
- Titles and descriptions use
{{VariableName}}placeholder syntax
Planned enhancement [To Build]
Split into two tabs matching the full pipeline architecture:
Pipeline Templates tab
| Template Name | Deliverable Type | Steps | Tenants Using | Actions |
|---|---|---|---|---|
| Standard Blog Post Pipeline | blog_posts | 4 | 14 | Edit / Clone / Archive |
| Standard Backlinks Pipeline | backlinks | 5 | 11 | Edit / Clone / Archive |
| GBP Posts Pipeline | gbp_posts | 4 | 8 | Edit / Clone / Archive |
Visual pipeline editor: Each step as a card — name, assignee type (agent or human), agent role, is approval gate. Drag to reorder. “Save as new version”. “Push to tenants” (confirmation shows affected count).
Recurring Task Templates tab
| Template Name | Trigger | Periodicity | Assignee | Variables | Tenants |
|---|---|---|---|---|---|
| Update GBP “always open” | on_onboarding | one_time | Human | gbp_url | 14/14 |
| Request Google reviews | cron | monthly | Human | gbp_url | 14/14 |
| NAP consistency check | cron | quarterly | SEO Specialist agent | business_name, address | 9/14 |
Template editor fields: Name · description · assignee (agent role or human role) · periodicity · trigger · cron expression with human-readable preview · prompt template with {{variable}} syntax · variable definitions table.
Variable substitution preview: Select a tenant from dropdown to preview with real data.
On save: New tenants get this template automatically. Existing tenants are not updated unless they adopt it (show non-adopting tenant count).
Screen M12 — Request Queue (/request-queue) [Live]
Purpose: Manage incoming blog content creation requests from digital marketers.
Header
- “Request Queue — Manage incoming blog creation requests from digital marketers”
- ”+ Add Request” button
Stat cards
| Card | Count (observed) |
|---|---|
| Pending Requests | 29 |
| My Active | 16 |
| Needs Action | 26 |
| In Review | 12 |
Tabs
All (63) · Pending · In Progress · Needs Action
Filters / view options
- My Assignments toggle
- Filter button · Sort button
- View switcher: List · Grid · Table · Kanban
Request card fields (List view)
| Field | Notes |
|---|---|
| Tenant | Avatar + name |
| Requested By | DM who submitted |
| Title | Blog title (linked) |
| Keywords | Primary keyword chips |
| Request ID | REQ[Date]#[Hash] format |
| Created | Creation date |
| Due Date | Red + “OVERDUE” if past due |
| Blog Month | Target publication month |
| Assigned To | Team member or Blog AI Agent |
| Status badge | DM Review · Pending · In Progress · Needs Action |
Pending / Unassigned cards additionally show a Move to In Progress button.
Pagination: 10/page configurable. 63 requests → 7 pages observed.
Screen M13 — Request Detail (/request-queue/[requestId]) [Live]
Purpose: Full details and actions for a single blog request.
Header bar
← Back to Queue | [Request ID] | [Status badge] | v[N]
Title section
Tenant avatar + name · blog title (h1) · action buttons.
Action buttons
- Copy Details — copies request info to clipboard
- Copy Image Prompt — copies image generation prompt
- Blog AI Agent (dropdown):
- Reassign to Team Member: Assign to Me · Blog AI Agent · [named team members]
- Move to On Hold
- Move to Pending
Request Information section
| Field | Notes |
|---|---|
| Primary Keywords | Chip(s) |
| Required Date | Red + “OVERDUE” if past due |
| Blog Month | Target month |
| Requested By | DM name |
| Assigned To | Agent or team member |
| Created | Relative time |
| Secondary Keywords | Additional keyword chips |
Feedback & Comments section
Threaded comments. Empty state: “No comments found”.
Screen M14 — All Blogs (/all-blogs) [Live]
Purpose: View and manage all generated blog posts across all lifecycle stages.
Header
- “All Blogs — View and manage all blog posts across all stages”
- Filter button · Sort button
Tabs
All (18) · DM Review · Client Review · Approved · Published · On Hold
Table columns
| Column | Notes |
|---|---|
| Title / Keyword | Blog title + primary keyword chip |
| Client | Tenant avatar + name |
| Submitted for Review | Date + time |
| Status | DM Review · Client Review · Approved · Published · On Hold |
| Version | v1, v2, v3… (increments on revision) |
| Actions | Eye icon → slide-over |
Blog detail slide-over (row click or eye icon)
Right panel: Status · Version · Submitted for Review · Last Updated · Requested By · Assigned To · Keywords · Submission History timeline.
Screen M15 — System Health (/system) [To Build]
Purpose: Infrastructure and operational health monitoring.
- Service status cards: Next.js (Dashboard / DM Portal / Manage) · Fastify API · PostgreSQL · MongoDB · Redis · Ollama — green/red with uptime %
- Queue depths: BullMQ queue size per agent type · currently processing · failed jobs in DLQ
- Database metrics: active connections · slow queries (> 500ms) · replication lag
- Recent errors: last 20 system-level errors with service, message, timestamp
- Active SSE connections: live client count per app
Quick actions:
- Drain / pause a specific BullMQ queue
- Clear DLQ (with confirmation)
- Force re-sync token refresh for all tenants
- Trigger manual DataForSEO backlink check run
Screen M16 — Backlink Directories (/directories) [Live]
Purpose: Platform-wide directory database management. Superadmins curate the list of business directories used by the opportunity-matcher agent when finding submission opportunities for tenants.
List page (/directories)
Stats row (5 tiles): Total · Active · Free · Dofollow · Agent Ready (violet — count of isAutoSubmittable = true entries).
Filters:
- Search input — client-side; matches name, category, subcategory.
- “Agent Ready” toggle button — filters list to
isAutoSubmittable = trueonly (violet when active).
Table columns: Name · Category/Subcategory · DR · Link type · Difficulty · Regions · Free/Paid · Active · →
Name cell: Directory name + optional violet Bot badge (shown when isAutoSubmittable = true; title tooltip “Agent can auto-submit”) + external Globe link icon.
Row click → /directories/[id].
Detail / Edit page (/directories/[id])
Basic Info card fields: Name · URL · Category · Subcategory · Domain Rating · Link Type · Is Free · Is Paid · Paid Price (USD) · Regions · Difficulty · Estimated Minutes · Is Active · Is Auto-Submittable (checkbox) · Submission Notes (textarea — admin notes on CAPTCHA/login requirements for this directory).
Steps card: Ordered list of steps (title, description, URL, estimated minutes) for manual submission; also used by the directory-submitter agent as the navigation hint for step 1.
API: PATCH /api/admin/directories/[id] → PATCH /admin/v1/backlink-directories/:id.
Create page (/directories/new)
Same fields as detail page. POST /api/admin/directories → POST /admin/v1/backlink-directories.
isAutoSubmittable behaviour
When isAutoSubmittable = true, the directory-submitter Playwright agent will attempt to autonomously fill and submit the listing form when a DM sets an opportunity backlink to in_progress. The agent detects CAPTCHA, login walls, and OTP fields and marks submissionStatus = "failed" with a reason if it can’t proceed — the human then follows the manual steps[] guide.
Help Center (/help + /help/*) [Live]
Purpose: In-app documentation for all Manage portal features, accessible to super admins.
Index page (/help):
- Directory of 15 help articles grouped by category (Tenants & Users · AI Agents & Skills · Billing · Notifications & Templates · Content Management · System)
- Client-side full-text search across all article content
Topic pages:
| Route | Topic |
|---|---|
/help/tenants | Tenants — lifecycle, detail tabs, creating tenants |
/help/users | Users — roles, inviting admins and DMs |
/help/agents | Agents — registry, categories, runs, analytics tab |
/help/skills | Skills — types, assigning to agents |
/help/invoices | Invoices — lifecycle, fields |
/help/plans | Plans — subscription tiers, multi-subscription |
/help/usage | Credits & Usage — consumption, balance adjustments |
/help/costs | LLM Costs — model/agent/tenant breakdown |
/help/templates/email | Email Templates — variables, editing |
/help/templates/telegram | Telegram Templates — format, event-driven |
/help/blog-posts | Blog Posts — cross-tenant view, status flow |
/help/social-posts | Social Posts — cross-tenant view, status flow |
/help/push-notifications | Push Notifications — broadcast, FCM |
/help/audit-logs | Audit Logs — fields, search, export |
/help/rag-config | RAG & AI Config — datasets, adapters, re-indexing |
Architecture: Data in apps/manage/src/app/(manage)/help/_data/index.ts; shared HelpPage/HelpCenter components from @leadmetrics/ui.
Background agents (not screens)
Two system agents appear in Manage app context but run in the background:
| Agent | Role |
|---|---|
| Blog AI Agent | Generates blog drafts for Request Queue items; shows as assignee in M12/M13 |
| Billing Agent | Auto-creates invoices; shows as actor in invoice audit trail |