Skip to Content
Apps & PortalsDashboardScreens — Manage App

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

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/notifications on 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 to GET /admin/v1/notifications
  • POST /api/admin/notifications/read-all → proxies to POST /admin/v1/notifications/read-all

Backend routes (/admin/v1/, requireSuperAdmin):

  • GET /admin/v1/notifications — last 50 notifications across all tenants, newest first
  • POST /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.

  • 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

ColumnNotes
Tenant NameAvatar initials + name
StatusActive / Onboarding / Inactive badge
SourceAdmin (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

ColumnNotes
TenantName
Requested ByName of super admin who triggered deletion
StatusColour badge: pending (yellow) · running (blue) · completed (green) · completed_with_errors (orange) · failed (red)
ProgressX / 9 steps completed counter
RequestedISO date of the deletion request
CompletedISO date of completion, or

Row click → /tenants/deleted/[deletionId] (M2d-detail).

Proxy route: GET /api/admin/tenant-deletionsGET /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 errorMessage is 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

ColumnNotes
#Step icon: pending · running · completed · failed · skipped
StepLabel (bold) + step key below in mono
StatusColour badge
RecordsCount of records affected (or )
DurationXms or X.Xs
DetailHuman-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/:id
  • POST /api/admin/tenant-deletions/[id]/cleanupPOST /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 keyContent
1progressMonth Progress panel
2pipelinePipeline status panel
3contextRead-only client context viewer; version picker (when >1 version); timeline + details sidebar; PDF download. Fetched from GET /api/admin/tenants/[tenantId]/context
4strategyRead-only strategy viewer; same layout as context with purple gradient. Fetched from GET /api/admin/tenants/[tenantId]/strategy
5strategy_configPer-tenant strategy writer input toggles. Fetched from GET/PUT /api/admin/tenants/[tenantId]/strategy-config
6subscription_settingsMulti-row subscriptions table; per-row Edit, Lock/Unlock, Cancel; ”+ Add Subscription” button
7invoicesPaginated invoice list (25/page) for this tenant; click row → /invoices/[id]; “Raise Invoice” slide-over; fetched from GET /api/admin/tenants/[tenantId]/invoices
8usageCredits & LLM tab — credit balance + adjust form + LLM spend breakdown + ledger table
9activitiesPaginated activity log (50/page) with Label, Type, Status, Agent Queue, Due Date, Created columns; fetched from GET /api/admin/activities?tenantId=
10goalsSummary stat cards (Total/Ahead/On Track/Behind) + goal cards with progress bars; inline edit on hover; fetched from GET /api/dm/goals?tenantId=
11usersAll members of this tenant (via TenantMember); ”+ Add User” modal (Existing User search or New User form); static prop from server component
12deliverablesPeriod picker + expandable deliverable type rows with item grid; fetched from GET /api/dm/deliverables?tenantId=&period=YYYY-MM
13keywordsInfinite-scroll keyword list; fetched from GET /api/admin/tenant-keywords
14keyword_groupsInfinite-scroll keyword groups; fetched from GET /api/admin/tenant-keyword-groups
15reportsInfinite-scroll reports list; fetched from GET /api/admin/tenant-reports
16audit_logsPaginated audit trail (50/page); fetched from GET /api/admin/audit-logs?tenantId=
17settingsGeneral Settings form — Company (name, website, address, industry, country, timezone, currency) + Point of Contact + Automation (backlink auto-send toggle)
18context_settingsPer-tenant context-file-writer input toggles — see Context Settings tab detail below
19design_intelligenceDesign 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 to active, stamps billingActivatedOn / startDate on the subscription (billing cycles start from this date), and writes a tenant.activated audit 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…”) when tenant.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.updated audit log
  • Lock — inline lock confirm row with optional reason field; writes subscription.locked audit log
  • Unlock — confirm dialog; writes subscription.unlocked audit log
  • Cancel — confirm dialog; sets status to cancelled; writes subscription.cancelled audit 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, due now + paymentDueDays). The tenant stays in onboarding until manually activated via the Activate button. On activation, billingActivatedOn and startDate are 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 (backlinkAutoSend boolean). 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).

