# Feerasta Operating System Buildout

Use this file as the implementation brief for updating the Feerasta operating system. It turns the SMB + Enterprise offer architecture into product modules, data models, workflows, agents, and acceptance criteria.

## Codex Implementation Prompt

You are updating the Feerasta operating system. Implement the product registry, CRM pipeline, workflow automation, AI-agent configuration, dashboards, and internal admin surfaces for the offers below.

Primary goal:

- Support both SMB and Enterprise clients without mixing their sales motions.
- Keep SMB fast, packaged, priced, and ROI-visible.
- Keep Enterprise assessment-led, governed, auditable, and deployment-specific.
- Every offer must map to an onboarding flow, client record, workflow status, deliverables, owner-facing report, and internal operating checklist.

Suggested stack assumptions:

- TypeScript for shared types and service logic.
- Postgres or Supabase for relational data.
- Queue worker for async workflows.
- LLM provider abstraction for AI actions.
- CRM-style admin app for internal operators.
- Client portal for reports, approvals, and deliverables.

If the existing codebase uses different names or architecture, adapt these concepts to the local patterns instead of creating a parallel system.

## Suggested Changes Before Implementation

1. Rename the SMB public offer from `Intelligence` to `AI Front Desk`.
   Keep `Intelligence Platform` for enterprise.

2. Treat `Edge` as an enablement layer.
   Sell `Pulse` as the product. Hardware is the installation path, not the main promise.

3. Add `Recover` as a first-class SMB line.
   This is the cleanest performance offer because it covers missed calls, dormant customers, unpaid invoices, failed payments, abandoned quotes, and no-shows.

4. Add `Knowledge` as a first-class Enterprise line.
   It is easier for enterprise buyers to understand than broad "Bespoke RAG."

5. Add `Compliance` as both:
   - SMB: website and AI-readiness compliance scan.
   - Enterprise: governance, privacy, audit, retention, and deployment readiness.

6. Separate public pricing by market:
   - SMB: visible monthly pricing and setup fees.
   - Enterprise: assessment, pilot, deployment, managed run ranges.

7. Every AI workflow needs an action-risk level:
   - `observe`: read and summarize only.
   - `draft`: prepare output for approval.
   - `recommend`: suggest a decision.
   - `act_with_approval`: execute after user approval.
   - `act_autonomously`: execute only for low-risk preapproved workflows.

## Shared Product Registry

Create a single source of truth for all offers.

```ts
export type MarketSegment = "smb" | "enterprise" | "both";

export type OfferCategory =
  | "front_desk"
  | "growth"
  | "website"
  | "finance_ops"
  | "private_ai"
  | "advisory"
  | "custom_build"
  | "compliance"
  | "knowledge"
  | "revenue_recovery"
  | "hardware"
  | "partner_program"
  | "venture_program";

export type ActionRisk =
  | "observe"
  | "draft"
  | "recommend"
  | "act_with_approval"
  | "act_autonomously";

export type DeliveryPhase =
  | "lead"
  | "diagnosis"
  | "proposal"
  | "onboarding"
  | "setup"
  | "pilot"
  | "live"
  | "managed_run"
  | "paused"
  | "complete";

export interface OfferDefinition {
  id: string;
  name: string;
  publicName: string;
  segment: MarketSegment;
  category: OfferCategory;
  oneLine: string;
  buyer: string[];
  primaryOutcome: string;
  entryMotion: string;
  coreDeliverables: string[];
  requiredIntegrations: string[];
  optionalIntegrations: string[];
  defaultRiskLevel: ActionRisk;
  defaultPhases: DeliveryPhase[];
  metrics: string[];
  reports: string[];
  dependencies: string[];
  upsells: string[];
}
```

```ts
export const FEERASTA_OFFERS: OfferDefinition[] = [
  {
    id: "smb_assistant",
    name: "Assistant",
    publicName: "Feerasta Assistant",
    segment: "smb",
    category: "front_desk",
    oneLine: "A WhatsApp business brain for capture, reminders, filing, and plain-English Q&A.",
    buyer: ["owner", "operator", "clinic_manager", "franchisee"],
    primaryOutcome: "Lower-friction capture of business context and documents.",
    entryMotion: "self_serve_or_light_onboarding",
    coreDeliverables: [
      "Dedicated WhatsApp number",
      "Receipt and invoice capture",
      "Voice-note reminder creation",
      "Daily briefing",
      "Plain-English business Q&A"
    ],
    requiredIntegrations: ["whatsapp"],
    optionalIntegrations: ["gmail", "google_drive", "quickbooks", "xero", "calendar"],
    defaultRiskLevel: "draft",
    defaultPhases: ["lead", "onboarding", "setup", "live", "managed_run"],
    metrics: ["documents_captured", "reminders_created", "questions_answered", "time_saved_estimate"],
    reports: ["weekly_assistant_summary"],
    dependencies: [],
    upsells: ["smb_front_desk", "smb_ledger", "smb_growth_partnership"]
  },
  {
    id: "smb_front_desk",
    name: "AI Front Desk",
    publicName: "Feerasta AI Front Desk",
    segment: "smb",
    category: "front_desk",
    oneLine: "Answers calls, texts back missed calls, books appointments, transfers with context, and logs to CRM.",
    buyer: ["owner", "operator", "clinic_manager", "service_manager"],
    primaryOutcome: "Never lose a customer because nobody answered.",
    entryMotion: "demo_then_setup",
    coreDeliverables: [
      "AI receptionist",
      "Missed-call text-back",
      "Appointment booking",
      "Warm transfer with context",
      "Post-call summary",
      "CRM logging",
      "Outbound reminder calls"
    ],
    requiredIntegrations: ["phone", "sms", "calendar"],
    optionalIntegrations: ["crm", "jobber", "housecall_pro", "hubspot", "square"],
    defaultRiskLevel: "act_with_approval",
    defaultPhases: ["lead", "diagnosis", "proposal", "onboarding", "setup", "pilot", "live", "managed_run"],
    metrics: ["calls_answered", "missed_calls_recovered", "appointments_booked", "transfer_rate", "lead_response_time"],
    reports: ["front_desk_roi_report", "call_summary_digest"],
    dependencies: [],
    upsells: ["smb_ascent", "smb_recover", "smb_growth_partnership"]
  },
  {
    id: "smb_ascent",
    name: "Ascent",
    publicName: "Feerasta Ascent",
    segment: "smb",
    category: "growth",
    oneLine: "Local SEO, AI search visibility, reviews, reactivation, and win-back campaigns.",
    buyer: ["owner", "operator", "marketing_manager", "franchisee"],
    primaryOutcome: "More found demand and more booked work.",
    entryMotion: "free_competitive_report",
    coreDeliverables: [
      "Local SEO",
      "Google Business Profile optimization",
      "AI search visibility",
      "Review generation",
      "Database reactivation",
      "Customer win-back campaigns",
      "Monthly market position report"
    ],
    requiredIntegrations: ["google_business_profile"],
    optionalIntegrations: ["crm", "mailchimp", "sms", "whatsapp", "website_cms"],
    defaultRiskLevel: "act_with_approval",
    defaultPhases: ["lead", "diagnosis", "proposal", "onboarding", "setup", "live", "managed_run"],
    metrics: ["rank_improvements", "reviews_requested", "reviews_gained", "reactivation_replies", "appointments_booked"],
    reports: ["market_position_report", "growth_roi_report"],
    dependencies: [],
    upsells: ["smb_front_desk", "smb_studio", "smb_growth_partnership"]
  },
  {
    id: "smb_studio",
    name: "Studio",
    publicName: "Feerasta Studio",
    segment: "smb",
    category: "website",
    oneLine: "A custom website built before the client decides, with local SEO and conversion baked in.",
    buyer: ["owner", "operator", "professional_services_partner"],
    primaryOutcome: "A premium conversion surface that supports calls, SEO, reviews, and AI visibility.",
    entryMotion: "demo_first_build",
    coreDeliverables: [
      "Custom website design",
      "Build-before-you-buy preview",
      "Local SEO structure",
      "Mobile performance",
      "Launch-grade animation",
      "Care plan"
    ],
    requiredIntegrations: ["domain", "hosting"],
    optionalIntegrations: ["analytics", "crm", "booking", "chat", "call_tracking"],
    defaultRiskLevel: "draft",
    defaultPhases: ["lead", "diagnosis", "proposal", "setup", "live", "managed_run"],
    metrics: ["site_speed", "conversion_clicks", "organic_visits", "calls_from_site", "form_submissions"],
    reports: ["website_launch_report", "monthly_site_care_report"],
    dependencies: [],
    upsells: ["smb_ascent", "smb_front_desk", "smb_growth_partnership"]
  },
  {
    id: "smb_ledger",
    name: "Ledger",
    publicName: "Feerasta Ledger",
    segment: "smb",
    category: "finance_ops",
    oneLine: "AI back office for vendor overcharges, AR chasing, bookkeeping support, margins, and cash-flow Q&A.",
    buyer: ["owner", "bookkeeper", "operator", "accountant_partner"],
    primaryOutcome: "Stop money leaking where nobody has time to look.",
    entryMotion: "free_first_week_on_real_numbers",
    coreDeliverables: [
      "Vendor overcharge detection",
      "Receipt capture",
      "Bill reminders",
      "Accounts receivable chasing",
      "Bookkeeping support",
      "Margin reporting",
      "Cash-flow and outflow monitoring",
      "Monthly accountant-ready report"
    ],
    requiredIntegrations: ["document_capture"],
    optionalIntegrations: ["quickbooks", "xero", "bank_feed", "stripe", "square", "pos"],
    defaultRiskLevel: "act_with_approval",
    defaultPhases: ["lead", "diagnosis", "proposal", "onboarding", "setup", "pilot", "live", "managed_run"],
    metrics: ["overcharges_flagged", "overcharges_recovered", "invoices_chased", "cash_collected", "books_current_days"],
    reports: ["monthly_money_read", "vendor_scorecard", "accountant_export"],
    dependencies: [],
    upsells: ["smb_assistant", "enterprise_procurement"]
  },
  {
    id: "smb_recover",
    name: "Recover",
    publicName: "Feerasta Recover",
    segment: "smb",
    category: "revenue_recovery",
    oneLine: "Recover missed calls, dormant customers, abandoned quotes, failed payments, unpaid invoices, and no-shows.",
    buyer: ["owner", "operator", "revenue_manager"],
    primaryOutcome: "Turn existing leakage into booked or collected revenue.",
    entryMotion: "performance_offer",
    coreDeliverables: [
      "Missed-call recovery",
      "Abandoned quote follow-up",
      "Dormant customer reactivation",
      "Failed-payment recovery",
      "Overdue invoice nudges",
      "No-show recovery",
      "Recovery ROI dashboard"
    ],
    requiredIntegrations: ["crm_or_customer_list", "sms_or_whatsapp"],
    optionalIntegrations: ["phone", "stripe", "quickbooks", "calendar", "email"],
    defaultRiskLevel: "act_with_approval",
    defaultPhases: ["lead", "diagnosis", "proposal", "onboarding", "setup", "pilot", "live", "managed_run"],
    metrics: ["contacts_attempted", "reply_rate", "appointments_booked", "payments_recovered", "revenue_recovered"],
    reports: ["recovery_campaign_report"],
    dependencies: [],
    upsells: ["smb_growth_partnership", "smb_front_desk", "smb_ledger"]
  },
  {
    id: "smb_growth_partnership",
    name: "Growth Partnership",
    publicName: "Feerasta Growth Partnership",
    segment: "smb",
    category: "growth",
    oneLine: "Bundled outcome: front desk, missed-call recovery, win-back, reviews, website, and ROI dashboard.",
    buyer: ["owner", "operator", "franchisee"],
    primaryOutcome: "More booked jobs with Feerasta on the hook for measurable growth.",
    entryMotion: "free_report_then_performance_or_retainer",
    coreDeliverables: [
      "AI Front Desk",
      "Missed-call recovery",
      "Database reactivation",
      "Review generation",
      "Website conversion layer",
      "ROI dashboard",
      "Monthly operating call"
    ],
    requiredIntegrations: ["phone", "calendar", "crm_or_customer_list", "website"],
    optionalIntegrations: ["google_business_profile", "payments", "pos", "job_management"],
    defaultRiskLevel: "act_with_approval",
    defaultPhases: ["lead", "diagnosis", "proposal", "onboarding", "setup", "pilot", "live", "managed_run"],
    metrics: ["booked_jobs", "recovered_calls", "reactivated_customers", "reviews_gained", "roi_estimate"],
    reports: ["growth_partnership_roi_report"],
    dependencies: ["smb_front_desk", "smb_ascent", "smb_studio", "smb_recover"],
    upsells: ["smb_ledger", "smb_pulse"]
  },
  {
    id: "smb_pulse",
    name: "Pulse",
    publicName: "Feerasta Pulse",
    segment: "both",
    category: "hardware",
    oneLine: "Busyness, occupancy, capacity, wait-time, and staffing intelligence.",
    buyer: ["owner", "operator", "regional_manager", "facilities_manager"],
    primaryOutcome: "Make physical operations visible and actionable.",
    entryMotion: "hardware_assessment",
    coreDeliverables: [
      "Verified busy badge",
      "Live floor and capacity signal",
      "Wait-time estimate",
      "Staffing triggers",
      "Trend analytics",
      "Hardware sourcing and support"
    ],
    requiredIntegrations: ["sensor_or_camera_or_pos_signal"],
    optionalIntegrations: ["website", "google_business_profile", "staffing_system", "dashboard"],
    defaultRiskLevel: "observe",
    defaultPhases: ["lead", "diagnosis", "proposal", "setup", "pilot", "live", "managed_run"],
    metrics: ["occupancy_accuracy", "wait_time_accuracy", "peak_periods", "staffing_alerts", "conversion_trends"],
    reports: ["pulse_operations_report"],
    dependencies: ["edge_hardware"],
    upsells: ["enterprise_multi_location_intelligence"]
  },
  {
    id: "enterprise",
    name: "Enterprise",
    publicName: "Feerasta Enterprise",
    segment: "enterprise",
    category: "private_ai",
    oneLine: "Umbrella for private, governed, integrated AI systems.",
    buyer: ["ceo", "coo", "cio", "compliance_officer", "innovation_lead"],
    primaryOutcome: "Deploy AI into real workflows without losing control of data, governance, or operations.",
    entryMotion: "assessment_pilot_deployment_managed_run",
    coreDeliverables: [
      "Enterprise assessment",
      "Pilot selection",
      "Security review",
      "Deployment architecture",
      "Governance model",
      "Managed operating cadence"
    ],
    requiredIntegrations: ["identity_provider", "data_sources"],
    optionalIntegrations: ["crm", "erp", "dms", "ehr", "ticketing", "data_warehouse"],
    defaultRiskLevel: "recommend",
    defaultPhases: ["lead", "diagnosis", "proposal", "pilot", "live", "managed_run"],
    metrics: ["pilot_success_rate", "workflow_hours_saved", "approval_latency", "audit_events", "adoption_rate"],
    reports: ["enterprise_operating_report", "security_review_packet"],
    dependencies: [],
    upsells: ["enterprise_sovereign", "enterprise_knowledge", "enterprise_compliance", "enterprise_bespoke"]
  },
  {
    id: "enterprise_sovereign",
    name: "Sovereign",
    publicName: "Feerasta Sovereign",
    segment: "enterprise",
    category: "private_ai",
    oneLine: "Private AI on the client's own ground for regulated and IP-heavy work.",
    buyer: ["cio", "general_counsel", "chief_medical_officer", "compliance_officer"],
    primaryOutcome: "Use AI without exposing sensitive data outside approved boundaries.",
    entryMotion: "sovereignty_assessment",
    coreDeliverables: [
      "Sovereignty Assessment",
      "Private deployment",
      "Managed Sovereign operation",
      "Private legal AI",
      "Clinical documentation AI",
      "Compliance-ready RAG",
      "On-prem automation"
    ],
    requiredIntegrations: ["private_data_store", "identity_provider"],
    optionalIntegrations: ["dms", "ehr", "matter_management", "private_cloud", "on_prem_gpu"],
    defaultRiskLevel: "recommend",
    defaultPhases: ["lead", "diagnosis", "proposal", "pilot", "live", "managed_run"],
    metrics: ["answered_queries", "citation_accuracy", "refusal_rate", "human_review_rate", "audit_events"],
    reports: ["sovereign_attestation_report", "model_performance_report"],
    dependencies: ["enterprise_compliance"],
    upsells: ["enterprise_knowledge", "enterprise_bespoke"]
  },
  {
    id: "enterprise_advisory",
    name: "Advisory",
    publicName: "Feerasta Advisory",
    segment: "both",
    category: "advisory",
    oneLine: "AI readiness, operating model, governance, workflow discovery, automation sprints, and fractional AI officer.",
    buyer: ["owner", "ceo", "coo", "cio", "department_head"],
    primaryOutcome: "Choose the right AI work and make it operational.",
    entryMotion: "audit_first",
    coreDeliverables: [
      "AI Readiness Audit",
      "Use-case map",
      "Automation Sprint",
      "Team training",
      "Fractional AI Officer",
      "Vendor and model evaluation"
    ],
    requiredIntegrations: [],
    optionalIntegrations: ["all_client_systems"],
    defaultRiskLevel: "recommend",
    defaultPhases: ["lead", "diagnosis", "proposal", "pilot", "managed_run"],
    metrics: ["use_cases_identified", "automation_candidates", "training_completion", "roadmap_items_completed"],
    reports: ["ai_readiness_audit", "fractional_ai_officer_report"],
    dependencies: [],
    upsells: ["enterprise_bespoke", "enterprise_compliance", "smb_growth_partnership"]
  },
  {
    id: "enterprise_bespoke",
    name: "Bespoke",
    publicName: "Feerasta Bespoke",
    segment: "both",
    category: "custom_build",
    oneLine: "Custom AI agents, workflow automation, integrations, dashboards, internal apps, RAG, and private builds.",
    buyer: ["owner", "coo", "cio", "department_head", "operations_lead"],
    primaryOutcome: "Build the exact system when productized offers do not fit.",
    entryMotion: "blueprint_build_run",
    coreDeliverables: [
      "Blueprint",
      "Prototype",
      "Production build",
      "Integration layer",
      "Dashboard or internal app",
      "Runbook",
      "Managed run option"
    ],
    requiredIntegrations: ["client_specific"],
    optionalIntegrations: ["client_specific"],
    defaultRiskLevel: "act_with_approval",
    defaultPhases: ["lead", "diagnosis", "proposal", "pilot", "live", "managed_run"],
    metrics: ["workflow_completion_rate", "manual_hours_removed", "user_adoption", "error_rate", "approval_rate"],
    reports: ["bespoke_build_report", "managed_run_report"],
    dependencies: [],
    upsells: ["enterprise_advisory", "enterprise_compliance"]
  },
  {
    id: "enterprise_compliance",
    name: "Compliance",
    publicName: "Feerasta Compliance",
    segment: "both",
    category: "compliance",
    oneLine: "AI governance, privacy, accessibility, cookie consent, AI disclosure, audit trails, retention, and regulated readiness.",
    buyer: ["owner", "compliance_officer", "general_counsel", "security_lead"],
    primaryOutcome: "Make AI and web operations reviewable, policy-aligned, and ready for regulated work.",
    entryMotion: "scan_or_governance_assessment",
    coreDeliverables: [
      "Website compliance scan",
      "AI governance review",
      "Privacy and retention map",
      "Human-in-loop policy",
      "Audit trail design",
      "Disclosure and consent checklist",
      "Remediation backlog"
    ],
    requiredIntegrations: ["website_or_ai_system"],
    optionalIntegrations: ["policy_docs", "identity_provider", "logging_stack"],
    defaultRiskLevel: "recommend",
    defaultPhases: ["lead", "diagnosis", "proposal", "setup", "live", "managed_run"],
    metrics: ["issues_found", "issues_resolved", "audit_coverage", "approval_paths_defined"],
    reports: ["compliance_scan_report", "ai_governance_readiness_report"],
    dependencies: [],
    upsells: ["enterprise_sovereign", "enterprise_advisory"]
  },
  {
    id: "enterprise_knowledge",
    name: "Knowledge",
    publicName: "Feerasta Knowledge",
    segment: "enterprise",
    category: "knowledge",
    oneLine: "Permission-aware internal knowledge intelligence with citations.",
    buyer: ["coo", "cio", "knowledge_manager", "general_counsel", "department_head"],
    primaryOutcome: "Let teams ask policies, contracts, SOPs, matters, tickets, and reports in plain English.",
    entryMotion: "knowledge_assessment_then_pilot",
    coreDeliverables: [
      "Source inventory",
      "Permission model",
      "Document ingestion",
      "Citation-backed answers",
      "Refusal behavior",
      "Feedback loop",
      "Knowledge dashboard"
    ],
    requiredIntegrations: ["document_store", "identity_provider"],
    optionalIntegrations: ["slack", "teams", "notion", "sharepoint", "google_drive", "dms", "ticketing"],
    defaultRiskLevel: "observe",
    defaultPhases: ["lead", "diagnosis", "proposal", "pilot", "live", "managed_run"],
    metrics: ["queries_answered", "citation_accuracy", "unanswered_queries", "feedback_score", "time_saved_estimate"],
    reports: ["knowledge_usage_report", "knowledge_gap_report"],
    dependencies: ["enterprise_compliance"],
    upsells: ["enterprise_sovereign", "enterprise_bespoke"]
  },
  {
    id: "enterprise_procurement",
    name: "Procurement",
    publicName: "Feerasta Procurement",
    segment: "enterprise",
    category: "finance_ops",
    oneLine: "Vendor pricing, invoice anomaly detection, contract renewal alerts, supplier comparison, and spend leakage.",
    buyer: ["cfo", "controller", "procurement_lead", "operations_lead"],
    primaryOutcome: "Detect leakage and prevent spend drift across vendors and locations.",
    entryMotion: "finance_ops_assessment",
    coreDeliverables: [
      "Vendor price monitoring",
      "Invoice anomaly detection",
      "Contract renewal alerts",
      "Supplier comparison",
      "Spend leakage dashboard",
      "AP workflow automation"
    ],
    requiredIntegrations: ["ap_system_or_invoice_source"],
    optionalIntegrations: ["erp", "quickbooks", "xero", "netsuite", "bank_feed", "contract_repository"],
    defaultRiskLevel: "act_with_approval",
    defaultPhases: ["lead", "diagnosis", "proposal", "pilot", "live", "managed_run"],
    metrics: ["anomalies_detected", "savings_identified", "savings_approved", "renewals_caught", "supplier_variance"],
    reports: ["procurement_leakage_report", "vendor_scorecard"],
    dependencies: [],
    upsells: ["enterprise_bespoke", "enterprise_knowledge"]
  },
  {
    id: "partners",
    name: "Partners",
    publicName: "Feerasta Partners",
    segment: "both",
    category: "partner_program",
    oneLine: "Associations, franchises, referral agencies, and channel partners.",
    buyer: ["association_leader", "franchise_group", "agency_owner", "consultant"],
    primaryOutcome: "Distribute Feerasta through trusted networks.",
    entryMotion: "partner_application",
    coreDeliverables: [
      "Partner intake",
      "Referral tracking",
      "Co-branded reports",
      "Revenue-share rules",
      "Partner dashboard"
    ],
    requiredIntegrations: ["crm"],
    optionalIntegrations: ["partner_portal", "stripe", "hubspot"],
    defaultRiskLevel: "observe",
    defaultPhases: ["lead", "diagnosis", "proposal", "live", "managed_run"],
    metrics: ["referrals", "qualified_leads", "closed_clients", "partner_revenue"],
    reports: ["partner_pipeline_report"],
    dependencies: [],
    upsells: ["smb_growth_partnership", "enterprise"]
  },
  {
    id: "ventures",
    name: "Ventures",
    publicName: "Feerasta Ventures",
    segment: "enterprise",
    category: "venture_program",
    oneLine: "Fund and build AI companies for local business.",
    buyer: ["founder", "operator", "investor", "strategic_partner"],
    primaryOutcome: "Create or co-build AI companies from proven Feerasta operating patterns.",
    entryMotion: "venture_thesis_review",
    coreDeliverables: [
      "Venture thesis",
      "Operator diligence",
      "Prototype",
      "Pilot customer",
      "Investment or build agreement"
    ],
    requiredIntegrations: [],
    optionalIntegrations: [],
    defaultRiskLevel: "recommend",
    defaultPhases: ["lead", "diagnosis", "proposal", "pilot", "live"],
    metrics: ["theses_reviewed", "pilots_launched", "ventures_approved", "revenue_from_ventures"],
    reports: ["venture_review_memo"],
    dependencies: [],
    upsells: []
  }
];
```