ToggleFieldDefaultEffect when disabled
Live website crawlenableWebCrawltrueClient-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 researchenableCompetitorResearchtrueCompetitor-researcher step is skipped entirely. Context file Competitive Landscape section will note that competitor research is not configured.
Brand voice sectionenableBrandVoiceSectiontrueBrand voice block is not appended to the context file after generation. Use when the tenant has not yet completed brand voice setup.
Key pages sectionenableKeyPagesSectiontruePublished 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, calls assignExistingUser server action (PATCH /admin/v1/users/:userId with { tenantId }).
  • New User — form with Name / Email / Password / Role; calls createUserForTenant server action (POST /admin/v1/users).

Data source: The users list is sourced from TenantMember, not User.tenantId. DM reviewers and other cross-tenant users only appear if they have a TenantMember record for this tenant. User.tenantId reflects 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 marked to 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.

ToggleWhat it controlsWhen to turn off
Baseline performance dataInjects manually entered metrics (monthly visitors, organic clicks, ad spend per platform, social followers) into the promptThe client entered rough estimates or placeholder numbers during onboarding that would skew the strategy’s goal-setting
Knowledge base: brand docsRuns a RAG search against brand voice, messaging, target audience, and product documentsNew tenant with no uploaded brand documents — empty RAG results add noise
Knowledge base: competitor researchRuns a RAG search against competitor analysis and market positioning documentsThe client is sensitive about competitor mentions appearing in their strategy document
Connected channel contextFetches all OAuth-connected channels (isConnected: true) and tells Claude to prioritise them; also instructs Claude to flag any recommended channels that aren’t connected yetChannels haven’t been connected yet but you want to run the strategy now — prevents Claude from noting missing connections as warnings

Data flow: StrategyConfigTab.tsxPUT /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)

DatasetFilesChunksEmbedding ModelStatus
Client Documents329text-embed-3-small
Website Content142 pages1,840text-embed-3-small✅ weekly crawl
Published Content24312text-embed-3-small✅ auto
Competitor Research18210nomic-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

ColumnNotes
Name”TenantName – Mon YYYY” (period-based). Invoice number in mono below. Clicking navigates to detail page.
Net PayableFormatted currency amount
Due DateFormatted date
StatusPill badge with dot (draft / pending / paid / overdue / void)
Billed OnInvoice issued date
Type”Subscription” or “One-time”
ActionsEye 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

FieldNotes
TenantRequired dropdown; auto-fills subscription billing info on selection
CurrencyAuto-filled from subscription (default INR)
Issued DateDefaults to today
Due DateDefaults to today + paymentDueDays from subscription
Period Start / EndDate pickers
Tax applicable?Toggle; when on, shows Tax Type (Inclusive / Exclusive)
NotesOptional 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” 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, writes invoice.cancelled audit 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

FieldNotes
Invoice NumberRead-only
StatusDropdown: draft / pending / paid / overdue / void
Issued DateDate picker
Due DateDate picker
Period Start / EndDate pickers
Tax (GST) %Number input
TDS %Number input
NotesTextarea

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

ColumnNotes
PlanAvatar initial + name; green if Custom offering, violet otherwise
OfferingOffering name
RegionRegion name
PriceFormatted in major currency units + /mo or /yr
TierT{n} {label} badge (T0 Starter / T1 Pro / T2 Agency / T3 Enterprise)
TrialTrial days or ”—“
TenantsCount with user icon
StatusActive / 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

FieldNotes
OfferingDropdown of all offerings
RegionDropdown of all regions
NameText input
DescriptionOptional textarea
PriceNumber input in major units (paise/fils handled automatically: stored × 100)
Billing Cyclemonthly / annual
Tier0 = Starter / 1 = Professional / 2 = Agency / 3 = Enterprise
Trial DaysNumber, default 0
ActiveCheckbox, 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 OverviewAgentRunStats component: 4 stat cards (Total Runs · Total Time · Total Cost · Avg Duration) + 30-day bar chart. Data from GET /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.model in 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 to GET /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 default badge) · 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):