## Core Database Model

Use these as relational tables or ORM models.

```sql
create table clients (
  id uuid primary key,
  name text not null,
  segment text not null check (segment in ('smb', 'enterprise')),
  industry text,
  website_url text,
  primary_contact_name text,
  primary_contact_email text,
  primary_contact_phone text,
  timezone text,
  lifecycle_stage text not null default 'lead',
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

create table client_locations (
  id uuid primary key,
  client_id uuid not null references clients(id),
  name text not null,
  address text,
  city text,
  region text,
  country text,
  phone text,
  google_business_profile_url text,
  created_at timestamptz not null default now()
);

create table client_offers (
  id uuid primary key,
  client_id uuid not null references clients(id),
  offer_id text not null,
  status text not null default 'lead',
  phase text not null default 'lead',
  commercial_model text not null default 'monthly',
  monthly_price_cents integer,
  setup_fee_cents integer,
  performance_fee_rules jsonb not null default '{}'::jsonb,
  start_date date,
  renewal_date date,
  owner_user_id uuid,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

create table integrations (
  id uuid primary key,
  client_id uuid not null references clients(id),
  provider text not null,
  status text not null default 'requested',
  auth_type text,
  scopes text[] not null default '{}',
  metadata jsonb not null default '{}'::jsonb,
  last_sync_at timestamptz,
  created_at timestamptz not null default now()
);

create table workflows (
  id uuid primary key,
  client_offer_id uuid not null references client_offers(id),
  workflow_key text not null,
  status text not null default 'draft',
  risk_level text not null,
  human_approval_required boolean not null default true,
  config jsonb not null default '{}'::jsonb,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

create table workflow_runs (
  id uuid primary key,
  workflow_id uuid not null references workflows(id),
  status text not null default 'queued',
  input jsonb not null default '{}'::jsonb,
  output jsonb not null default '{}'::jsonb,
  error text,
  started_at timestamptz,
  completed_at timestamptz,
  created_at timestamptz not null default now()
);

create table approvals (
  id uuid primary key,
  workflow_run_id uuid not null references workflow_runs(id),
  client_id uuid not null references clients(id),
  title text not null,
  summary text not null,
  proposed_action jsonb not null,
  status text not null default 'pending',
  approved_by uuid,
  approved_at timestamptz,
  rejected_reason text,
  created_at timestamptz not null default now()
);

create table reports (
  id uuid primary key,
  client_id uuid not null references clients(id),
  client_offer_id uuid references client_offers(id),
  report_type text not null,
  period_start date,
  period_end date,
  title text not null,
  summary text not null,
  metrics jsonb not null default '{}'::jsonb,
  recommendations jsonb not null default '[]'::jsonb,
  published_at timestamptz,
  created_at timestamptz not null default now()
);

create table audit_events (
  id uuid primary key,
  client_id uuid not null references clients(id),
  actor_type text not null,
  actor_id text,
  event_type text not null,
  object_type text,
  object_id text,
  payload jsonb not null default '{}'::jsonb,
  created_at timestamptz not null default now()
);
```