SkillCategoryMapped to
Research Methodology GuideResearchclient-researcher, competitor-researcher, topic-researcher, research-note-writer
Competitor Analysis FrameworkResearchcompetitor-researcher
Context File StructureGeneralcontext-file-writer
Marketing Strategy FrameworkStrategystrategy-writer
Deliverable Types ReferenceStrategydeliverable-planner, activity-planner
SEO Writing Best PracticesSEOblog-writer, keyword-researcher, content-brief-writer, landing-page-writer
Keyword Research MethodologySEOkeyword-researcher, content-brief-writer
Content Brief TemplateSEOcontent-brief-writer, blog-writer
Social Media Platform GuideContentsocial-post-writer, social-calendar-planner
Ad Copy FrameworksContentgoogle-ads-writer, meta-ads-writer
Email Copywriting FrameworkContentemail-writer
Landing Page Conversion PrinciplesContentlanding-page-writer
GBP Post Best PracticesContentgbp-post-writer
Reporting Standards GuideReportingreport-writer, ads-analyst, anomaly-detector
Review Response GuideGeneralreview-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.

ProviderStatusAPI KeyTotal Cost (Month)Actions
Anthropic✅ OKsk-…abc$892Configure
OpenAI✅ OKsk-…xyz$312Configure
Ollama✅ Local$0Configure

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

ColumnNotes
NameTemplate key (camelCase, e.g. invoiceDraftStatusMail)
TitleHuman-readable subject/title
TypeAlways email
Created OnDate
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 NameDeliverable TypeStepsTenants UsingActions
Standard Blog Post Pipelineblog_posts414Edit / Clone / Archive
Standard Backlinks Pipelinebacklinks511Edit / Clone / Archive
GBP Posts Pipelinegbp_posts48Edit / 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 NameTriggerPeriodicityAssigneeVariablesTenants
Update GBP “always open”on_onboardingone_timeHumangbp_url14/14
Request Google reviewscronmonthlyHumangbp_url14/14
NAP consistency checkcronquarterlySEO Specialist agentbusiness_name, address9/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

CardCount (observed)
Pending Requests29
My Active16
Needs Action26
In Review12

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)

FieldNotes
TenantAvatar + name
Requested ByDM who submitted
TitleBlog title (linked)
KeywordsPrimary keyword chips
Request IDREQ[Date]#[Hash] format
CreatedCreation date
Due DateRed + “OVERDUE” if past due
Blog MonthTarget publication month
Assigned ToTeam member or Blog AI Agent
Status badgeDM 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

FieldNotes
Primary KeywordsChip(s)
Required DateRed + “OVERDUE” if past due
Blog MonthTarget month
Requested ByDM name
Assigned ToAgent or team member
CreatedRelative time
Secondary KeywordsAdditional 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

ColumnNotes
Title / KeywordBlog title + primary keyword chip
ClientTenant avatar + name
Submitted for ReviewDate + time
StatusDM Review · Client Review · Approved · Published · On Hold
Versionv1, v2, v3… (increments on revision)
ActionsEye 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

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 = true only (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/directoriesPOST /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:

RouteTopic
/help/tenantsTenants — lifecycle, detail tabs, creating tenants
/help/usersUsers — roles, inviting admins and DMs
/help/agentsAgents — registry, categories, runs, analytics tab
/help/skillsSkills — types, assigning to agents
/help/invoicesInvoices — lifecycle, fields
/help/plansPlans — subscription tiers, multi-subscription
/help/usageCredits & Usage — consumption, balance adjustments
/help/costsLLM Costs — model/agent/tenant breakdown
/help/templates/emailEmail Templates — variables, editing
/help/templates/telegramTelegram Templates — format, event-driven
/help/blog-postsBlog Posts — cross-tenant view, status flow
/help/social-postsSocial Posts — cross-tenant view, status flow
/help/push-notificationsPush Notifications — broadcast, FCM
/help/audit-logsAudit Logs — fields, search, export
/help/rag-configRAG & 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:

AgentRole
Blog AI AgentGenerates blog drafts for Request Queue items; shows as assignee in M12/M13
Billing AgentAuto-creates invoices; shows as actor in invoice audit trail

© 2026 Leadmetrics — Internal use only