## Workflow Engine Contract

```ts
export interface WorkflowContext {
  clientId: string;
  clientOfferId: string;
  workflowKey: string;
  runId: string;
  integrationTokens: Record<string, string>;
  clientFacts: Record<string, unknown>;
  riskLevel: ActionRisk;
}

export interface WorkflowResult {
  status: "completed" | "needs_approval" | "failed";
  summary: string;
  metrics?: Record<string, number | string | boolean>;
  proposedAction?: {
    type: string;
    payload: Record<string, unknown>;
  };
  artifacts?: Array<{
    type: "report" | "transcript" | "document" | "dashboard" | "export";
    title: string;
    url?: string;
    content?: string;
  }>;
}

export interface WorkflowDefinition {
  key: string;
  offerIds: string[];
  name: string;
  description: string;
  riskLevel: ActionRisk;
  requiredIntegrations: string[];
  run: (ctx: WorkflowContext, input: Record<string, unknown>) => Promise<WorkflowResult>;
}
```

## AI Agent Contract

```ts
export interface AgentDefinition {
  id: string;
  name: string;
  offerIds: string[];
  systemPrompt: string;
  allowedTools: string[];
  disallowedActions: string[];
  defaultRiskLevel: ActionRisk;
  escalationRules: string[];
  outputSchema: Record<string, unknown>;
}

export const BASE_AGENT_RULES = `
You are a Feerasta operating agent.
You work for the client, but you do not pretend to be a licensed professional.
Use the client's approved facts, scripts, policies, and connected tools.
If information is missing, ask for it or mark the uncertainty.
Do not invent prices, legal advice, clinical advice, financial filings, or contractual commitments.
Do not send, pay, book, cancel, refund, or modify records unless the workflow allows it and approval rules are satisfied.
For every material recommendation, explain the source or reasoning in plain English.
`;
```

## Agents To Implement

### Agent: AI Front Desk

```ts
export const aiFrontDeskAgent: AgentDefinition = {
  id: "agent_ai_front_desk",
  name: "AI Front Desk Agent",
  offerIds: ["smb_front_desk", "smb_growth_partnership"],
  systemPrompt: `${BASE_AGENT_RULES}
Your job is to answer inbound calls or messages for a local business.
Goals in order:
1. Understand the caller's need.
2. Answer approved common questions.
3. Capture name, phone, email, desired service, urgency, location, and preferred time.
4. Book the appointment if booking is enabled.
5. Transfer with context if the caller needs a human.
6. Log a short summary to the CRM.

Never quote unapproved prices.
Never promise availability unless calendar lookup confirms it.
Never handle emergencies beyond the approved escalation script.
`,
  allowedTools: ["calendar.lookup", "calendar.book", "crm.createLead", "crm.updateContact", "phone.transfer", "sms.sendDraft"],
  disallowedActions: ["take_payment", "give_medical_advice", "give_legal_advice", "change_contract_terms"],
  defaultRiskLevel: "act_with_approval",
  escalationRules: [
    "Emergency or safety issue",
    "Angry customer",
    "Refund request",
    "Legal, medical, or insurance question",
    "Caller asks for owner or manager"
  ],
  outputSchema: {
    callerName: "string",
    callerPhone: "string",
    intent: "string",
    urgency: "low|medium|high|emergency",
    bookingStatus: "booked|needs_human|not_booked",
    summary: "string",
    nextAction: "string"
  }
};
```

### Agent: WhatsApp Assistant

```ts
export const whatsappAssistantAgent: AgentDefinition = {
  id: "agent_whatsapp_assistant",
  name: "WhatsApp Assistant",
  offerIds: ["smb_assistant", "smb_ledger", "smb_front_desk"],
  systemPrompt: `${BASE_AGENT_RULES}
Your job is to receive forwarded messages, photos, receipts, invoices, documents, and voice notes.
Classify each item, extract structured fields, file it, and create reminders or tasks when requested.
If the owner asks a business question, answer only from connected data and cite the source system or document.
`,
  allowedTools: ["ocr.extract", "docs.file", "tasks.create", "reminders.create", "ledger.query", "crm.search"],
  disallowedActions: ["pay_bill", "send_external_message_without_approval", "delete_document"],
  defaultRiskLevel: "draft",
  escalationRules: [
    "Document is unreadable",
    "Amount seems unusually high",
    "Request would send money or bind the business",
    "Question requires accountant, lawyer, or clinician"
  ],
  outputSchema: {
    itemType: "receipt|invoice|contract|note|question|other",
    extractedFields: "object",
    filedLocation: "string",
    remindersCreated: "array",
    answer: "string"
  }
};
```

### Agent: Ledger

```ts
export const ledgerAgent: AgentDefinition = {
  id: "agent_ledger",
  name: "Ledger Agent",
  offerIds: ["smb_ledger", "enterprise_procurement"],
  systemPrompt: `${BASE_AGENT_RULES}
Your job is to watch invoices, receipts, bills, AR, AP, cash flow, margins, and vendor pricing.
You may flag anomalies, draft collection messages, prepare bill reminders, and summarize financial movement.
You do not file taxes, certify books, provide regulated accounting advice, or move money without approval.
`,
  allowedTools: ["ocr.extract", "accounting.query", "bankfeed.query", "crm.query", "email.draft", "whatsapp.draft", "report.create"],
  disallowedActions: ["pay_bill_without_approval", "file_tax_return", "certify_financials", "change_accounting_records_without_approval"],
  defaultRiskLevel: "act_with_approval",
  escalationRules: [
    "Potential fraud",
    "Large vendor overcharge",
    "Tax question",
    "Payroll question",
    "Customer dispute",
    "Write-off or refund request"
  ],
  outputSchema: {
    anomalyType: "overcharge|duplicate|late_ar|cash_warning|margin_warning|none",
    amountAtRisk: "number",
    evidence: "array",
    recommendedAction: "string",
    approvalRequired: "boolean"
  }
};
```

### Agent: Growth and Recover

```ts
export const growthRecoverAgent: AgentDefinition = {
  id: "agent_growth_recover",
  name: "Growth and Recover Agent",
  offerIds: ["smb_ascent", "smb_recover", "smb_growth_partnership"],
  systemPrompt: `${BASE_AGENT_RULES}
Your job is to recover and create demand from existing assets: missed calls, dormant customers, old quotes, reviews, local search presence, and AI search visibility.
You may segment lists, draft campaigns, identify opportunities, and prepare review requests.
You must respect consent, opt-out rules, and approved campaign language.
`,
  allowedTools: ["crm.segment", "sms.draftCampaign", "whatsapp.draftCampaign", "email.draftCampaign", "gbp.query", "reviews.requestDraft", "report.create"],
  disallowedActions: ["send_campaign_without_approval", "message_opted_out_contact", "post_fake_review", "misrepresent_business"],
  defaultRiskLevel: "act_with_approval",
  escalationRules: [
    "Low consent confidence",
    "Sensitive health, legal, or finance campaign",
    "Negative review response",
    "Aggressive or misleading offer"
  ],
  outputSchema: {
    campaignType: "reactivation|review_request|missed_call|quote_followup|failed_payment|no_show",
    audienceSize: "number",
    proposedMessage: "string",
    expectedOutcome: "string",
    approvalRequired: "boolean"
  }
};
```

### Agent: Enterprise Knowledge

```ts
export const knowledgeAgent: AgentDefinition = {
  id: "agent_enterprise_knowledge",
  name: "Enterprise Knowledge Agent",
  offerIds: ["enterprise_knowledge", "enterprise_sovereign", "enterprise_bespoke"],
  systemPrompt: `${BASE_AGENT_RULES}
Your job is to answer questions from approved internal sources with citations.
Obey document permissions and source boundaries.
If the answer is not in the approved corpus, say so.
For legal, clinical, financial, compliance, or HR matters, provide source-grounded information and escalate for professional review where required.
`,
  allowedTools: ["knowledge.search", "documents.retrieve", "citations.render", "ticket.create", "report.create"],
  disallowedActions: ["answer_without_source", "bypass_permissions", "provide_final_legal_or_clinical_advice"],
  defaultRiskLevel: "observe",
  escalationRules: [
    "No citation found",
    "Conflicting sources",
    "Regulated decision requested",
    "User lacks permission",
    "Matter involves employment, legal, medical, or financial risk"
  ],
  outputSchema: {
    answer: "string",
    citations: "array",
    confidence: "low|medium|high",
    escalationRequired: "boolean",
    sourceGaps: "array"
  }
};
```

### Agent: Compliance

```ts
export const complianceAgent: AgentDefinition = {
  id: "agent_compliance",
  name: "Compliance Agent",
  offerIds: ["enterprise_compliance", "enterprise_sovereign", "enterprise"],
  systemPrompt: `${BASE_AGENT_RULES}
Your job is to inspect websites, AI workflows, policies, consent surfaces, retention rules, audit logs, and governance gaps.
You may create findings, severity ratings, remediation steps, and readiness reports.
You do not provide legal advice. You prepare operational compliance evidence for review.
`,
  allowedTools: ["website.scan", "policy.search", "workflow.inspect", "audit.query", "report.create"],
  disallowedActions: ["declare_legal_compliance_certified", "modify_policy_without_approval"],
  defaultRiskLevel: "recommend",
  escalationRules: [
    "Possible legal exposure",
    "Missing consent for customer messaging",
    "Sensitive data in unapproved tool",
    "No audit trail for high-risk action"
  ],
  outputSchema: {
    findings: "array",
    severity: "low|medium|high|critical",
    remediationPlan: "array",
    owner: "string",
    dueDate: "string"
  }
};
```

## Workflow Definitions By Offer

### SMB Assistant Workflows

```ts
export const assistantWorkflows: WorkflowDefinition[] = [
  {
    key: "assistant.capture_document",
    offerIds: ["smb_assistant", "smb_ledger"],
    name: "Capture document from WhatsApp",
    description: "Receive a photo, PDF, or forwarded message, extract fields, classify, and file it.",
    riskLevel: "draft",
    requiredIntegrations: ["whatsapp"],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Document captured, classified, and filed.",
        metrics: { documents_captured: 1 },
        artifacts: [{ type: "document", title: "Captured document metadata", content: JSON.stringify(input) }]
      };
    }
  },
  {
    key: "assistant.daily_briefing",
    offerIds: ["smb_assistant", "smb_front_desk", "smb_ledger"],
    name: "Daily owner briefing",
    description: "Summarize today's calls, bookings, tasks, bills, reminders, and money alerts.",
    riskLevel: "observe",
    requiredIntegrations: [],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Daily briefing generated.",
        metrics: { briefings_sent: 1 }
      };
    }
  }
];
```

### AI Front Desk Workflows

```ts
export const frontDeskWorkflows: WorkflowDefinition[] = [
  {
    key: "front_desk.inbound_call",
    offerIds: ["smb_front_desk", "smb_growth_partnership"],
    name: "Inbound AI receptionist call",
    description: "Answer, qualify, book, transfer, and summarize inbound calls.",
    riskLevel: "act_with_approval",
    requiredIntegrations: ["phone", "calendar"],
    async run(ctx, input) {
      return {
        status: "needs_approval",
        summary: "Caller qualified and appointment slot proposed.",
        proposedAction: {
          type: "book_appointment",
          payload: input
        }
      };
    }
  },
  {
    key: "front_desk.missed_call_textback",
    offerIds: ["smb_front_desk", "smb_ascent", "smb_growth_partnership"],
    name: "Missed-call text-back",
    description: "Text missed callers in seconds and drive them to booking.",
    riskLevel: "act_autonomously",
    requiredIntegrations: ["phone", "sms"],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Missed caller received text-back.",
        metrics: { missed_calls_texted: 1 }
      };
    }
  },
  {
    key: "front_desk.post_call_summary",
    offerIds: ["smb_front_desk", "smb_growth_partnership"],
    name: "Post-call summary and CRM log",
    description: "Summarize every call and write structured notes to CRM.",
    riskLevel: "draft",
    requiredIntegrations: ["crm"],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Call summary logged to CRM.",
        metrics: { calls_logged: 1 }
      };
    }
  }
];
```

### Ascent and Recover Workflows

```ts
export const growthWorkflows: WorkflowDefinition[] = [
  {
    key: "growth.competitive_report",
    offerIds: ["smb_ascent", "smb_growth_partnership"],
    name: "Free competitive-analysis report",
    description: "Analyze local rankings, reviews, website, AI visibility, and missed-call risk.",
    riskLevel: "observe",
    requiredIntegrations: [],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Competitive report generated.",
        artifacts: [{ type: "report", title: "Competitive Analysis Report" }]
      };
    }
  },
  {
    key: "recover.database_reactivation",
    offerIds: ["smb_recover", "smb_ascent", "smb_growth_partnership"],
    name: "Database reactivation",
    description: "Segment dormant customers and draft a win-back campaign.",
    riskLevel: "act_with_approval",
    requiredIntegrations: ["crm_or_customer_list"],
    async run(ctx, input) {
      return {
        status: "needs_approval",
        summary: "Dormant customer campaign drafted.",
        proposedAction: {
          type: "send_campaign",
          payload: input
        }
      };
    }
  },
  {
    key: "growth.review_generation",
    offerIds: ["smb_ascent", "smb_growth_partnership"],
    name: "Review generation",
    description: "Ask happy customers for reviews by WhatsApp, SMS, or email.",
    riskLevel: "act_with_approval",
    requiredIntegrations: ["crm_or_customer_list"],
    async run(ctx, input) {
      return {
        status: "needs_approval",
        summary: "Review request batch prepared.",
        proposedAction: {
          type: "send_review_requests",
          payload: input
        }
      };
    }
  }
];
```

### Ledger and Procurement Workflows

```ts
export const financeOpsWorkflows: WorkflowDefinition[] = [
  {
    key: "ledger.vendor_overcharge_check",
    offerIds: ["smb_ledger", "enterprise_procurement"],
    name: "Vendor overcharge detection",
    description: "Compare invoices against price history, price book, quantities, and contracts.",
    riskLevel: "recommend",
    requiredIntegrations: ["document_capture"],
    async run(ctx, input) {
      return {
        status: "needs_approval",
        summary: "Potential overcharge flagged.",
        metrics: { amount_at_risk: Number(input.amountAtRisk ?? 0) },
        proposedAction: {
          type: "query_vendor_invoice",
          payload: input
        }
      };
    }
  },
  {
    key: "ledger.ar_chasing",
    offerIds: ["smb_ledger", "smb_recover", "enterprise_procurement"],
    name: "Accounts receivable chasing",
    description: "Identify overdue invoices and draft staged collection messages.",
    riskLevel: "act_with_approval",
    requiredIntegrations: ["accounting"],
    async run(ctx, input) {
      return {
        status: "needs_approval",
        summary: "AR reminder prepared.",
        proposedAction: {
          type: "send_ar_reminder",
          payload: input
        }
      };
    }
  },
  {
    key: "ledger.monthly_money_read",
    offerIds: ["smb_ledger", "enterprise_procurement"],
    name: "Monthly money read",
    description: "Summarize cash in, cash out, margin warnings, collections, overcharges, and next actions.",
    riskLevel: "observe",
    requiredIntegrations: [],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Monthly money read generated.",
        artifacts: [{ type: "report", title: "Monthly Money Read" }]
      };
    }
  }
];
```

### Studio Workflows

```ts
export const studioWorkflows: WorkflowDefinition[] = [
  {
    key: "studio.demo_first_build",
    offerIds: ["smb_studio"],
    name: "Demo-first website build",
    description: "Generate a working website draft before the client decides.",
    riskLevel: "draft",
    requiredIntegrations: [],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Website demo created.",
        artifacts: [{ type: "document", title: "Website Demo Brief", content: JSON.stringify(input) }]
      };
    }
  },
  {
    key: "studio.monthly_care",
    offerIds: ["smb_studio"],
    name: "Monthly website care plan",
    description: "Run uptime, speed, SEO, accessibility, conversion, and content checks.",
    riskLevel: "recommend",
    requiredIntegrations: ["website"],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Website care report generated.",
        artifacts: [{ type: "report", title: "Monthly Website Care Report" }]
      };
    }
  }
];
```

### Enterprise Workflows

```ts
export const enterpriseWorkflows: WorkflowDefinition[] = [
  {
    key: "enterprise.assessment",
    offerIds: ["enterprise", "enterprise_advisory", "enterprise_sovereign", "enterprise_compliance"],
    name: "Enterprise AI assessment",
    description: "Map workflows, data, risks, integrations, governance gaps, and pilot candidates.",
    riskLevel: "recommend",
    requiredIntegrations: [],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Enterprise assessment completed.",
        artifacts: [{ type: "report", title: "Enterprise AI Assessment" }]
      };
    }
  },
  {
    key: "enterprise.pilot_readiness",
    offerIds: ["enterprise", "enterprise_sovereign", "enterprise_knowledge", "enterprise_bespoke"],
    name: "Pilot readiness review",
    description: "Define pilot scope, data access, success criteria, evaluation set, and oversight rules.",
    riskLevel: "recommend",
    requiredIntegrations: [],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Pilot readiness packet prepared.",
        artifacts: [{ type: "report", title: "Pilot Readiness Packet" }]
      };
    }
  },
  {
    key: "enterprise.managed_run_report",
    offerIds: ["enterprise", "enterprise_sovereign", "enterprise_knowledge", "enterprise_bespoke"],
    name: "Managed operation report",
    description: "Monthly operating report for deployed enterprise AI systems.",
    riskLevel: "observe",
    requiredIntegrations: [],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Managed run report generated.",
        artifacts: [{ type: "report", title: "Managed AI Operation Report" }]
      };
    }
  }
];
```

### Compliance and Knowledge Workflows

```ts
export const trustWorkflows: WorkflowDefinition[] = [
  {
    key: "compliance.website_scan",
    offerIds: ["enterprise_compliance", "smb_studio"],
    name: "Website compliance scan",
    description: "Scan HTTPS, privacy, cookies, accessibility basics, AI disclosure, and contact/legal pages.",
    riskLevel: "recommend",
    requiredIntegrations: ["website"],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Website compliance scan generated.",
        artifacts: [{ type: "report", title: "Website Compliance Scan" }]
      };
    }
  },
  {
    key: "knowledge.ingest_and_answer",
    offerIds: ["enterprise_knowledge", "enterprise_sovereign"],
    name: "Knowledge ingestion and citation Q&A",
    description: "Ingest approved sources, enforce permissions, and answer questions with citations.",
    riskLevel: "observe",
    requiredIntegrations: ["document_store", "identity_provider"],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Knowledge answer generated with citations.",
        metrics: { queries_answered: 1 }
      };
    }
  }
];
```

### Pulse and Edge Workflows

```ts
export const pulseWorkflows: WorkflowDefinition[] = [
  {
    key: "pulse.busyness_signal",
    offerIds: ["smb_pulse"],
    name: "Live busyness signal",
    description: "Read occupancy source and publish verified busy badge, capacity, and wait-time estimate.",
    riskLevel: "observe",
    requiredIntegrations: ["sensor_or_camera_or_pos_signal"],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Busyness signal updated.",
        metrics: {
          occupancy_percent: Number(input.occupancyPercent ?? 0),
          wait_time_minutes: Number(input.waitTimeMinutes ?? 0)
        }
      };
    }
  },
  {
    key: "edge.hardware_provisioning",
    offerIds: ["smb_pulse"],
    name: "Hardware provisioning",
    description: "Spec, source, configure, ship, and support the hardware required for a Feerasta workflow.",
    riskLevel: "recommend",
    requiredIntegrations: [],
    async run(ctx, input) {
      return {
        status: "completed",
        summary: "Hardware provisioning checklist created.",
        artifacts: [{ type: "document", title: "Hardware Provisioning Checklist" }]
      };
    }
  }
];
```

## API Routes To Add

Use route names that match the existing backend conventions.

```ts
export const routes = [
  "GET /api/offers",
  "GET /api/offers/:offerId",
  "POST /api/clients",
  "GET /api/clients/:clientId",
  "POST /api/clients/:clientId/offers",
  "PATCH /api/client-offers/:clientOfferId",
  "POST /api/client-offers/:clientOfferId/workflows",
  "POST /api/workflows/:workflowId/run",
  "GET /api/workflow-runs/:runId",
  "POST /api/approvals/:approvalId/approve",
  "POST /api/approvals/:approvalId/reject",
  "GET /api/clients/:clientId/reports",
  "POST /api/reports/:reportId/publish",
  "GET /api/clients/:clientId/audit-events"
];
```

Example request/response shapes:

```ts
export interface CreateClientOfferRequest {
  offerId: string;
  commercialModel: "monthly" | "setup_plus_monthly" | "performance" | "assessment" | "pilot" | "custom";
  monthlyPriceCents?: number;
  setupFeeCents?: number;
  performanceFeeRules?: Record<string, unknown>;
}

export interface RunWorkflowRequest {
  input: Record<string, unknown>;
  dryRun?: boolean;
}

export interface ApprovalDecisionRequest {
  decidedByUserId: string;
  note?: string;
}
```

## Internal Admin Screens

Build these screens in the Feerasta OS.

```ts
export const adminScreens = [
  {
    path: "/admin/offers",
    purpose: "Browse all offer definitions, dependencies, metrics, and required integrations."
  },
  {
    path: "/admin/clients",
    purpose: "CRM list of SMB and Enterprise clients with segment, lifecycle stage, and active offers."
  },
  {
    path: "/admin/clients/:clientId",
    purpose: "Client command center: contacts, locations, offers, integrations, workflows, approvals, reports, audit events."
  },
  {
    path: "/admin/client-offers/:clientOfferId/runbook",
    purpose: "Offer-specific setup checklist, live workflows, reporting cadence, and operator owner."
  },
  {
    path: "/admin/approvals",
    purpose: "Review pending actions before AI sends, books, changes records, escalates, or contacts customers."
  },
  {
    path: "/admin/reports",
    purpose: "Draft, review, publish, and archive client reports."
  },
  {
    path: "/admin/enterprise/security-review",
    purpose: "Enterprise assessment packets: data architecture, model policy, audit trail, access controls, deployment posture."
  }
];
```

## Client Portal Screens

```ts
export const clientPortalScreens = [
  {
    path: "/portal",
    purpose: "Client home: active offers, next actions, approvals, recent reports, ROI summary."
  },
  {
    path: "/portal/approvals",
    purpose: "Approve or reject AI-proposed actions."
  },
  {
    path: "/portal/reports",
    purpose: "Owner-facing reports and exported deliverables."
  },
  {
    path: "/portal/front-desk",
    purpose: "Calls, bookings, missed-call recovery, and scripts."
  },
  {
    path: "/portal/ledger",
    purpose: "Overcharges, AR, bills, margin warnings, monthly money read."
  },
  {
    path: "/portal/growth",
    purpose: "Rankings, reviews, campaigns, recovered jobs, and market position."
  },
  {
    path: "/portal/enterprise",
    purpose: "Pilot status, security packet, audit events, managed run reports."
  }
];
```

## Offer Runbooks

Every client offer should generate a runbook from its registry definition.

```ts
export interface Runbook {
  clientOfferId: string;
  offerId: string;
  setupChecklist: ChecklistItem[];
  operatingCadence: CadenceItem[];
  approvalRules: ApprovalRule[];
  reportSchedule: ReportSchedule[];
  escalationContacts: EscalationContact[];
}

export interface ChecklistItem {
  key: string;
  label: string;
  owner: "feerasta" | "client" | "partner";
  required: boolean;
  status: "not_started" | "waiting" | "in_progress" | "done" | "blocked";
}

export interface CadenceItem {
  frequency: "daily" | "weekly" | "monthly" | "quarterly";
  task: string;
  owner: "agent" | "operator" | "client";
}

export interface ApprovalRule {
  actionType: string;
  riskLevel: ActionRisk;
  approvalRequired: boolean;
  approverRole: string;
}

export interface ReportSchedule {
  reportType: string;
  frequency: "weekly" | "monthly" | "quarterly";
  audience: string[];
}

export interface EscalationContact {
  name: string;
  role: string;
  email?: string;
  phone?: string;
  escalationTypes: string[];
}
```

## Default Approval Rules

```ts
export const DEFAULT_APPROVAL_RULES: ApprovalRule[] = [
  {
    actionType: "send_customer_message",
    riskLevel: "act_with_approval",
    approvalRequired: true,
    approverRole: "client_owner"
  },
  {
    actionType: "book_appointment",
    riskLevel: "act_with_approval",
    approvalRequired: false,
    approverRole: "client_owner"
  },
  {
    actionType: "send_marketing_campaign",
    riskLevel: "act_with_approval",
    approvalRequired: true,
    approverRole: "client_owner"
  },
  {
    actionType: "query_vendor_invoice",
    riskLevel: "recommend",
    approvalRequired: true,
    approverRole: "finance_contact"
  },
  {
    actionType: "pay_bill",
    riskLevel: "act_with_approval",
    approvalRequired: true,
    approverRole: "client_owner"
  },
  {
    actionType: "change_system_record",
    riskLevel: "act_with_approval",
    approvalRequired: true,
    approverRole: "system_owner"
  },
  {
    actionType: "answer_knowledge_question",
    riskLevel: "observe",
    approvalRequired: false,
    approverRole: "none"
  }
];
```

## Reporting Templates

### SMB Growth Partnership ROI Report

```ts
export interface GrowthPartnershipReport {
  periodStart: string;
  periodEnd: string;
  bookedJobs: number;
  recoveredMissedCalls: number;
  reactivatedCustomers: number;
  reviewsRequested: number;
  reviewsGained: number;
  estimatedRevenueRecoveredCents: number;
  websiteConversions: number;
  topWins: string[];
  nextActions: string[];
}
```

### Ledger Monthly Money Read

```ts
export interface LedgerMonthlyMoneyRead {
  periodStart: string;
  periodEnd: string;
  cashInCents: number;
  cashOutCents: number;
  overdueReceivablesCents: number;
  overchargesFlaggedCents: number;
  overchargesRecoveredCents: number;
  billsDueSoon: Array<{ vendor: string; amountCents: number; dueDate: string }>;
  marginWarnings: Array<{ item: string; warning: string; amountAtRiskCents?: number }>;
  accountantNotes: string[];
  ownerSummary: string;
}
```

### Enterprise Managed AI Operation Report

```ts
export interface EnterpriseManagedRunReport {
  periodStart: string;
  periodEnd: string;
  activeWorkflows: number;
  workflowRuns: number;
  successfulRuns: number;
  failedRuns: number;
  humanApprovals: number;
  escalations: number;
  auditEvents: number;
  knowledgeQueries?: number;
  citationAccuracy?: number;
  securityIncidents: number;
  changesShipped: string[];
  risksAndRecommendations: string[];
}
```

## Acceptance Criteria

Implementation is complete when:

1. Product registry exists and includes all offers above.
2. Admin can create a client, assign one or more offers, and see generated runbooks.
3. Each offer can create default workflows from the registry.
4. Workflow runs are logged with input, output, status, metrics, and audit events.
5. Risky actions generate approval records before execution.
6. Client portal shows approvals, reports, active offers, and ROI/status summaries.
7. SMB and Enterprise sales motions are separated in UI and data.
8. Reports can be generated for:
   - Growth Partnership ROI.
   - Ledger Monthly Money Read.
   - Enterprise Managed AI Operation.
9. Enterprise security review packet includes:
   - Data architecture.
   - Human-in-loop policy.
   - Audit logging.
   - Model/vendor policy.
   - Private deployment options.
10. All agent prompts include safety, escalation, and no-unapproved-action rules.

## Implementation Order

1. Add shared product registry and offer definitions.
2. Add database tables or ORM models.
3. Add client/offers/workflows/reports API routes.
4. Add runbook generator.
5. Add approval system.
6. Add SMB workflows:
   - Assistant.
   - AI Front Desk.
   - Ascent.
   - Studio.
   - Ledger.
   - Recover.
   - Growth Partnership.
7. Add Enterprise workflows:
   - Assessment.
   - Sovereign.
   - Compliance.
   - Knowledge.
   - Bespoke.
   - Procurement.
8. Add admin screens.
9. Add client portal screens.
10. Add reporting templates and scheduled report jobs.
11. Add audit events everywhere an agent reads, recommends, drafts, sends, books, or changes state.

## Notes For Codex

- Do not implement autonomous send/pay/change behavior before the approval layer exists.
- Prefer explicit workflow configuration over hidden prompt-only behavior.
- Keep offer names public-facing, but use stable internal IDs for code.
- Do not let Enterprise clients see SMB pricing pages as their main flow.
- Do not call Ledger a tax or accounting certification product.
- Do not call Compliance legal certification.
- Keep Pulse separate from Edge. Pulse is the product; Edge is hardware provisioning and support.
