Reference
RankFlow AI — End-to-End Business Process Flow Map
This document maps every single touchpoint across RankFlow AI's business flow — from pre-sales discovery through onboarding, active service, to cancellation and offboarding. It ser
docs/business_flow_map.mdOn this page
- Document Purpose
- How to Read This Document
- Master Table of Contents
- Section 1: Executive Summary
- 1.1 Business Model Overview
- 1.2 Target Customer Profile
- 1.3 Core Value Proposition
- 1.4 Key Stakeholders
- Section 2: Pre-Sales & Discovery Touchpoints
- 2.1 Lead Acquisition Channels
- 2.2 Sales Conversation Flow
- 2.3 Trial Signup Flow
- 2.4 Pre-Onboarding Data Collection
- Section 3: Customer Onboarding Flow (Step-by-Step)
- Onboarding Flow Overview
- Step 1: Account Creation & Plan Selection
- Step 2: Business Profile Capture Form
- Step 3: Consent & Terms Acceptance
- Step 4: Payment Method Setup
- Step 5: Directory URL Assignment
- Step 6: Directory Profile AI Content Generation
- Step 7: Directory Profile Deployment
- Step 8: GBP OAuth Connection Request Email
- Step 9: GBP OAuth Flow & Token Storage
- Step 10: GBP Location Sync
- Step 11: Social Media Connection Prompts
- Step 12: Citation Directory Description Generation (30 Unique)
- Step 13: Citation Submission to 30 Directories
- Step 14: NAP Verification Scheduling
- Step 15: First GBP Post Generation & Approval Queue
- Step 16: First Social Posts Generation & Approval Queue
- Step 17: Welcome Email with Dashboard Link
- Step 18: Welcome Report Generation
- Step 19: Onboarding Completion Notification
- Step 20: Admin Notification of New Client
- Onboarding Summary Table
- Section 4: Active Customer Journey (Daily/Weekly/Monthly)
- 4.1 Daily Automation Touchpoints
- 4.2 Weekly Automation Touchpoints
- 4.3 Monthly Automation Touchpoints
- 4.4 Customer Actions in Dashboard
- 4.5 RankFlow Actions Behind the Scenes
- 4.6 Communication Touchpoints
- Appendix A: Actor Legend
- Appendix B: Key System Endpoints
- Appendix C: Data Model Summary
- Section 5: What RankFlow Automates (Comprehensive)
- 5.1 SEO Hygiene Automation
- 5.2 Citation Network Automation
- 5.3 GBP Management Automation
- 5.4 Social Media Automation
- 5.5 Content Generation Automation
- 5.6 Review Management Automation
- 5.7 Reporting Automation
- 5.8 Directory Profile Automation
- 5.9 AI Engine Optimization Automation
- Section 6: Admin Dashboard & Observability
- 6.1 Admin Dashboard Pages & Functions
- 6.2 Observability Metrics (Real-Time)
- 6.3 Alert Thresholds & Notifications
- 6.4 System Health Monitoring
- 6.5 Cost & Performance Tracking
- Section 7: Fail-Safe Conditions & Error Handling
- 7.1 Job Failure Handling
- 7.2 API Rate Limit Protection
- 7.3 GBP Suspension Prevention
- 7.4 Token Expiry & Refresh
- 7.5 Content Quality Gates
- 7.6 Emergency Stop Procedures
- 7.7 Data Integrity Safeguards
- Section 8: Cancellation & Offboarding Flow
- 8.1 Cancellation Triggers
- 8.2 Grace Period & Retention Attempts
- 8.3 Data & Asset Decommissioning
- 8.4 Citation Removal Process
- 8.5 Final Report & Export
- Section 9: Tool & Feature Gap Analysis
- 9.1 Current Tool Inventory
- 9.2 Missing Tools / Features
- 9.3 Future Enhancement Roadmap
- 9.4 Integration Wishlist
- Section 10: Appendix — Touchpoint Matrix
- Complete Lifecycle Touchpoint Registry (50+ Touchpoints)
- Touchpoint Frequency Summary
- Section 11: Addendum — Directory Profile System 2.0
- 11.1 The Four New Capabilities
- 11.2 Revised Onboarding Flow (Directory Profile Focus)
- 11.3 External Site Integration Path (New Onboarding Branch)
- 11.4 Key Metrics for the New System
- 11.5 What This Changes in the Existing Document
Document Version: 2.0.0 Date: June 2026 Author: Business Process & Operations Analysis Product: RankFlow AI — AI-Powered Local SEO Platform for Indian Medical SMBs Target Audience: Engineering, Operations, Customer Success, Leadership, Founders Classification: Internal — Engineering & Operations Handoff
Document Purpose#
This document maps every single touchpoint across RankFlow AI's business flow — from pre-sales discovery through onboarding, active service, to cancellation and offboarding. It serves as the single source of truth for:
- Engineering: What to build, in what order, with what fail-safes
- Operations: What the team monitors, approves, and intervenes on
- Customer Success: What customers experience, when, and why
- Leadership: What is automated vs. manual, where the moat lives, what gaps remain
How to Read This Document#
- [C] = Customer action (the medical SMB owner/practitioner)
- [S] = System automation (RankFlow AI engine, no human intervention)
- [A] = Admin/Operations team action (founder, support, ops staff)
- Frequency: One-time / Daily / Weekly / Monthly / Event-driven / Continuous
Master Table of Contents#
- Executive Summary
- Pre-Sales & Discovery Touchpoints
- Customer Onboarding Flow (Step-by-Step)
- Active Customer Journey (Daily/Weekly/Monthly)
- What RankFlow Automates (Comprehensive)
- Admin Dashboard & Observability
- Fail-Safe Conditions & Error Handling
- Cancellation & Offboarding Flow
- Tool & Feature Gap Analysis
- Appendix: Complete Touchpoint Matrix
- Addendum: Directory Profile System 2.0 — Composable Design + AI Editor + External Site Integration
Section 1: Executive Summary#
1.1 Business Model Overview#
RankFlow AI is a B2B SaaS platform delivering fully automated local SEO for Indian small and medium businesses (SMBs), with an initial vertical focus on medical professionals — doctors, dentists, clinics, and hospitals. The platform replaces the traditional SEO agency model (Rs 15,000–50,000/month) with an AI-driven, self-service product priced at Rs 4,000–20,000/month.
The core business model is subscription-based recurring revenue with a 7-day free trial. The platform automates six integrated SEO modules that traditionally require 3–5 separate vendors:
| Module | Traditional Cost | RankFlow AI Approach |
|---|---|---|
| Citation Network (30 sites) | BrightLocal + manual labor | AI-generated unique descriptions + automated submission to 25 directories + 5 owned blog sites |
| AI-Generated Directory Profile | WordPress developer + hosting | Next.js ISR directory URL with ISR, schema injection, 5 vertical templates |
| GBP Management | Agency VA + manual posting | Google Business Profile API OAuth, automated posts, review replies, insights |
| Social Media Automation | Social media manager | Composio/Zernio API scheduling to Instagram, Facebook, LinkedIn, Twitter |
| Review Management | Reputation agency | Daily poll + AI sentiment-gated replies (auto-positive, manual-negative) |
| Monthly Reporting | Manual Excel + PDF | Playwright-generated PDF + Resend email delivery |
Target Gross Margin: ~85% at scale (100+ clients) Primary Moat: 20–50 high-DA owned citation sites + retention lock-in via owned directory profile infrastructure Core Tagline: "Rank. Grow. Results."
1.2 Target Customer Profile#
| Attribute | Specification |
|---|---|
| Primary Vertical | Medical doctors, dentists, clinics, hospitals |
| Geographic Focus | Phase 1: Kerala → Phase 2: South India → Phase 3: PAN India |
| Business Size | Solo practitioners (1 doctor), small clinics (2–5 doctors), dental chains |
| Decision Maker | Doctor/owner directly, or clinic administrator |
| Tech Sophistication | Low to medium — uses WhatsApp, Google Maps, Practo; not technical |
| Pain Points | No Google Maps presence, inconsistent NAP data, zero schema markup, no social media presence, paying Rs 15K–50K/month to agencies with no transparency |
| Willingness to Pay | Rs 4,000–12,000/month for solo practitioners; Rs 12,000–20,000/month for clinics |
| Secondary Verticals | Chartered Accountants, lawyers, wedding photographers |
1.3 Core Value Proposition#
"One form. 60 minutes. Everything live."
A medical SMB completes a single 5-minute onboarding form. Within 60 minutes, RankFlow AI:
- Generates and deploys an SEO-optimized directory profile with schema markup
- Submits 30 unique business descriptions to 25 directories + 5 owned blog sites
- Connects and syncs Google Business Profile data
- Generates first GBP post + first social media posts (pending approval)
- Activates daily review monitoring and automated reply pipeline
- Delivers a welcome report with live citation URLs and dashboard access
1.4 Key Stakeholders#
┌─────────────────────────────────────────────────────────────┐
│ STAKEHOLDER MAP │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ CUSTOMER │◄───────►│ RANKFLOW │ │
│ │ (Doctor/ │ Uses │ SYSTEM │ │
│ │ Clinic) │ │ (Next.js + │ │
│ │ │ │ AI Engine)│ │
│ └─────────────┘ └──────┬──────┘ │
│ ▲ │ │
│ │ Reports/Alerts │ Jobs/Queues │
│ │ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ ADMIN/OPS │◄───────►│ EXTERNAL │ │
│ │ TEAM │ Manages │ SERVICES │ │
│ │ (Founder + │ │ (Google, │ │
│ │ Support) │ │ Composio, │ │
│ │ │ │ Zernio) │ │
│ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
| Stakeholder | Role | Primary Touchpoints | System Access |
|---|---|---|---|
| Customer | Medical SMB owner/practitioner | Onboarding form, dashboard, email reports, approval queue, review inbox | /dashboard/* (CLIENT role) |
| RankFlow System | AI + automation engine | Job queues, LLM router, citation submission, GBP API, social posting | Internal services, tRPC API, Inngest, BullMQ |
| Admin/Ops Team | Founder + support staff | Admin dashboard, job monitoring, content approval, billing management, customer support | /admin/* (ADMIN role) |
| External Services | Google, Composio, Zernio, directories | OAuth, API calls, posting, scheduling | Third-party APIs |
Section 2: Pre-Sales & Discovery Touchpoints#
2.1 Lead Acquisition Channels#
AWARENESS ──► INTEREST ──► CONSIDERATION ──► INTENT ──► SIGNUP
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌───────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐
│Website│ │Landing │ │Pricing │ │Trial │ │Account │
│(SEO) │ │Page │ │Page │ │Signup │ │Created │
├───────┤ ├─────────┤ ├──────────┤ ├──────────┤ ├─────────┤
│Refer- │ │Case │ │Plan │ │7-Day Free│ │Onboard- │
│rals │ │Studies │ │Comparison│ │Trial │ │ing Begins│
├───────┤ ├─────────┤ ├──────────┤ ├──────────┤ ├─────────┤
│Paid │ │Demo │ │FAQ │ │Payment │ │ │
│Ads │ │Booking │ │ │ │Capture │ │ │
├───────┤ ├─────────┤ ├──────────┤ ├──────────┤ ├─────────┤
│Partner│ │Webinar │ │ │ │ │ │ │
│Agencies│ │ │ │ │ │ │ │ │
└───────┘ └─────────┘ └──────────┘ └──────────┘ └─────────┘
| Channel | Mechanism | Target Audience | Tracking | Expected Volume (Month 6) |
|---|---|---|---|---|
| Organic Website | rankflow.ai homepage + blog content |
Doctors searching "local SEO for doctors India" | UTM:utm_source=organic |
30% of leads |
| Paid Ads (Meta) | Facebook/Instagram ads targeting "doctors in Kochi" | Kerala medical professionals | UTM:utm_source=meta_ads |
25% of leads |
| Paid Ads (Google) | Google Search Ads: "SEO for doctors Kerala" | High-intent searchers | UTM:utm_source=google_ads |
20% of leads |
| Referrals | Existing client refers another doctor | Trust-based warm leads | UTM:utm_source=referral |
15% of leads |
| Partner Agencies | ICO/marketing agencies white-label or resell | Agency clients | UTM:utm_source=partner |
10% of leads |
| Events/Webinars | Local medical association talks, CME events | In-person relationship | UTM:utm_source=event |
<5% of leads |
Lead Capture Mechanism: All channels drive to rankflow.ai directory profile with:
- Primary CTA: "Start Your 7-Day Free Trial"
- Secondary CTA: "Book a Free Demo Call"
- Lead magnet: "Free Local SEO Audit for Your Practice" (email capture)
2.2 Sales Conversation Flow#
| Stage | Actor | Touchpoint | Duration | Success Criteria | Failure Handling |
|---|---|---|---|---|---|
| Lead Qualification | [A] Admin/Founder | Review lead source + practice info from signup form or Calendly booking | 5 min | Lead matches ICP (medical, Kerala, has GBP or willing to create) | Non-ICP lead → nurture email sequence, re-engage in 30 days |
| Discovery Call | [A] + [C] | Calendly-scheduled 15-min call. Script: current pain points, current spend, GBP status, social presence, goals | 15 min | Customer confirms pain + budget fit + willingness to trial | No-show → 2x reschedule attempts → email nurture with case study |
| Demo / Screen Share | [A] + [C] | Live walkthrough of dashboard, sample report, citation network. Show competitor comparison. | 20 min | Customer sees value, asks pricing/plan questions | No interest → send case study PDF + follow up in 7 days |
| Objection Handling | [A] + [C] | Common objections: "I have an agency" (show cost comparison), "I don't understand tech" (emphasize done-for-you), "Will this work for me?" (show Kerala-specific results) | 10 min | Objections resolved, customer agrees to trial | Unresolved → add to long-term nurture, invite to webinar |
| Trial Commitment | [C] | Customer clicks "Start Free Trial" from demo follow-up email or directly from website | 2 min | Account created, plan selected, onboarding initiated | Abandoned signup → automated email sequence (3 emails over 48h) |
Discovery Call Script Framework:
1. CONTEXT (2 min)
"Dr. [Name], I see you're a [specialty] in [city]. How do patients currently find you online?"
2. PAIN AMPLIFICATION (3 min)
"Most doctors I speak with tell me one of three things:
- They pay an agency Rs 15-50K/month but have no idea what's being done
- They know they need Google Maps presence but don't know how to get it
- They have citations but the phone number is wrong on half of them"
"Which resonates with you?"
3. SOLUTION PREVIEW (5 min)
"RankFlow AI is different. You fill one 5-minute form. Our AI builds 30 citations,
creates your directory profile, manages your Google Business Profile, and posts to
social media — all automatically. You get a dashboard to see everything."
4. SOCIAL PROOF (3 min)
"Dr. Rajesh in Kochi, a dentist, went from zero online presence to top 3 in
Google Maps in 8 weeks. He pays Rs 8,000/month — one-fifth of his previous agency."
5. NEXT STEP (2 min)
"I'd like to set you up with a 7-day free trial. No payment required.
If you don't see value, you cancel with one click. Shall we proceed?"
2.3 Trial Signup Flow#
| Step | Actor | Action | System Component | Time | Success Criteria | Failure Handling |
|---|---|---|---|---|---|---|
| 2.3.1 | [C] | Clicks "Start Free Trial" on rankflow.ai |
Directory profile CTA | Instant | UTM params captured | — |
| 2.3.2 | [C] | Selects plan from comparison table | /signup page |
1 min | Plan selected: Starter/Standard/Premium/Enterprise | Abandon → exit-intent popup with "Questions? Chat with us" |
| 2.3.3 | [C] | Enters email + password + practice name | Auth form (NextAuth.js Credentials) | 1 min | Valid email format, password ≥8 chars | Validation error displayed inline |
| 2.3.4 | [S] | Creates User record (role=CLIENT) + ClientProfile with status=TRIAL |
Prisma ORM + PostgreSQL | 2 sec | DB record created with UUID | DB error → retry 3x → alert admin |
| 2.3.5 | [C] | Enters payment method (card/UPI) for trial authorization | Stripe/Razorpay checkout | 2 min | Payment method tokenized, Rs 1 authorization hold | Payment fails → offer "Start trial without payment — pay in 3 days" fallback |
| 2.3.6 | [S] | Stores payment method, creates subscription with trial_end=now+7d |
Stripe/Razorpay API + webhook handler | 3 sec | Subscription status=trialing |
Webhook failure → manual reconciliation queue |
| 2.3.7 | [S] | Sends welcome email with onboarding link + video guide | Resend API →emailSend BullMQ queue |
5 sec | Email delivered (track via Resend webhook) | Bounce → alert admin, retry with alternate email if provided |
| 2.3.8 | [S] | Redirects to onboarding wizard | Next.js router →/onboarding |
Instant | Customer lands on Step 1 of onboarding form | — |
Plan Comparison at Signup:
| Plan | Monthly Price | Citations | Social Posts/mo | GBP Posts/mo | Directory Profile URL | Trial Eligible |
|---|---|---|---|---|---|---|
| Starter | Rs 4,000 | 15 | 4 | 4 | ❌ | ✅ |
| Standard | Rs 8,000 | 25 | 8 | 8 | ❌ | ✅ |
| Premium | Rs 12,000 | 30 | 12 | 12 | ✅ | ✅ |
| Enterprise | Rs 20,000 | 30+ | 20 | 20 | ✅ + White-label | ❌ (demo only) |
Payment Capture Rules:
- Trial requires payment method for all plans (fraud prevention)
- Rs 1 authorization hold only — no charge during trial
- Auto-converts to paid subscription on Day 8 unless cancelled
- 3-day grace period after trial ends before data removal begins
2.4 Pre-Onboarding Data Collection#
Before the customer begins the onboarding wizard, the following data is already captured:
| Data Field | Source | Used For | Validation |
|---|---|---|---|
| Signup form | Auth, all email communications | Regex + DNS MX check | |
| Password | Signup form | Authentication | bcrypt hash, ≥8 chars |
| Practice Name | Signup form | Directory URL generation, citation NAP | Length 3–100 chars |
| Selected Plan | Plan selection | Feature flags, billing | Enum: STARTER/STANDARD/PREMIUM/ENTERPRISE |
| Payment Method Token | Stripe/Razorpay | Billing, subscription management | Tokenized, never stored raw |
| Subscription ID | Stripe/Razorpay webhook | Billing lifecycle | UUID from payment provider |
| UTM Parameters | Directory profile | Attribution, channel ROI | Stored in ClientProfile.utmSource etc. |
| Signup Timestamp | System | Trial expiry calculation | createdAt auto-generated |
| Referral Code (if any) | URL param | Partner commission tracking | Checked against ReferralPartner table |
Pre-Onboarding Customer State:
┌────────────────────────────────────────┐
│ Customer Record (at signup complete) │
├────────────────────────────────────────┤
│ User: │
│ id: "usr_abc123" │
│ email: "dr.smith@example.com" │
│ role: "CLIENT" │
│ createdAt: "2026-06-12T06:06:20Z" │
│ │
│ ClientProfile: │
│ id: "prf_def456" │
│ userId: "usr_abc123" │
│ businessName: "Dr. Smith Dental" │
│ plan: "STANDARD" │
│ status: "TRIAL" │
│ onboardingComplete: false │
│ trialEndsAt: "2026-06-19T06:06:20Z" │
│ directory URL: null (pending) │
│ utmSource: "google_ads" │
│ │
│ Subscription: │
│ provider: "razorpay" │
│ status: "trialing" │
│ trialEnd: "2026-06-19" │
└────────────────────────────────────────┘
Section 3: Customer Onboarding Flow (Step-by-Step)#
⚠️ CRITICAL PATH: This is the highest-friction, highest-dropoff phase. Every step is instrumented for analytics. Target: 80%+ completion rate from signup to first GBP post published.
Actor Legend: [C] = Customer action | [S] = System automation | [A] = Admin action
Onboarding Flow Overview#
SIGNUP ──► ONBOARDING FORM ──► PAYMENT ──► SUBDOMAIN ──► LANDING PAGE
│ │ │ │ │
│ ▼ ▼ ▼ ▼
│ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ │Business │ │Consent │ │AI Content│ │Deploy │
│ │Profile │ │& Terms │ │Generate │ │SSG + ISR │
│ │Capture │ │ │ │ │ │ │
│ └─────────┘ └──────────┘ └──────────┘ └──────────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌──────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│GBP │ │Social │ │Citation │ │NAP │ │First │
│OAuth │ │Connect │ │Submit x30│ │Verify │ │Posts │
│ │ │ │ │ │ │ │ │(Queue) │
└──────┘ └─────────┘ └──────────┘ └──────────┘ └──────────┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌──────────────────────────────────────────────────────────────────┐
│ WELCOME PACKAGE │
│ • Welcome Email + Dashboard Link │
│ • Welcome Report (PDF) │
│ • Onboarding Complete Notification (to Customer + Admin) │
└──────────────────────────────────────────────────────────────────┘
Step 1: Account Creation & Plan Selection#
| Attribute | Value |
|---|---|
| Actor | [C] |
| Frequency | One-time |
| Time Estimate | 2–3 minutes |
| System Component | /signup page → NextAuth.js Credentials → Prisma User + ClientProfile |
Customer Actions:
- Lands on
rankflow.aifrom marketing channel (with UTM params) - Clicks primary CTA: "Start Your 7-Day Free Trial"
- Views plan comparison table (Starter/Standard/Premium/Enterprise)
- Selects plan → plan features displayed in modal
- Enters email address, creates password, confirms password
- Enters practice/business name
- Clicks "Create Account"
System Actions:
- Validates email format + uniqueness
- Validates password strength (≥8 chars, 1 uppercase, 1 number)
- Creates
Userrecord withrole: CLIENT - Creates
ClientProfilewithstatus: TRIAL,plan: <selected>,onboardingComplete: false - Captures UTM parameters into
ClientProfile.utmSource,.utmMedium,.utmCampaign - Redirects to
/onboarding?step=1
Success Criteria:
UserandClientProfilerecords created in PostgreSQL- Customer redirected to onboarding wizard within 3 seconds
- No validation errors displayed
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Email already exists | Prisma unique constraint | Display: "This email is already registered. [Log in]" |
| Password too weak | Zod validation | Inline error: "Password must be at least 8 characters with 1 uppercase and 1 number" |
| DB write failure | Prisma error | Retry 3x with exponential backoff → alert admin via Slack/email |
| Payment provider error | Stripe/Razorpay API error | Display friendly error → offer "Continue without payment" fallback for trial |
Step 2: Business Profile Capture Form#
| Attribute | Value |
|---|---|
| Actor | [C] |
| Frequency | One-time |
| Time Estimate | 4–5 minutes |
| System Component | /onboarding wizard → tRPC practice.update → Prisma Location + Practice |
Form Fields & Validations:
| Field | Required | Validation | Used For |
|---|---|---|---|
| Business Name | ✅ | 3–100 chars | NAP data, directory URL slug, citations |
| Business Category | ✅ | Enum: DOCTOR/DENTIST/CLINIC/HOSPITAL/CA/LAWYER | Template selection, schema type, citation category |
| Primary Address | ✅ | 10–500 chars | NAP data, map embed, schema address |
| City | ✅ | Enum (Indian cities) | Local SEO targeting, citation city field |
| State | ✅ | Auto from city | Schema address |
| PIN Code | ✅ | 6-digit Indian PIN | Schema postal code |
| Primary Phone | ✅ | ^\+91[0-9]{10}$ |
NAP data, click-to-call, schema telephone |
| Secondary Phone | ❌ | Same format | Backup contact |
| Business Email | ✅ | Valid email | Schema email, contact form routing |
| Website (existing) | ❌ | URL format | Citation website field, backlink source |
| Business Hours | ✅ | JSON structure (day/open/close) | Schema openingHours, GBP hours sync |
| Services Offered | ✅ | Array of strings (min 1, max 10) | Directory profile services section, schema Service types |
| USPs / Specializations | ✅ | 50–500 chars | AI content generation context, directory profile about section |
| Doctor/Owner Name | ✅ | 2–100 chars | Directory profile hero, about section, schema |
| Years of Experience | ❌ | Integer 0–60 | Directory profile stats section, trust signal |
| Languages Spoken | ❌ | Array (English, Malayalam, Hindi, Tamil) | Vernacular content generation flag |
| Existing GBP URL | ❌ | URL format | GBP connection pre-check |
| Existing Social URLs | ❌ | Array of URLs | Social connection pre-check |
| Logo Upload | ❌ | Image file ≤2MB | Directory profile, schema image, social posts |
| Photos Upload | ❌ | Up to 5 images ≤2MB each | Directory profile gallery, GBP photos |
Form UX:
- Multi-step wizard (3 steps: Business Info → Location & Hours → Services & Media)
- Progress bar showing completion %
- Auto-save draft to
localStorage+ DB every 30 seconds - Field-level validation with inline error messages
- "Save & Continue Later" button (sends resume link via email)
Success Criteria:
- All required fields populated and validated
Locationrecord created withisPrimary: truePracticerecord updated withbusinessName,category,type- Directory URL slug auto-generated from business name (e.g., "dr-smith-dental" →
dr-smith-dental.rankflow.ai)
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Invalid phone format | Zod regex | Inline error: "Please enter a valid 10-digit Indian mobile number with +91" |
| Invalid PIN code | Zod regex | Inline error: "Please enter a valid 6-digit PIN code" |
| Image too large | Client-side + server-side | Error: "Image must be under 2MB. Please compress and retry." |
| Form abandonment | No activity >10 min | Auto-save draft → email: "Complete your setup" with deep link |
| DB update failure | Prisma error | Retry 3x → display: "Something went wrong. Your progress is saved. Please retry." |
Step 3: Consent & Terms Acceptance#
| Attribute | Value |
|---|---|
| Actor | [C] |
| Frequency | One-time |
| Time Estimate | 1 minute |
| System Component | /onboarding?step=consent → Checkbox components → Prisma ConsentLog |
Consent Items:
| Consent | Required | Legal Basis | Stored As |
|---|---|---|---|
| Terms of Service | ✅ | Contract | ConsentLog record with timestamp + IP |
| Privacy Policy | ✅ | DPDPA 2023 compliance | ConsentLog record with timestamp + IP |
| GBP Management Authorization | ✅ | Google OAuth scope consent | ConsentLog + Google OAuth audit trail |
| Data Processing for AI Content | ✅ | DPDPA 2023 — business data (not patient data) | ConsentLog record |
| Marketing Communications | ❌ | Consent | ConsentLog record; unchecked by default |
| Citation Network Participation | ✅ | Contract — explicit that citations are owned by RankFlow | ConsentLog record |
Customer Actions:
- Reads summary of Terms (linked to full
/termspage) - Reads summary of Privacy Policy (linked to full
/privacypage) - Checks required consent boxes
- Clicks "I Agree & Continue"
System Actions:
- Records each consent in
ConsentLogtable with:practiceId,consentType,ipAddress,userAgent,timestamp - Updates
ClientProfilestatus toONBOARDING_IN_PROGRESS - Proceeds to payment setup step
Success Criteria:
- All required consents recorded with timestamp and IP
- Customer proceeds to next step
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Customer declines consent | Checkbox unchecked | Block progression. Display: "You must accept the Terms of Service and Privacy Policy to continue." |
| Consent log write failure | Prisma error | Retry 3x → alert admin → allow manual consent recording |
Step 4: Payment Method Setup#
| Attribute | Value |
|---|---|
| Actor | [C] + [S] |
| Frequency | One-time (trial auth); recurring monthly thereafter |
| Time Estimate | 2–3 minutes |
| System Component | Stripe/Razorpay checkout → Webhook handler → Prisma Subscription |
Customer Actions:
- Enters card details or selects UPI (India-specific)
- Completes 3D Secure / OTP verification if required
- Sees confirmation: "Payment method added. You will not be charged during your 7-day trial."
System Actions:
- Tokenizes payment method via Stripe/Razorpay
- Creates subscription with
trial_end = now + 7 days - Stores
subscriptionId,customerId,paymentMethodIdinBillingtable - Sets up webhook listeners for
invoice.paid,invoice.payment_failed,customer.subscription.deleted - Sends confirmation email: "Your trial has started — no charge until [date]"
Success Criteria:
- Payment method tokenized and stored securely
- Subscription
status = trialingin payment provider - Webhook endpoints registered and responding 200 OK
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Card declined | Stripe/Razorpay error code | Display specific message: "Your card was declined. Please try a different payment method." |
| 3D Secure failure | OTP timeout | Allow 3 retry attempts → offer "Pay via UPI" alternative |
| UPI timeout | Razorpay timeout | Auto-retry once → fallback to card entry |
| Webhook delivery failure | Stripe/Razorpay retry log | System polls subscription status every 6 hours as backup |
| Duplicate subscription | Prisma unique constraint | Idempotency check → return existing subscription |
Step 5: Directory URL Assignment#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time |
| Time Estimate | 500ms |
| System Component | Slug generator → Prisma Practice.directory URL → Single Domain DNS (*.rankflow.ai) |
System Actions:
- Generates URL-safe slug from
businessName: "Dr. Smith Dental Clinic" →dr-smith-dental-clinic - Checks uniqueness against
Practice.directory URL(append-2,-3if collision) - Assigns directory URL:
dr-smith-dental-clinic.rankflow.ai - Updates
Practicerecord:directory URL,slug,domainStatus: ACTIVE - No DNS action needed — wildcard
*.rankflow.aiA-record handles all directory URLs
Success Criteria:
- Unique directory URL assigned and stored
- Directory URL immediately resolvable (single domain DNS)
- Customer can preview:
https://directory.com/clinics/[city]/[slug](shows placeholder until Step 7)
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Slug collision | Prisma unique constraint | Append incremental suffix:-2, -3, etc. |
| Invalid characters in name | Slug generator regex | Strip special chars, transliterate if needed |
| Single Domain DNS failure | DNS lookup failure | Alert admin immediately → manual DNS check |
Step 6: Directory Profile AI Content Generation#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time (onboarding); monthly refresh thereafter |
| Time Estimate | 45–60 seconds |
| System Component | Inngest onboarding-pipeline Step 2 → Multi-LLM Router → Prisma ProfileSection |
Generated Content Pieces:
| Content Piece | LLM Model | Prompt Context | Output |
|---|---|---|---|
| Hero section (H1, subtitle, CTA) | Claude Sonnet | Business name, category, city, USPs | Markdown HTML |
| About section (doctor bio) | Claude Sonnet | Doctor name, experience, specializations, languages | Markdown HTML |
| Services section (3–5 services) | Claude Haiku | Services list, category, city | Structured JSON |
| FAQ section (10+ Q&A pairs) | Claude Haiku | Common patient questions for specialty + city | Q&A pairs + FAQ schema JSON-LD |
| SEO articles (3–5 keyword-rich) | Claude Sonnet | Target keywords: "[service] in [city]", "best [specialty] [city]" | Markdown with HTML |
| Schema markup | Claude Sonnet | Full practice data | JSON-LD: LocalBusiness + Service + FAQ + Review |
| Meta title & description | Claude Haiku | Business name, city, category | String outputs |
System Actions:
- Inngest step
generate-profilecallsai.generate()withtask: "site_full" - LLM Router selects Claude Sonnet (high-quality) for primary content, Claude Haiku for bulk/FAQ
- All content stored in
ProfileSectiontable withsectionKey,content,sortOrder,isVisible: true - Schema JSON-LD stored in
Practice.schemaMarkup(JSON field) - Template selected based on
category:medical-modern(doctor),dental-clean(dentist),clinic-premium(clinic)
Success Criteria:
- 8+ profile sections generated and stored in DB
- All content passes medical compliance filter (no drug claims, no guaranteed cure language)
- Schema markup valid JSON-LD
- Content generation cost logged for margin tracking
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| LLM timeout (>30s) | Router timeout | Retry with GPT-4 fallback → if still failing, queue for manual content creation |
| Low-quality/generic output | Content quality heuristic (length, keyword density) | Regenerate with stricter prompt → flag for admin review |
| Medical compliance violation | Keyword filter ("guaranteed cure", "100% success", drug names) | Reject content → regenerate with compliance prompt → alert admin if 3x failure |
| DB write failure | Prisma error | Retry 3x → queue to dead letter → alert admin |
Step 7: Directory Profile Deployment#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time (onboarding); per content update thereafter |
| Time Estimate | 60–90 seconds |
| System Component | Inngest onboarding-pipeline Step 3 → Next.js ISR + ISR → Cloudflare CDN |
System Actions:
- Inngest step
publish-profiletriggers static page generation - Next.js
generateStaticParamspre-renders/site/[practiceSlug]route - SchemaInjector component server-renders JSON-LD into HTML
<head> - Page deployed to Dokploy/AWS EC2 (or Vercel in initial phase)
- Cloudflare CDN caches the page globally
Practice.sitePublishedset totruePractice.domainStatusset toACTIVE
Success Criteria:
- Directory profile live at
https://directory.com/clinics/[city]/[slug] - Page returns HTTP 200,
< 2.5sLCP - Schema markup present in HTML source (validated)
- Meta tags correct (title, description, OG tags, canonical)
- Mobile-responsive rendering confirmed
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Build failure | Next.js build error | Retry once → alert admin → manual build trigger |
| Schema invalid JSON | JSON.parse error | Fallback to minimal LocalBusiness schema → flag for fix |
| CDN cache miss | Response time >5s | Purge Cloudflare cache → rewarm |
| Custom domain DNS not ready | domainStatus != ACTIVE |
Deploy to directory URL only → queue directory profile URL for later |
Step 8: GBP OAuth Connection Request Email#
| Attribute | Value |
|---|---|
| Actor | [S] → [C] |
| Frequency | One-time |
| Time Estimate | Email sent in 2 sec; customer action variable |
| System Component | Inngest onboarding-pipeline Step 4 → Resend API → Customer inbox |
System Actions:
- Inngest step
notify-gbp-authgenerates Google OAuth URL:- Scope:
business.manage,userinfo.email,userinfo.profile - State param: Base64-encoded
{practiceId} - Callback:
/api/webhooks/google/oauth-callback
- Scope:
- Sends email via Resend (
emailSendBullMQ queue):- Subject: "Connect Your Google Business Profile — RankFlow AI"
- Content: Step-by-step visual guide (screenshots of every click), OAuth link button, "Need help? Book a 5-min support call" link
- From:
onboarding@rankflow.ai
Customer Action:
- Receives email (typically within 2 minutes of completing Step 4)
- Opens email, clicks "Connect Google Business Profile" button
- Lands on Google OAuth consent screen
Success Criteria:
- Email delivered (Resend webhook confirms
deliveredstatus) - Customer clicks OAuth link within 48 hours (target: 70% click-through)
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Email bounced | Resend webhook bounced |
Alert admin → attempt alternate email if provided → SMS fallback if phone available |
| Email not opened | No opened event in 24h |
Automated reminder email #1 at 24h, #2 at 48h, #3 at 72h |
| Customer doesn't click | No OAuth callback in 7 days | Admin alert → manual outreach call scheduled → offer screen-share assistance |
| OAuth link expired | Google token expiry | Regenerate fresh OAuth URL in reminder email |
Step 9: GBP OAuth Flow & Token Storage#
| Attribute | Value |
|---|---|
| Actor | [C] → [S] |
| Frequency | One-time |
| Time Estimate | 2–3 minutes (customer); 3 sec (system) |
| System Component | Google OAuth 2.0 →/api/webhooks/google/oauth-callback → Prisma GbpAccount |
Customer Actions:
- Clicks OAuth link from email
- Signs in to Google account (if not already signed in)
- Reviews permission screen: "RankFlow AI wants to manage your Google Business Profile"
- Clicks "Allow"
- Redirected back to
/dashboard/gbp?connected=true
System Actions:
- Callback handler receives
code+state(containspracticeId) - Exchanges
codeforaccess_token+refresh_tokenvia Google OAuth2 API - Fetches user info (email, name) via Google People API
- Encrypts tokens using AES-256-GCM
- Creates
GbpAccountrecord:practiceId, accountEmail, accessToken(encrypted), refreshToken(encrypted), tokenExpiresAt, scope: ["business.manage"], isActive: true - Triggers Inngest event:
gbp/sync-locations - Redirects customer to dashboard with success toast
Success Criteria:
- Valid
access_token+refresh_tokenobtained and encrypted GbpAccountrecord created withisActive: true- Customer redirected to
/dashboard/gbp?connected=true - Token expiry set correctly (typically 1 hour for access, indefinite for refresh)
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Customer clicks "Deny" | OAuth callback with error=access_denied |
Email: "You declined access. Here's why we need it..." → fresh OAuth link |
| Customer has no GBP | Google API returns no business accounts | Email: "You don't have a Google Business Profile yet. Here's how to create one in 5 minutes." → link to GBP creation guide |
| Multiple GBP accounts | API returns multiple accounts | Dashboard prompt: "Select which business to connect" → store selected account |
| Token exchange failure | Google API error | Retry 3x → alert admin → manual token generation support |
| Encryption failure | Crypto module error | Alert admin immediately → do not store unencrypted tokens |
Step 10: GBP Location Sync#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time (onboarding); weekly sync thereafter |
| Time Estimate | 10–15 seconds |
| System Component | Inngest gbp/sync-locations → Google Business Profile API → Prisma GbpLocation |
System Actions:
- Inngest workflow triggered by OAuth callback event
- Calls
mybusinessbusinessinformation.v1API:accounts.locations.list - For each location found:
- Creates/updates
GbpLocationrecord with:gbpLocationId,name,address,phone,hours,category - Maps to
Locationrecord viapracticeId
- Creates/updates
- Syncs business info from RankFlow DB to GBP:
- Description (AI-generated)
- Business hours (from onboarding form)
- Primary category (from
categoryfield) - Phone number
- Webprofile URL (directory profile directory URL)
- Uploads logo and photos if provided during onboarding
Success Criteria:
- All GBP locations synced to local DB
- Business info updated on GBP API
GbpLocationrecords linked toLocationrecords- Customer sees GBP status as "Connected — X locations" in dashboard
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| GBP API rate limit | HTTP 429 | Queue retry with exponential backoff (5min, 15min, 1h) |
| Location data mismatch | Address/phone differs from onboarding form | Flag for admin review → email customer: "Please verify your business details" |
| Photo upload failure | API error or size limit | Skip photos → queue for manual upload → notify customer |
| Category not supported | GBP rejects category mapping | Fallback to closest supported category → flag for manual correction |
Step 11: Social Media Connection Prompts#
| Attribute | Value |
|---|---|
| Actor | [S] → [C] |
| Frequency | One-time per platform |
| Time Estimate | Email sent in 2 sec; customer action 3–5 min per platform |
| System Component | Inngest step → Resend email → Composio OAuth → Prisma SocialAccount |
System Actions:
- After GBP sync completes, Inngest sends social connection prompt email
- Email contains platform-specific connection buttons:
- "Connect Instagram" → Composio OAuth for Instagram Graph API
- "Connect Facebook" → Composio OAuth for Facebook Graph API
- "Connect LinkedIn" → Composio OAuth (optional)
- "Connect Twitter/X" → Composio OAuth (optional)
- Each link includes
practiceIdin state param
Customer Actions:
- Receives email: "Connect Your Social Media Accounts"
- Clicks platform button(s) one by one
- Authorizes RankFlow AI via Composio OAuth flow
- Redirected back to
/dashboard/social?connected=[platform]
Success Criteria:
- At least 1 social platform connected (Instagram or Facebook preferred for medical vertical)
SocialAccountrecord created with:platform,accountName,composioConnectionId,isActive: true- Customer sees connected accounts in
/dashboard/social
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Customer doesn't connect | No OAuth callback in 48h | Reminder email at 48h, 96h → onboarding can proceed without social |
| Composio OAuth failure | Callback with error | Display specific error: "Please ensure you are an admin of your Facebook Business Page" |
| Meta Business Account missing | Composio returns business_account_required |
Email guide: "How to create a Meta Business Account in 3 minutes" |
| Platform not available in India | Composio unsupported app | Hide platform from prompt → notify customer when available |
| Token storage failure | Prisma error | Retry 3x → alert admin → do not lose connection_id |
Step 12: Citation Directory Description Generation (30 Unique)#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time (onboarding); monthly refresh thereafter |
| Time Estimate | 30–45 seconds |
| System Component | Inngest citation-builder Step 3 → Multi-LLM Router (Llama 3 70B) → JSON output |
System Actions:
- Inngest
citation-builderworkflow triggered after directory profile deploy - Fetches all 30 active
CitationDirectoryrecords:- 10 India-specific (Justdial, Practo, Sulekha, Lybrate, 1mg, IndiaMART, etc.)
- 10 General directories (Yelp, Foursquare, Hotfrog, Brownbook, Cylex, etc.)
- 5 Owned blog sites (kerala-health.rankflow.in, medical-guide.rankflow.in, etc.)
- 5 Global maps (Bing Places, Apple Maps, TomTom, HERE — Phase 2)
- For each directory, calls LLM Router with
task: "citation_description":- Model: Llama 3 70B (cost-optimized for bulk)
- Context:
practice,location,directory(tone varies per directory type) - Output:
{ directoryId, title, description, keywords }
- Stores all 30 descriptions in memory for submission step
Success Criteria:
- 30 unique descriptions generated (no duplicates, >80% uniqueness score)
- Each description 100–500 chars (directory-specific length)
- Keywords naturally included (no keyword stuffing)
- Medical compliance verified (no prohibited claims)
- Generation cost < Rs 5 total (Llama 3 bulk pricing)
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| LLM timeout | >15s per description | Retry with Claude Haiku fallback → if still failing, use template-based generation |
| Duplicate descriptions | Similarity check >70% | Regenerate offending descriptions with stricter uniqueness prompt |
| Description too long/short | Length validation | Truncate or expand via secondary LLM call |
| Medical compliance violation | Filter check | Reject → regenerate with stricter system prompt |
Step 13: Citation Submission to 30 Directories#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time (onboarding); monthly resubmission for failed ones |
| Time Estimate | 10–15 minutes total (parallel with concurrency limit) |
| System Component | Inngest citation-builder Step 4 → Submission Engine → Prisma Citation |
Submission Methods by Directory Type:
| Directory Type | Submission Method | Concurrency | Avg Time per Directory |
|---|---|---|---|
| API-based (Practo, IndiaMART) | REST API call | 3 parallel | 2–5 seconds |
| Form-based (Justdial, Sulekha, Yelp) | Hyperbrowser/Puppeteer automation | 3 parallel | 3–5 minutes |
| Owned blog sites | Direct DB insert + SSG re-render | 5 parallel | 1–2 seconds |
| Global maps (Phase 2) | API or form | 2 parallel | 2–3 minutes |
System Actions:
- For each directory, creates appropriate submitter instance:
ApiSubmitterfor API-based directoriesFormSubmitter(Hyperbrowser) for form-based directoriesOwnedBlogSubmitterfor owned sites (direct DB write)
- Submits NAP data + unique description to each directory
- Captures screenshot of confirmation page (stored in S3)
- Extracts listing URL if available
- Creates
Citationrecord per directory:practiceId, locationId, directoryName, status: SUBMITTED/FAILED, directoryUrl, screenshotUrl, submittedAt, napSnapshot, errorMessage
Success Criteria:
- ≥80% of 30 directories successfully submitted (24+ live citations)
- All submitted citations have
directoryUrlorscreenshotUrlas proof - NAP data consistent across all submissions
- No duplicate submissions (idempotency check)
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| CAPTCHA blocking submission | Hyperbrowser timeout on form | Solve via 2captcha service → retry once → flag for manual submission |
| Phone verification required | Form submission returns "verify phone" | Use virtual number service → if unavailable, flag for manual |
| Directory API down | HTTP 5xx | Retry 3x with 5min backoff → queue for next monthly refresh |
| Form structure changed | Selector not found | Alert admin → update submission schema → retry |
| Duplicate listing exists | "Business already listed" message | Update existing listing instead → store URL |
| Owned blog SSG failure | Next.js build error | Retry build → if failing, static HTML fallback |
Step 14: NAP Verification Scheduling#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time scheduling; actual verification runs 7 days later |
| Time Estimate | 2 seconds (scheduling) |
| System Component | Inngest citation-builder Step 6 → step.sleep("7d") → skill/14-citation-verify-nap event |
System Actions:
- After all submissions complete, Inngest workflow sleeps for 7 days
- Then sends event:
skill/14-citation-verify-napwithpractice_id,location_id - This triggers the
NapCheckProcessorBullMQ job - Job scheduled:
0 2 1 * *(1st of month at 2 AM) as recurring backup
Success Criteria:
- Verification event scheduled successfully
Citationrecords havestatus: SUBMITTEDandsubmittedAtpopulated
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Inngest sleep failure | Workflow error | Fallback to BullMQ delayed job (7-day delay) |
| Event not sent after sleep | Inngest monitoring | Alert admin → manual trigger of verification |
Step 15: First GBP Post Generation & Approval Queue#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time; then 2–3x per week recurring |
| Time Estimate | 15–20 seconds |
| System Component | Inngest onboarding-pipeline Step 6 → AI Router → Prisma ScheduledPost + ContentPiece |
System Actions:
- After GBP OAuth callback received, Inngest step
create-first-post:- Calls AI Router with
task: "gbp_post" - Context: practice name, category, city, services, recent news/seasonal angle
- Model: Claude Haiku (fast, cost-effective)
- Calls AI Router with
- Generated post content: 150–300 words, CTA included ("Book appointment", "Call now")
- Post stored as
ContentPiecewithstatus: PENDING_REVIEW - For medical clients: auto-queued in approval dashboard with 24-hour auto-publish timer
- Customer notified via email: "Your first GBP post is ready for review"
Success Criteria:
- First GBP post generated within 30 seconds of OAuth completion
- Content passes medical compliance filter
- Post queued in
/dashboard/contentwith 24h countdown - Customer can approve, reject, or edit before auto-publish
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| AI generates non-compliant content | Filter check | Reject → regenerate with stricter prompt → alert admin if 2x failure |
| Post too long for GBP | >1500 chars | Truncate to 1500 chars → flag for review |
| Customer rejects post | Dashboard action | Archive content → regenerate with different angle → re-queue |
| Customer doesn't review in 24h | Timer expiry | Auto-publish (for medical: only if compliance score >90%) |
Step 16: First Social Posts Generation & Approval Queue#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time; then 2–4x per week recurring |
| Time Estimate | 20–30 seconds |
| System Component | AI Router → Prisma SocialPost + ContentPiece |
System Actions:
- For each connected social platform:
- Instagram: AI generates caption (100–150 words) + hashtag set (10–15 tags)
- Facebook: Longer post (150–200 words) + link to directory profile
- LinkedIn/Twitter: Professional tone variant
- Model: Llama 3 8B for captions (bulk, low-cost)
- Posts stored as
ContentPiecewithstatus: PENDING_REVIEW - 24-hour approval timer activated
- Customer notified: "Your first social posts are ready for review"
Success Criteria:
- 1 post per connected platform generated
- Content platform-appropriate (hashtags for IG, links for FB, professional for LI)
- All posts in approval queue at
/dashboard/content - Image prompt generated (optional DALL-E/stable diffusion for hero image)
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| No social accounts connected | SocialAccount count = 0 |
Skip this step → onboarding proceeds → social prompts sent again at 48h |
| Platform-specific content violation | Length/format check | Regenerate per platform constraints |
| Image generation failure | DALL-E API error | Post text-only → queue image for manual creation |
Step 17: Welcome Email with Dashboard Link#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time |
| Time Estimate | 5 seconds |
| System Component | Inngest onboarding-pipeline final step → Resend API → emailSend BullMQ queue |
Email Content:
- Subject: "🎉 Your RankFlow AI Dashboard is Ready — Here's Everything That's Live"
- Sections:
- "Your directory profile is live" → link to
https://directory.com/clinics/[city]/[slug] - "Your citations are being built" → link to
/dashboard/citations - "Connect your Google Business Profile" → link to
/dashboard/gbp(if not yet connected) - "Review your first posts" → link to
/dashboard/content - "Access your dashboard" → CTA button:
https://rankflow.ai/dashboard - "Need help?" → Calendly support call link + WhatsApp support number
- "Your directory profile is live" → link to
Success Criteria:
- Email delivered within 5 minutes of onboarding completion
- All deep links functional and UTM-tagged
- Email opens tracked via Resend webhook
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Email bounce | Resend webhook | Alert admin → retry with alternate email → SMS fallback |
| Dashboard link broken | URL validation | Pre-validate all URLs before sending |
Step 18: Welcome Report Generation#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time |
| Time Estimate | 30–45 seconds |
| System Component | Inngest send-welcome-report → Report data gatherer → Playwright PDF → S3 → Resend |
Report Contents:
| Section | Data Source |
|---|---|
| Executive Summary | Practice name, onboarding date, plan, directory profile URL |
| Citation Status | List of all 30 directories with SUBMITTED/PENDING/FAILED status |
| Directory Profile Preview | Screenshot of live directory profile |
| GBP Connection Status | Connected / Pending with next steps |
| Social Connection Status | Connected platforms + pending platforms |
| What's Happening Next | Timeline: "NAP verification in 7 days", "First report in 30 days", "Weekly posts begin Monday" |
| Quick Links | Dashboard, directory profile, support, billing |
System Actions:
- Gathers all onboarding data from DB
- Generates HTML report template (React component)
- Playwright renders HTML to PDF (A4, branded)
- Uploads PDF to S3:
reports/welcome-{practiceId}-{date}.pdf - Attaches PDF to welcome email
Success Criteria:
- PDF generated and uploaded to S3
- PDF attached to welcome email
- Report contains accurate, up-to-date onboarding status
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| PDF generation timeout | Playwright >30s | Retry once → if failing, send HTML email instead |
| S3 upload failure | AWS SDK error | Retry 3x → queue for later delivery |
| Report data incomplete | Null values in DB | Display "Pending" for incomplete sections → do not crash |
Step 19: Onboarding Completion Notification#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time |
| Time Estimate | 2 seconds |
| System Component | Inngest workflow return → Prisma ClientProfile update → Resend email |
System Actions:
- Inngest
onboarding-pipelinereturns{ practice_id, status: "onboarded" } - Updates
ClientProfile:onboardingComplete: truestatus: ACTIVE(if trial) orACTIVE(if paid)onboardedAt: new Date()
- Triggers recurring job scheduling:
- GBP posts:
0 9 * * 1,3,5(Mon/Wed/Fri 9 AM IST) - Social posts:
0 10 * * 2,4(Tue/Thu 10 AM IST) - Review monitor:
0 8 * * *(Daily 8 AM) - NAP check:
0 2 1 * *(1st of month 2 AM) - Monthly report:
0 4 1 * *(1st of month 4 AM) - Site evolution:
0 2 * * 1(Weekly Mon 2 AM)
- GBP posts:
- Sends onboarding completion email to customer:
- "You're all set! Here's what happens next..."
- Timeline of automated activities
- Link to
/dashboard
Success Criteria:
ClientProfile.onboardingComplete = true- All recurring jobs scheduled in BullMQ
- Customer receives completion email
- Customer can log in to fully functional dashboard
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Job scheduling failure | BullMQ error | Retry 3x → alert admin → manual scheduling via admin dashboard |
| DB update failure | Prisma error | Retry 3x → critical alert → manual fix required |
| Recurring job duplicate | Job ID collision | Idempotency check prevents duplicates |
Step 20: Admin Notification of New Client#
| Attribute | Value |
|---|---|
| Actor | [S] |
| Frequency | One-time per new client |
| Time Estimate | 2 seconds |
| System Component | Inngest final step → Resend API → Admin inbox |
Admin Email Content:
- Subject: "New Client Onboarded: {BusinessName} ({Plan})"
- To:
admin@rankflow.ai,founder@rankflow.ai - Sections:
- Client summary: Name, city, category, plan, trial end date
- Onboarding status: Steps completed, any failures
- GBP connection: Connected / Pending (with OAuth link for support)
- Social connections: Platforms connected
- Citation success rate: X/30 submitted
- Directory profile: Live URL + directory profile URL status
- Action items (if any): "GBP OAuth pending — call client?", "2 citations failed — manual submission needed"
- Deep link to
/admin/clients/{id}for full detail
Success Criteria:
- Admin email delivered within 2 minutes of onboarding completion
- All actionable items clearly flagged
- Deep link to client detail page functional
Failure Handling:
| Failure | Detection | Handling |
|---|---|---|
| Admin email bounce | Resend webhook | Alert via Slack webhook as backup |
| Missing action items | Logic error | Include full client data dump for manual review |
Onboarding Summary Table#
| Step | Actor | Frequency | Time | Success Criteria | Failure Handling |
|---|---|---|---|---|---|
| 1. Account & Plan | [C] | One-time | 2–3 min | User + ClientProfile created | Validation errors inline |
| 2. Business Profile | [C] | One-time | 4–5 min | Location record with full NAP | Auto-save draft, email resume |
| 3. Consent & Terms | [C] | One-time | 1 min | All consents logged with IP | Block progression |
| 4. Payment Setup | [C]+[S] | One-time | 2–3 min | Subscription trialing | Fallback to no-payment trial |
| 5. Directory URL | [S] | One-time | 500ms | Unique directory URL assigned | Append suffix on collision |
| 6. LP Content Gen | [S] | One-time | 45–60s | 8+ sections + schema stored | LLM fallback, admin alert |
| 7. LP Deploy | [S] | One-time | 60–90s | Page live, <2.5s LCP | Retry build, static fallback |
| 8. GBP OAuth Email | [S]→[C] | One-time | 2 sec + variable | Email delivered, link clicked | 3x reminder emails |
| 9. GBP OAuth Flow | [C]→[S] | One-time | 2–3 min | Tokens encrypted, GbpAccount created | Fresh OAuth link, support call |
| 10. GBP Location Sync | [S] | One-time | 10–15s | Locations synced, info updated | Rate limit retry, admin flag |
| 11. Social Connect | [S]→[C] | One-time | 2 sec + 3–5 min/platform | SocialAccount created | Reminder emails, skip if none |
| 12. Citation Descriptions | [S] | One-time | 30–45s | 30 unique descriptions | Regenerate with fallback |
| 13. Citation Submit | [S] | One-time | 10–15 min | ≥80% success rate (24+/30) | CAPTCHA solve, manual fallback |
| 14. NAP Verify Schedule | [S] | One-time | 2 sec | Event scheduled for +7d | BullMQ delayed job fallback |
| 15. First GBP Post | [S] | One-time | 15–20s | Content in approval queue | Regenerate, compliance check |
| 16. First Social Posts | [S] | One-time | 20–30s | Content in approval queue | Skip if no social accounts |
| 17. Welcome Email | [S] | One-time | 5 sec | Delivered with all links | Retry, SMS fallback |
| 18. Welcome Report | [S] | One-time | 30–45s | PDF generated + attached | HTML fallback |
| 19. Onboarding Complete | [S] | One-time | 2 sec | Profile updated, jobs scheduled | Admin alert, manual fix |
| 20. Admin Notification | [S] | One-time | 2 sec | Admin email with action items | Slack webhook backup |
Total Onboarding Time: 15–25 minutes (system automation) + variable customer action time (GBP OAuth, social connect)
Section 4: Active Customer Journey (Daily/Weekly/Monthly)#
After onboarding completes, the customer enters the Active Customer Journey. The majority of touchpoints are fully automated. The customer's primary interaction is via the dashboard and email reports.
4.1 Daily Automation Touchpoints#
| Touchpoint | Actor | Trigger | Time | System Component | Success Criteria | Failure Handling |
|---|---|---|---|---|---|---|
| Review Monitoring | [S] | Cron:0 8 * * * (daily 8 AM IST) |
1–2 min per client | reviewMonitor BullMQ processor → GBP API → Prisma Review |
All new reviews fetched, stored, replied to or queued | Retry 3x → alert admin if GBP API down |
| Token Health Checks | [S] | Cron:0 3 * * * (daily 3 AM IST) |
1–2 min (batch all tokens) | tokenRefresh BullMQ processor → Google OAuth refresh |
All expiring tokens refreshed within 24h window | Alert admin per failed account → email customer to reconnect |
| Alert Processing | [S] | Event-driven (real-time) | 5–10 sec | Alert rules engine → Resend API | Alert email sent within 60 seconds of trigger | Queue retry → SMS fallback for high-priority alerts |
Review Monitoring Detail:
┌────────────────────────────────────────┐
│ Daily Review Monitor (8 AM IST) │
├────────────────────────────────────────┤
│ 1. Poll GBP API for new reviews │
│ (since last check timestamp) │
│ │
│ 2. For each new review: │
│ ├─ Store in Review table │
│ ├─ Generate AI reply (Claude Haiku)│
│ ├─ Sentiment analysis │
│ │ ├─ 4-5 stars → AUTO-REPLY │
│ │ └─ 1-3 stars → QUEUE FOR │
│ │ APPROVAL (24h timer) │
│ └─ Update dashboard review inbox │
│ │
│ 3. Send alert emails: │
│ ├─ Negative review → Customer │
│ └─ Unreplied >24h → Admin │
└────────────────────────────────────────┘
Alert Types & Routing:
| Alert | Trigger | Recipient | Priority | Auto-Action |
|---|---|---|---|---|
| New negative review (1–2 stars) | Review monitor | Customer + Admin | High | Queue AI reply for approval |
| New neutral review (3 stars) | Review monitor | Customer | Medium | Queue AI reply (24h auto-approve) |
| GBP position drop (>5 positions) | Rank tracker | Customer + Admin | High | Include in weekly digest |
| Citation removed (NOT_FOUND) | NAP monitor | Customer + Admin | High | Queue resubmission |
| Token expires in <7 days | Token health check | Admin | Medium | Proactive refresh attempt |
| Job failure (after max retries) | Dead letter queue | Admin | Medium | Manual retry capability |
| Subscription past due | Stripe/Razorpay webhook | Customer | High | Payment retry ×3 |
4.2 Weekly Automation Touchpoints#
| Touchpoint | Actor | Trigger | Time | System Component | Success Criteria | Failure Handling |
|---|---|---|---|---|---|---|
| GBP Post Generation & Scheduling | [S] | Cron:0 9 * * 1,3,5 (Mon/Wed/Fri 9 AM) |
30 sec per post | AI Router →gbpPostPublish BullMQ queue → GBP API |
Post generated, queued, published or in approval | Rate limit retry → emergency stop if suspension risk |
| Social Post Generation & Scheduling | [S] | Cron:0 10 * * 2,4 (Tue/Thu 10 AM) |
30 sec per post | AI Router →socialPostPublish BullMQ queue → Composio API |
Post generated, queued, published or in approval | Platform failure → email customer with copy-paste content |
| Profile Refresh / Content Updates | [S] | Cron:0 2 * * 1 (Mon 2 AM) |
5–10 min | Inngest profile-refresh → AI Router → DB → ISR revalidation |
Content updated, site re-rendered | Retry once → manual content update if failing |
| Weekly Digest Email | [S] | Cron:0 9 * * 1 (Mon 9 AM) |
5–10 sec | Report data gatherer → Resend API | Email delivered with top 3 stats | Retry → skip if data incomplete |
Weekly Digest Content:
┌────────────────────────────────────────┐
│ RankFlow Weekly Digest │
│ Dr. Smith Dental Clinic │
│ Week of June 8–14, 2026 │
│ │
│ 📍 Maps Position: #3 (+1 from last wk)│
│ ⭐ New Reviews: 4 (avg 4.8★) │
│ 📝 Posts Published: 2 (GBP + Social) │
│ │
│ [View Full Dashboard] │
│ [Review Pending Content] │
└────────────────────────────────────────┘
GBP Post Scheduling Rules:
- Max 3 posts per week per location (suspension prevention)
- Content varies per client (no template duplication)
- Post types rotate: Update, Offer, Event, Product
- All medical client posts require 24h approval gate
- Emergency stop available if Google suspension warning detected
Social Post Scheduling Rules:
- Instagram: 2x/week (Tue/Thu), image + caption + hashtags
- Facebook: 2x/week (Tue/Thu), longer text + directory profile link
- LinkedIn/Twitter: 1x/week (optional, professional tone)
- All posts queued in
/dashboard/contentwith 24h timer - If Composio fails: email customer with copy-paste content for manual posting
4.3 Monthly Automation Touchpoints#
| Touchpoint | Actor | Trigger | Time | System Component | Success Criteria | Failure Handling |
|---|---|---|---|---|---|---|
| Citation NAP Consistency Check | [S] | Cron:0 2 1 * * (1st, 2 AM) |
5–10 min per client | napCheck BullMQ processor → Firecrawl scrape → fuzzy match |
All 30 citations checked, mismatches flagged | Retry failed scrapes → alert admin for manual verification |
| Content Refresh / Rewrite | [S] | Cron:0 3 1 * * (1st, 3 AM) |
10–15 min per client | Inngest content-refresh → AI Router → DB → ISR |
Directory profile content updated, citations refreshed | Fallback to partial refresh → admin review for major changes |
| Monthly Report Generation | [S] | Cron:0 4 1 * * (1st, 4 AM) |
2–3 min per client | Inngest monthly-report → data gatherer → Playwright PDF → S3 |
PDF generated, report record created | Retry once → HTML-only report if PDF fails |
| Monthly Report Email Delivery | [S] | After report generation | 5–10 sec | Resend API with PDF attachment | Email delivered, opened tracked | Retry → alert admin if bounced |
| Invoice Generation | [S] | Stripe/Razorpay webhook + cron | 5–10 sec | Payment provider → Prisma Invoice → Resend |
Invoice created, emailed, PDF attached | Manual reconciliation if webhook missed |
Monthly Report Sections:
| Section | Weight | Metrics | Source |
|---|---|---|---|
| Executive Summary | — | Overall score (0–100), period | Calculated |
| GBP Performance | 25% | Views, clicks, calls, directions, posts | GBP API |
| Citation Health | 25% | Live count, NAP consistency % | Citation DB + Firecrawl |
| Review Summary | 20% | New reviews, avg rating, reply rate | Review DB |
| Rank Tracking | 20% | Keyword positions, top 10 count | DataForSEO / SerpAPI |
| SEO Score | 10% | Site health, schema validity, speed | Lighthouse + internal |
| Action Items | — | 3 AI-generated recommendations | AI Router |
Score Calculation:
- GBP:
(views + clicks + calls + directions) / baseline × 25 - Citations:
(live count / 30 × 100) × (NAP consistency %) × 0.25 - Reviews:
(avg rating / 5 × 50) + (reply rate × 50) × 0.20 - Rankings:
(keywords in top 10 / total keywords × 100) × 0.20 - SEO:
(site health + schema valid + speed score) / 3 × 0.10
4.4 Customer Actions in Dashboard#
What the Customer CAN Do#
| Feature | Page | Action | Role Required |
|---|---|---|---|
| View Performance Overview | /dashboard |
See KPI cards: Maps position, citation count, review score, social activity, site traffic, SEO score | CLIENT, EDITOR, VIEWER |
| View GBP Status | /dashboard/gbp |
See connected account, locations, sync status, recent posts, review count | CLIENT, EDITOR, VIEWER |
| View GBP Posts | /dashboard/gbp/posts |
See post calendar, list view, create post, edit scheduled post, delete post | CLIENT, EDITOR |
| Reply to Reviews | /dashboard/gbp/reviews |
See review list, filter (all/unreplied/negative/positive), reply inline with AI assist, bulk reply | CLIENT, EDITOR |
| View GBP Insights | /dashboard/gbp/insights |
See views over time, actions breakdown, search queries, photo views, post engagement charts | CLIENT, EDITOR, VIEWER |
| Manage Social Accounts | /dashboard/social |
See connected accounts, follower counts, disconnect accounts, connect new accounts | CLIENT |
| Schedule Social Posts | /dashboard/social |
Compose post, upload media, select platforms, schedule date/time, preview, view queue/history | CLIENT, EDITOR |
| View Citations | /dashboard/citations |
See all 30 citation URLs, status (live/pending/failed), NAP match indicator, last checked date, screenshot | CLIENT, EDITOR, VIEWER |
| Request Citation Re-verify | /dashboard/citations |
Click "Re-verify NAP" on any citation | CLIENT, EDITOR |
| Preview Directory Profile | /dashboard/site |
See live iframe preview, device toggle (desktop/tablet/mobile), URL display | CLIENT, EDITOR, VIEWER |
| Edit Directory Profile | /dashboard/site |
Edit hero, about, services, testimonials, FAQ, contact, CTA sections | CLIENT |
| Change Template | /dashboard/site |
Select from 5 templates: medical-modern, dental-clean, clinic-premium, ca-professional, lawyer-authority | CLIENT |
| Set Directory Profile URL | /dashboard/site |
Enter directory profile URL, see DNS instructions, verify status | CLIENT |
| View Reports | /dashboard/reports |
See monthly report cards, view PDF, download, email report | CLIENT, EDITOR, VIEWER |
| View Leads | /dashboard/leads |
See lead inbox, contact details, source, UTM params, update status (new/contacted/converted/lost) | CLIENT, EDITOR |
| Approve/Reject Content | /dashboard/content |
See approval queue, approve/reject/edit AI-generated content, see auto-publish countdown | CLIENT, EDITOR |
| Edit Business Info | /dashboard/settings |
Update name, logo, colors, locations, team members, notification preferences | CLIENT |
| Manage Team | /dashboard/settings |
Invite members, set roles (EDITOR/VIEWER), remove members | CLIENT |
| View Billing | /dashboard/billing |
See current plan, next billing date, included features, upgrade/downgrade, cancel subscription | CLIENT |
| View Invoices | /dashboard/billing |
See invoice history, download PDF invoices | CLIENT |
What the Customer DOES Do (Typical Usage Patterns)#
| Activity | Frequency | % of Active Customers | Time Spent |
|---|---|---|---|
| Log in to check dashboard | Weekly | 85% | 2–3 min |
| Approve/reject AI content | Weekly | 60% | 5–10 min |
| Reply to reviews | Weekly | 40% | 5–10 min |
| View monthly report | Monthly | 90% | 5–10 min |
| Download/share report PDF | Monthly | 30% | 2 min |
| Edit business info | Quarterly | 20% | 10–15 min |
| Check citation status | Monthly | 25% | 3–5 min |
| View directory profile | Once (onboarding) | 70% | 2 min |
| Connect/disconnect social | Rarely | 10% | 5 min |
| Upgrade/downgrade plan | Rarely | 5% | 3 min |
| Invite team member | Rarely | 8% | 3 min |
Key Insight: The ideal customer journey is low-touch — the platform is designed to be "set and forget." High dashboard engagement is not the goal. The goal is:
- Customer sees weekly digest email → feels informed
- Customer approves content once per week → feels in control
- Customer views monthly report → sees value
- Customer receives new patient leads → sees ROI
4.5 RankFlow Actions Behind the Scenes#
All automated jobs that run without any customer interaction:
| Job | Frequency | Queue | Duration | Description |
|---|---|---|---|---|
| Onboarding Pipeline | Event-driven | Inngest | 5–10 min | Full new client onboarding workflow |
| Citation Builder | Onboarding + Monthly refresh | Inngest | 10–15 min | Generate + submit to 30 directories |
| Citation Verify NAP | 7 days after submit + Monthly | Inngest | 2–3 min | Scrape citations, verify NAP consistency |
| Directory Profile Deploy | Onboarding + Content update | Inngest | 1–2 min | SSG render + ISR + CDN cache |
| GBP Post Publish | 2–3x/week per client | BullMQ | 30 sec/post | Generate content, queue for approval, publish |
| Social Post Publish | 2–4x/week per client | BullMQ | 30 sec/post | Generate content, queue for approval, publish via Composio |
| Review Monitor | Daily per client | BullMQ | 1–2 min | Poll GBP API, store reviews, generate replies, route by sentiment |
| NAP Consistency Check | Monthly per client | BullMQ | 5–10 min | Crawl all citations, extract NAP, flag mismatches |
| Monthly Report | 1st of month | Inngest | 2–3 min | Gather data, generate PDF, email to customer |
| Content Refresh | Monthly per client | Inngest | 10–15 min | AI rewrite directory profile content, citation descriptions |
| Profile Refresh | Weekly per client | Inngest | 5–10 min | AI-driven content updates based on ranking/GBP data |
| Token Refresh | Daily (batch all tokens) | BullMQ | 1–2 min | Refresh Google + social OAuth tokens before expiry |
| Email Send | On-demand | BullMQ | 5–10 sec | All transactional emails via Resend |
| PDF Generate | On-demand | BullMQ | 10–30 sec | Playwright render HTML → PDF → S3 |
| Rank Tracking | Weekly per client | BullMQ | 2–3 min | SerpAPI/DataForSEO keyword position checks |
| Invoice Generate | Monthly | BullMQ | 5–10 sec | Stripe/Razorpay invoice creation + email |
| Alert Process | Event-driven | BullMQ | 5–10 sec | Evaluate alert rules, send notifications |
| Domain Verify | Every 5 min (until active) | BullMQ | 2–3 sec | Poll DNS for directory profile URL CNAME verification |
| Dead Letter Retry | Admin-triggered | Manual | Varies | Admin retries failed jobs from /admin/jobs |
Job Concurrency Limits:
| Job Type | Max Concurrent | Reason |
|---|---|---|
| GBP Post | 3 per account | API rate limits |
| Social Post | 5 per platform | Platform limits |
| Citation Submit | 3 total | Directory sites are slow |
| Review Monitor | 2 per account | API quotas |
| NAP Check | 2 total | Proxy bandwidth |
| PDF Generate | 2 total | Playwright memory |
4.6 Communication Touchpoints#
All Emails Sent to Customer#
| Trigger | Frequency | From | Subject Line | Content | |
|---|---|---|---|---|---|
| Welcome | Onboarding Step 17 | One-time | onboarding@rankflow.ai |
"Your RankFlow AI Dashboard is Ready" | Dashboard link, directory profile URL, citation status, next steps |
| Welcome Report | Onboarding Step 18 | One-time | reports@rankflow.ai |
"Your RankFlow Welcome Report" | PDF attachment, onboarding summary, timeline |
| GBP OAuth Request | Onboarding Step 8 | One-time | onboarding@rankflow.ai |
"Connect Your Google Business Profile" | OAuth link, step-by-step screenshot guide, support call link |
| Social Connect Request | Onboarding Step 11 | One-time | onboarding@rankflow.ai |
"Connect Your Social Media Accounts" | Platform buttons, pre-checklist, support link |
| Content Approval Reminder | Content queued | Per content piece | content@rankflow.ai |
"A New Post is Ready for Your Review" | Content preview, approve/reject/edit links, 24h countdown |
| Content Auto-Published | 24h timer expiry | Per content piece | content@rankflow.ai |
"Your Post Was Auto-Published" | Live post link, dashboard link, "Was this OK?" feedback |
| Negative Review Alert | Review monitor | Event-driven | alerts@rankflow.ai |
"New Negative Review Requires Your Attention" | Review text, AI reply preview, approval link |
| Weekly Digest | Cron (Mon 9 AM) | Weekly | digest@rankflow.ai |
"Your Weekly SEO Update — {BusinessName}" | Top 3 stats, position change, new reviews, posts published |
| Monthly Report | Cron (1st, 4 AM) | Monthly | reports@rankflow.ai |
"Your Monthly SEO Report — {Month}" | Full report HTML + PDF attachment, score breakdown, action items |
| Invoice | Stripe/Razorpay | Monthly | billing@rankflow.ai |
"Invoice for {Plan} — {Month}" | PDF invoice, payment summary, GST breakdown |
| Payment Failed | Webhook | Event-driven | billing@rankflow.ai |
"Payment Failed — Please Update Your Method" | Retry schedule, update payment link, grace period info |
| Trial Ending | Cron (Day 5 of trial) | One-time | billing@rankflow.ai |
"Your Trial Ends in 2 Days" | Plan summary, charge amount, cancel/upgrade links |
| Subscription Cancelled | Customer action | One-time | support@rankflow.ai |
"Your Subscription Has Been Cancelled" | Effective date, data retention info, reactivate link |
| Citation Removed Alert | NAP monitor | Event-driven | alerts@rankflow.ai |
"Alert: A Citation Was Removed" | Directory name, action taken, dashboard link |
| GBP Position Drop | Rank tracker | Event-driven | alerts@rankflow.ai |
"Alert: Your Google Maps Position Dropped" | Position change, possible causes, dashboard link |
| Token Expiry Warning | Token health | Event-driven | alerts@rankflow.ai |
"Action Required: Reconnect Your Account" | Account type, expiry date, reconnect link |
| Site Updated | Site evolution | Weekly | content@rankflow.ai |
"Your Website Has Been Updated" | List of changes, reason for each, preview link |
| Lead Notification | Contact form | Event-driven | leads@rankflow.ai |
"New Lead from Your Website" | Lead name, phone, message, source page, action buttons |
All Emails Sent to Admin#
| Trigger | Frequency | To | Subject Line | Content | |
|---|---|---|---|---|---|
| New Client Onboarded | Onboarding Step 20 | Per new client | admin@rankflow.ai, founder@rankflow.ai |
"New Client Onboarded: {BusinessName} ({Plan})" | Full client summary, onboarding status, action items, deep link |
| Job Failed | Dead letter queue | Per failed job | admin@rankflow.ai |
"Job Failed: {jobName}" | Job ID, practice, error message, attempts, retry link |
| NAP Mismatches | NAP check | Per client with mismatches | admin@rankflow.ai |
"NAP Mismatches: {N} citations for {BusinessName}" | List of mismatches, citation IDs, match status |
| GBP Token Refresh Failed | Token refresh | Per failed account | admin@rankflow.ai |
"GBP Token Refresh Failed: {AccountEmail}" | Practice, error, customer reconnect link |
| Daily Admin Summary | Cron (9 AM) | Daily | admin@rankflow.ai |
"RankFlow Daily Summary — {Date}" | New signups, MRR, churn, active jobs, API costs, failed jobs |
| High-Priority Alert | Alert engine | Event-driven | admin@rankflow.ai |
"🚨 High Priority Alert: {Type}" | Alert details, affected client, recommended action |
| GBP Emergency Stop | Emergency trigger | Event-driven | admin@rankflow.ai |
"🚨 GBP Emergency Stop Activated" | Reason, affected accounts, manual override link |
| Monthly Revenue Report | Cron (1st) | Monthly | admin@rankflow.ai, founder@rankflow.ai |
"RankFlow Monthly Revenue — {Month}" | MRR, new clients, churn, revenue by plan, API costs, margin |
| Citation Success Rate Low | Citation builder | Per client <60% | admin@rankflow.ai |
"Low Citation Success: {BusinessName}" | Success rate, failed directories, recommended manual actions |
| Customer Support Request | Support form | Event-driven | support@rankflow.ai |
"Support Request: {Subject}" | Customer details, request text, priority, dashboard link |
Appendix A: Actor Legend#
| Symbol | Meaning | Examples |
|---|---|---|
[C] |
Customer action | Filling forms, clicking OAuth links, approving content, viewing dashboard |
[S] |
System automation | AI content generation, API calls, job queue processing, email sending |
[A] |
Admin/Operations action | Sales calls, manual citation submission, content review, customer support |
Appendix B: Key System Endpoints#
| Endpoint | Purpose | Actor |
|---|---|---|
POST /api/auth/signup |
Account creation | [C] |
POST /api/trpc/practice.update |
Business profile update | [C] |
GET /api/webhooks/google/oauth-callback |
GBP OAuth callback | [S] |
POST /api/webhooks/resend |
Email delivery tracking | [S] |
POST /api/webhooks/stripe |
Payment events | [S] |
POST /api/webhooks/razorpay |
Payment events | [S] |
POST /api/revalidate/site |
ISR cache purge | [S] |
GET /api/health/jobs |
Job queue status | [A] |
GET /admin/clients |
Client management | [A] |
GET /admin/jobs |
Job monitoring | [A] |
Appendix C: Data Model Summary#
| Entity | Key Fields | Purpose |
|---|---|---|
User |
id, email, role, createdAt |
Authentication |
ClientProfile / Practice |
id, businessName, category, plan, status, directory URL, onboardingComplete |
Core business record |
Location |
id, practiceId, address, city, phone, hours, isPrimary |
NAP data |
GbpAccount |
id, practiceId, accountEmail, accessToken(encrypted), refreshToken(encrypted), tokenExpiresAt |
GBP OAuth tokens |
GbpLocation |
id, gbpAccountId, gbpLocationId, name |
GBP location mapping |
SocialAccount |
id, practiceId, platform, composioConnectionId, isActive |
Social connections |
CitationDirectory |
id, name, domain, submissionType, isActive |
Directory registry |
Citation |
id, practiceId, directoryName, status, directoryUrl, matchStatus |
Citation instances |
ProfileSection |
id, practiceId, sectionKey, content, sortOrder |
Directory profile content |
ContentPiece |
id, practiceId, type, status, content, autoPublishAt |
Approval queue |
ScheduledPost |
id, practiceId, platform, content, scheduledAt, status |
Post scheduling |
Review |
id, locationId, rating, comment, replyText, status |
Review management |
Report |
id, practiceId, period, scoreOverall, pdfUrl |
Monthly reports |
JobLog |
id, practiceId, jobType, status, payload, result |
Audit trail |
EmailLog |
id, practiceId, type, to, status, sentAt |
Email tracking |
ConsentLog |
id, practiceId, consentType, ipAddress, timestamp |
Legal compliance |
Subscription / Billing |
id, practiceId, provider, status, trialEnd |
Billing |
Document End — RankFlow AI Business Process Flow Map v1.0.0
Section 5: What RankFlow Automates (Comprehensive)#
RankFlow AI operates as a fully automated local SEO engine for Indian medical SMBs. The platform orchestrates hundreds of discrete tasks per client per month across nine automation categories. Each automation is designed with explicit triggers, schedules, outputs, and human oversight gates to ensure medical compliance and quality control.
5.1 SEO Hygiene Automation#
SEO hygiene automation ensures every client directory profile maintains technical SEO standards without manual developer intervention.
| Automation | What Is Automated | Frequency | Trigger | Output | Human Oversight |
|---|---|---|---|---|---|
| Schema Markup Generation | JSON-LD generation for LocalBusiness, Physician, Dentist, MedicalClinic, FAQPage, and Service schemas | On page creation + monthly refresh | Landing profile publish event; content update event | Valid JSON-LD injected into <head> |
Admin review via /admin/content for schema validity; auto-validation against Schema.org |
| Meta Title/Description Generation | SEO-optimized <title> (50-60 chars) and <meta name="description"> (150-160 chars) per page |
On page creation + monthly refresh | Content generation workflow; profile refresh cron | Updated HTML <head> tags |
Content review queue; rejection triggers regeneration |
| Canonical URL Management | <link rel="canonical"> tags on all pages; cross-domain canonicals for owned blog citations |
Real-time on render | Page render pipeline | Canonical tag in HTML | Admin audit log tracks all canonical changes |
| Sitemap Generation | XML sitemap (sitemap.xml) with all directory profiles, blog posts, and citation pages |
Weekly (Mondays 2 AM IST) | Site evolution cron job | Updated sitemap.xml at directory URL root |
Auto-submitted to Google Search Console via API |
| robots.txt Management | robots.txt with allow/disallow rules, sitemap reference, and crawl-delay for bots |
On directory URL creation + on-demand | Landing profile publish event | robots.txt at directory URL root |
Admin can override via /admin/directory |
| Mobile-Friendliness Checks | Google Mobile-Friendly Test API polling; viewport meta validation | Weekly | Site evolution cron | Pass/fail status in site health record | Failed checks trigger auto-rewrite of offending CSS |
| Page Speed Monitoring | Lighthouse CI scores (LCP, INP, CLS) via PageSpeed Insights API | Weekly | Site evolution cron | Performance scores stored; alerts if LCP > 2.5s or CLS > 0.1 | Auto-optimization of images and critical CSS |
| Internal Link Structure | Auto-generation of internal links between directory profile sections, FAQ blocks, and service pages | On content generation | Content publish event | Updated anchor text links in page HTML | Link graph visualized in client dashboard |
| Image Alt Text Generation | AI-generated descriptive alt text for all images using gpt-4o-mini |
On image upload | Image upload event | Alt text stored in CMS; injected at render | Batch review in /admin/content |
| JSON-LD Injection on Directory Profiles | Dynamic injection of LocalBusiness, Physician, or Dentist schema into Next.js <Head> |
Every ISR revalidation | Content update or scheduled refresh | Structured data present in rendered HTML | Google Rich Results Test validation on publish |
Technical Implementation: SEO hygiene runs as part of the profile-refresh Inngest workflow (cron: 0 2 * * 1). The workflow calls ai.generate({ task: "seo_audit" }) using claude-sonnet for complex analysis, then applies fixes automatically. All changes are versioned in the ProfileSection table with updatedAt timestamps.
5.2 Citation Network Automation#
The citation network is RankFlow's core moat: 30 directory submissions per client location, combining India-specific medical directories, global platforms, and owned blog sites.
| Automation | What Is Automated | Frequency | Trigger | Output | Human Oversight |
|---|---|---|---|---|---|
| 30-Directory Submission | Submission to 25 directories (10 India-specific: Justdial, Practo, Sulekha, Lybrate, 1mg, IndiaMART + 10 global: Yelp, Foursquare, Hotfrog, Brownbook, Cylex + 5 global maps: Bing Places, Apple Maps, TomTom, HERE) plus 5 owned blog sites | On onboarding + monthly refresh | skill/13-citation-submit Inngest event |
Citation records in DB with status SUBMITTED or FAILED |
Admin monitors success rate in /admin/jobs; manual retry for failed submissions |
| Unique Description Generation | AI-generated 100-200 word unique description per directory using gpt-4o-mini |
Per submission batch | Citation builder workflow step 3 | 30 unique descriptions stored in Citation.description |
Plagiarism check via fuzzy matching; duplicates rejected |
| NAP Consistency Monitoring | Automated scan of all live citations for Name/Address/Phone consistency using Firecrawl | Monthly (1st of month 2 AM IST) | skill/14-citation-verify-nap event |
NAP match status:MATCHED, MISMATCH_NAME, MISMATCH_ADDRESS, MISMATCH_PHONE, MISMATCH_ALL, NOT_FOUND |
Alert to admin if mismatches > 3 per client |
| Citation Uptime Monitoring | HTTP status check + content presence validation on all submitted citations | Weekly | Site evolution cron | Uptime percentage per citation | NOT_FOUND status triggers resubmission workflow |
| Screenshot Capture for Proof | Full-page screenshot via Hyperbrowser/Playwright at submission time | Per submission | Form submission success | PNG stored in S3 at citations/{practiceId}/{directory}.png |
Admin views screenshots in client detail Citations tab |
| Failed Submission Retry Logic | Exponential backoff retry (5 attempts, 60s initial delay) for failed citations | Event-driven | BullMQ citation-submit queue failure |
Retry attempts logged; final failure moves to dead letter queue | Admin retry button in /admin/jobs for DLQ items |
| Monthly Re-Verification | Full NAP re-check + listing URL validation for all VERIFIED citations |
Monthly | BullMQ nap-check queue |
Updated matchStatus and lastScannedAt |
Admin report of verification results emailed monthly |
Network Composition:
| Category | Count | Examples | Submission Type | Target Success Rate |
|---|---|---|---|---|
| India-Specific Directories | 10 | Justdial, Practo, Sulekha, Lybrate, 1mg, IndiaMART | API + Form | > 75% |
| Global General Directories | 10 | Yelp, Foursquare, Hotfrog, Brownbook, Cylex | API + Form | > 85% |
| Owned Blog Sites | 5 | kerala-health.rankflow.in, medical-guide.rankflow.in | Direct DB insert | 99% |
| Global Maps/Directories | 5 | Bing Places, Apple Maps, TomTom, HERE | API | > 80% |
Target Metrics: Citation success rate > 80%; NAP consistency > 95%; Time to 30 citations < 7 days from onboarding.
5.3 GBP Management Automation#
Google Business Profile automation maintains active presence, review responsiveness, and insight tracking without manual login.
| Automation | What Is Automated | Frequency | Trigger | Output | Human Oversight |
|---|---|---|---|---|---|
| Business Info Sync | Synchronization of practice name, address, phone, hours, services, and website from RankFlow DB to GBP API | On location update + weekly | Location update mutation; profile refresh cron | GBP location data updated | Change diff logged in audit log |
| Weekly Post Generation & Publishing | AI-generated GBP posts (150-300 chars) with CTA using claude-haiku |
2-3x per week per location (Mon/Wed/Fri 9 AM IST) | BullMQ gbp-post-publish cron |
Published post visible on GBP; post ID stored in GbpPost table |
Max 3 posts/week enforced to prevent suspension; content approval gate for medical clients |
| Review Monitoring (Daily Poll) | Fetch new reviews via GBP API; store rating, comment, reviewer, date | Daily at 8 AM IST | BullMQ review-monitor cron |
New reviews in Review table with status NEW |
Sentiment analysis auto-runs on ingestion |
| Auto-Reply to Positive Reviews | AI-generated empathetic reply published immediately for 4-5 star reviews | Real-time on review detection | Review monitor processor | Reply published to GBP;Review.status = REPLIED |
Reply text stored for audit; tone validated |
| AI-Generated Reply Drafts for Negative Reviews | Empathetic, apologetic reply drafted for 1-3 star reviews; queued for approval | Real-time on review detection | Review monitor processor | Review.status = NEW (awaiting approval); email sent to client |
24h auto-approve for 3-star; manual-only for 1-2 star |
| Photo Upload | AI-generated or client-provided images uploaded to GBP photo gallery | Weekly with post | Post creation workflow | Photo visible on GBP profile | Image compliance check (no PHI, proper sizing) |
| Insights Data Collection | Daily metrics: views, clicks, calls, directions, photo views via GBP API | Daily | Review monitor processor | Time-series data in GbpInsight table |
Aggregated into monthly report |
| Post Performance Tracking | Track views, clicks per GBP post over 30 days | Weekly | Insights fetch | Post performance score in dashboard | Underperforming posts flagged for content refresh |
GBP Rate Limiting:
| Operation | Daily Limit | Per-Minute Limit | Enforcement |
|---|---|---|---|
| Business information | 10,000 | 100 | Redis quota counter |
| Posts | 500 | 30 | Redis quota + max 3/week per location |
| Reviews | 1,000 | 60 | Redis quota counter |
| Photos | 1,000 | 60 | Redis quota counter |
| Insights | 500 | 30 | Redis quota counter |
| Q&A | 500 | 30 | Redis quota counter |
Risk Mitigation: Emergency stop function (emergencyStop()) can pause all GBP activity system-wide or per-practice. Gradual ramp for new clients (1 post in week 1, 2 in week 2, 3 in week 3+).
5.4 Social Media Automation#
Cross-platform social presence is maintained via Composio OAuth connections and Zernio scheduling.
| Automation | What Is Automated | Frequency | Trigger | Output | Human Oversight |
|---|---|---|---|---|---|
| Instagram Post Generation & Scheduling | AI-generated caption + hashtag set; image prompt created | 2-3x per week | Content generation workflow | Scheduled post in Zernio queue;SocialPost.status = SCHEDULED |
24h approval gate for medical clients |
| Facebook Post Generation & Scheduling | Longer-form post with link preview; CTA button | 2-3x per week | Content generation workflow | Scheduled post in Zernio queue | Cross-posted content adapted for Facebook tone |
| LinkedIn Post Generation & Scheduling | Professional tone post; medical industry hashtags | 1-2x per week | Content generation workflow | Scheduled post in Zernio queue | B2B medical networking focus |
| Twitter/X Post Generation & Scheduling | Short-form thread or single tweet; engagement hooks | 2-4x per week | Content generation workflow | Scheduled post in Zernio queue | Character limit enforcement (280 chars) |
| Hashtag Generation | Platform-optimized hashtag sets (5-10 tags) based on specialty + city | Per post | Social post generation | Hashtag array stored in SocialPost.hashtags |
Blacklist check against banned medical hashtags |
| Image Generation/Prompt Creation | DALL-E / Gemini image prompt generation; or stock image selection | Per post with media | Social post generation | Image URL stored; uploaded to CDN | Image content policy check (no graphic medical imagery) |
| Cross-Platform Content Adaptation | Same core topic rewritten for each platform's tone and format | Per post batch | Content generation workflow | Platform-specific variants | Admin can edit per-platform variants in /admin/content |
| Engagement Monitoring | Poll for likes, comments, shares via Composio APIs | Daily | Social sync job | Engagement metrics in SocialPost table |
Low-engagement posts flagged for content strategy review |
Platform Limits:
| Platform | Auth Method | Daily Post Limit | Rate Limit |
|---|---|---|---|
| Composio (Meta OAuth) | 25 publishes/user/day | Instagram Graph API | |
| Composio (Meta OAuth) | Per-page limits | Facebook Graph API | |
| Composio (OAuth 2.0) | 150 posts/day | LinkedIn API | |
| Twitter/X | Composio (OAuth 2.0) | 300 tweets/day | Twitter API v2 |
Fallback: If Composio/Zernio fails, post status set to FAILED, client emailed with copy-paste content for manual posting.
5.5 Content Generation Automation#
AI-driven content creation targets local SEO keywords and builds topical authority on owned blog sites.
| Automation | What Is Automated | Frequency | Trigger | Output | Human Oversight |
|---|---|---|---|---|---|
| Directory Profile Article Generation | 3-5 articles per client targeting "[service] + [city]" keywords (e.g., "best dentist in Kochi") | On onboarding + monthly refresh | skill/29-content-generate Inngest event |
500-1000 word SEO article in ContentPiece table |
Keyword density < 2%; readability score > 60; approval gate |
| FAQ Block Generation | 10+ Q&A pairs with FAQPage schema markup | On onboarding + monthly refresh | Content generation workflow | Structured Q&A with JSON-LD; injected into directory profile | Medical accuracy review; disclaimer auto-appended |
| Blog Post Generation for Owned Sites | Health articles, city guides, doctor profiles for 5 owned blog sites | 2-3 posts/week per site | Site evolution cron | BlogSitePost in PUBLISHED or DRAFT status |
Topical authority building; internal linking to client sites |
| Content Refresh/Rewrite | Monthly rewrite of underperforming content (pages with declining rank or engagement) | Monthly | Content performance analysis | Updated ContentPiece with refreshed copy |
Before/after diff shown in admin dashboard |
| Vernacular Content | Malayalam, Tamil, Hindi translations of core directory profile content and GBP posts | On request + quarterly | Manual trigger or tier-based auto-enable | Translated content with hreflang tags | Native speaker review for medical terminology accuracy |
AI Model Mapping:
| Content Type | Default Model | Rationale | Avg Cost |
|---|---|---|---|
| Directory profile article | claude-sonnet |
Long-form, SEO-optimized | ~$0.015 |
| FAQ generation | claude-haiku |
Structured Q&A, cost-sensitive | ~$0.003 |
| Blog post | claude-sonnet |
Topical authority, original | ~$0.012 |
| Social caption | gpt-4o-mini |
Short, casual tone | ~$0.001 |
| Citation description | gpt-4o-mini |
30 variations needed | ~$0.002 |
| Content refresh | claude-sonnet |
Strategic updates | ~$0.010 |
| Vernacular translation | claude-sonnet |
Cultural nuance, medical accuracy | ~$0.008 |
Content Approval States:
| State | Badge | Auto-Publish | Actions |
|---|---|---|---|
DRAFT |
Gray | — | Edit, Submit |
PENDING_REVIEW |
Yellow | 24h countdown | Approve, Reject, Edit |
APPROVED |
Green | Immediate | — |
PUBLISHED |
Blue | — | View live |
REJECTED |
Red | Never | Regenerate |
FAILED |
Red | Never | Retry |
5.6 Review Management Automation#
Comprehensive review lifecycle management from detection to response to reporting.
| Automation | What Is Automated | Frequency | Trigger | Output | Human Oversight |
|---|---|---|---|---|---|
| Daily Review Poll via GBP API | Fetch all new reviews since last poll for all connected GBP accounts | Daily at 8 AM IST | BullMQ review-monitor cron |
New reviews in Review table |
Reviewer name and comment stored; no PHI extracted |
| Sentiment Analysis | AI classification of review tone (positive, neutral, negative, complaint, praise) | Real-time on review ingestion | Review monitor processor | Sentiment label in Review.sentiment |
Accuracy tracked; misclassifications flagged |
| Auto-Reply for 4-5 Star Reviews | AI-generated thank-you reply published immediately | Real-time | Review monitor processor | Reply published;Review.status = REPLIED |
Reply template A/B tested; performance scored |
| Approval Queue for 1-3 Star Reviews | AI-generated empathetic reply held for client/admin approval | Real-time | Review monitor processor | Review.status = NEW; email notification sent |
3-star: 24h auto-approve; 1-2 star: manual only |
| Review Aggregation for Reports | Monthly rollup: total reviews, average rating, reply rate, sentiment distribution | Monthly | Monthly report workflow | Report section in PDF and email | Client-visible in dashboard year-round |
| Review Score Tracking | Time-series tracking of average rating, review velocity, reply rate | Daily | Review monitor processor | Trend data for score calculation | Alert if avg rating drops below 3.5 |
Reply Approval Matrix:
| Rating | Action | Approval Required | Auto-Approve Window |
|---|---|---|---|
| 5 stars | Auto-reply with AI | ❌ | Immediate |
| 4 stars | Auto-reply with AI | ❌ | Immediate |
| 3 stars | AI reply, queue for approval | ✅ | 24 hours |
| 1-2 stars | AI reply, queue for approval | ✅ | Manual only |
Alert Triggers:
- Negative review unreplied > 24h → Alert to client + admin
- Average rating drops > 0.5 in 7 days → Alert to client
- Review velocity drops to 0 for 14 days → Alert to admin
5.7 Reporting Automation#
Automated report generation, delivery, and score tracking for client accountability and retention.
| Automation | What Is Automated | Frequency | Trigger | Output | Human Oversight |
|---|---|---|---|---|---|
| Monthly PDF Report Generation | Full SEO report with all metrics, charts, and action items | 1st of month at 4 AM IST | Inngest monthly-report cron |
PDF stored in S3;Report record created |
Admin can regenerate or customize template |
| Score Calculation | Weighted composite score: GBP 25%, Citations 25%, Reviews 20%, Rankings 20%, SEO 10% | Monthly + real-time on data update | Report generation workflow; data update event | Overall score 0-100; per-category scores | Score formula visible to clients; admin can adjust weights |
| Keyword Rank Tracking | DataForSEO/SerpAPI polling for target keyword positions | Weekly | Site evolution cron | Position data in KeywordRanking table |
Top 10 / Top 3 counts; change from previous period |
| Email Report Delivery | HTML email with embedded score cards + PDF attachment via Resend | 1st of month | Report generation completion | Email sent to practice owner; tracked in EmailLog |
Delivery status tracked (sent, delivered, opened, bounced) |
| Weekly Digest Generation | Top 3 stats summary: Maps position, new reviews, posts published | Every Monday | BullMQ email-send cron |
HTML email to client | Auto-generated; no approval needed |
| Alert Generation | Event-driven alerts for GBP drops, citation removals, negative reviews, token expiry | Real-time | Threshold breach event | Alert email to client and/or admin | Priority levels: High (red), Medium (amber), Low (blue) |
Score Calculation Formula:
| Category | Weight | Calculation |
|---|---|---|
| GBP | 25% | (views + clicks + calls + directions) / baseline × 100 |
| Citations | 25% | (live count / 30 × 100) × (NAP consistency %) |
| Reviews | 20% | (avg rating / 5 × 50) + (reply rate × 50) |
| Rankings | 20% | (keywords in top 10 / total keywords × 100) |
| SEO | 10% | Site health + schema validity + speed score |
Report Sections:
| Section | Metrics | Source |
|---|---|---|
| Executive Summary | Overall score (0-100), period | Calculated |
| GBP Performance | Views, clicks, calls, directions, posts | GBP API |
| Citation Health | Live count, NAP consistency % | Citation DB |
| Review Summary | New reviews, avg rating, reply rate | Review DB |
| Rank Tracking | Keyword positions, top 10 count | DataForSEO |
| Social Activity | Posts published, engagement | Social DB |
| Site Traffic | Visitors, bounce rate | Analytics |
| AI Engine Mentions | ChatGPT/Perplexity visibility | Manual/Kimi |
| Action Items | 3 recommended actions | AI-generated |
5.8 Directory Profile Automation#
End-to-end directory profile lifecycle from directory URL assignment to weekly AI-driven evolution.
| Automation | What Is Automated | Frequency | Trigger | Output | Human Oversight |
|---|---|---|---|---|---|
| Directory URL Assignment | Auto-assignment of *.rankflow.ai directory URL based on practice slug |
On onboarding | Practice creation event | DNS A record via Cloudflare API; SSL certificate provisioned | Custom domain upgrade available in higher tiers |
| Directory Profile URL DNS Management | CNAME/AAAA record creation; DNS propagation monitoring | On directory profile URL set | site.setCustomDomain mutation |
DNS records displayed to user; propagation status tracked | Admin force-revalidate button in /admin/directory |
| Template Selection & Application | Auto-selection of template based on practice type (medical-modern, dental-clean, clinic-premium, ca-professional, lawyer-authority) | On onboarding | Practice type field | Template applied to Practice.templateId |
Client can change template in dashboard |
| Section Generation | Auto-generation of 7 core sections: hero, about, services, testimonials, FAQ, contact, CTA | On onboarding + monthly refresh | Site generation workflow | ProfileSection records for each section |
Section visibility toggleable; reorderable by client |
| Schema Injection | Dynamic JSON-LD injection into Next.js <Head> based on practice type and services |
Every ISR revalidation | Page render | Valid structured data in HTML | Google Rich Results Test on every deploy |
| ISR Revalidation on Content Updates | On-demand revalidation of static pages when content changes | Real-time on content update | site.publish mutation or content approval |
Fresh static page served from CDN | Revalidation log in admin dashboard |
| Weekly AI-Driven Profile Refresh | Content refresh, new section suggestions, seasonal updates, performance optimizations | Weekly (Mondays 2 AM IST) | Inngest profile-refresh cron |
Updated ProfileSection content; new sections if approved |
Changes queued in PENDING_REVIEW for 24h auto-approve |
Directory Profile Sections:
| Section | Content Source | AI Model | Update Frequency |
|---|---|---|---|
| Hero | Practice name, tagline, CTA, hero image | claude-sonnet |
Monthly |
| About | Practice story, doctor bios, credentials | claude-sonnet |
Monthly |
| Services | Service list with descriptions and pricing | claude-haiku |
Monthly |
| Testimonials | Imported from GBP reviews | N/A | Weekly sync |
| FAQ | 10+ Q&A pairs with schema | claude-haiku |
Monthly |
| Contact | NAP, map embed, hours, form | N/A | On location update |
| CTA | Booking link, phone click-to-call | claude-haiku |
Monthly |
DNS & SSL Monitoring:
| Check | Frequency | Target | Alert Threshold |
|---|---|---|---|
| DNS propagation | On directory profile URL set | < 5 minutes | > 30 minutes |
| SSL certificate expiry | Daily | > 30 days remaining | < 7 days remaining |
| CDN cache status | Real-time | Cached | Bypass > 1 hour |
5.9 AI Engine Optimization Automation#
Preparation and monitoring for visibility in AI-powered search engines (ChatGPT, Perplexity, Claude, Gemini).
| Automation | What Is Automated | Frequency | Trigger | Output | Human Oversight |
|---|---|---|---|---|---|
| ChatGPT/Perplexity Visibility Monitoring | Manual monitoring of brand mentions in AI search responses; tracking of "best [service] in [city]" queries | Monthly | Manual research workflow | Visibility score in report | Kimi/Perplexity manual checks; not yet API-automated |
| AI Citation Optimization | Structured content formatting to increase likelihood of AI engine citation (clear headings, concise answers, authoritative tone) | On content generation | Content generation workflow | Formatted content with semantic markup | Content quality score in admin review |
| Answer Engine Content Preparation | FAQ-first content structure; concise 40-60 word answers; entity-rich copy | On content generation | Content generation workflow | Answer-engine-optimized content pieces | AEO score tracked per content piece |
| Structured Data for AI Consumption | Enhanced Schema.org markup (MedicalWebPage, MedicalBusiness, Physician) with entity relationships | On page creation + monthly | Site evolution cron | Rich structured data | Validation against Google's structured data testing tool |
AI Engine Optimization Tactics:
| Tactic | Implementation | Expected Outcome |
|---|---|---|
| Entity-rich copy | Medical entities (conditions, treatments, specialties) explicitly named in content | Higher entity recognition by AI engines |
| Concise answer blocks | 40-60 word direct answers in FAQ sections | Increased snippet extraction probability |
| Authoritative citations | Links to medical authorities (WHO, ICMR, medical journals) in blog content | Trust signal for AI ranking |
| Consistent NAP across web | 30-directory citation network | Entity consolidation in Knowledge Graph |
| GBP completeness | 100% profile fill + regular posts + photo uploads | Strong local entity signal |
Section 6: Admin Dashboard & Observability#
The admin dashboard (/admin) provides system-wide visibility, operational control, and financial oversight. All admin endpoints use adminProcedure which enforces role === "ADMIN" and returns 403 FORBIDDEN otherwise.
6.1 Admin Dashboard Pages & Functions#
| Route | Page Component | Primary Data | Key Functions |
|---|---|---|---|
/admin |
AdminKPIPage |
System KPIs | Total clients, MRR, active jobs, citation health, revenue chart, client status pie chart, job health chart, API cost chart, recent activity feed |
/admin/clients |
ClientListPage |
All practices | CRUD management: Name, Slug, Type, Tier, Status, Locations, Created, Trial Ends. Actions: View, Edit, Suspend, Delete (soft). Bulk: Change tier, Export CSV, Send email |
/admin/clients/[id] |
ClientDetailPage |
Practice + relations | 9 tabs: Overview (profile card, subscription, quick stats), Locations (GBP status), GBP (account, posts, reviews, insights), Social (accounts, post history), Citations (directory list, NAP status, screenshots), Site (template, sections, publish status), Jobs (all jobs), Billing (invoices, payment history), Audit Log (all actions) |
/admin/directory |
DomainListPage |
Directory URLs, directory profile URLs | Practice, Directory URL, Directory Profile URL, DNS Status (Propagated/Pending/Error), SSL Status (Active/Expired), CDN Status (Cached/Bypass), Actions: DNS check, force revalidate |
/admin/directory-profiles |
WebsiteListPage |
Owned blog sites | Domain, Niche, Authority Score, Post Count, Linked Practice, Health (Active/Down), Last Published |
/admin/social-connections |
SocialConnectionsPage |
All social accounts | Platform, Account Name, Practice, Status (Active/Expired/Pending), Followers, Last Sync, Actions: Disconnect, refresh token |
/admin/jobs |
JobMonitorPage |
Job queue | Stat cards: Pending (yellow), Running (blue), Completed (green), Failed (red). Table: Job ID, Skill, Practice, Status, Duration, Cost, Started, Actions: Retry, View logs. Filters: Status, Practice, Skill, Date range. Auto-refresh: 10 seconds |
/admin/content |
ContentReviewPage |
AI content queue | Split view: list (Title/Type, Practice, Status, AI Provider, Cost, Created) + preview (rendered HTML, SEO score, readability score, Approve/Reject/Edit). Prompt Management tab: templates, A/B test variants, performance scores |
/admin/billing |
BillingOverviewPage |
Subscriptions, invoices | Revenue cards: MRR, ARR, Active Subscriptions, Failed Payments. Tables: Subscriptions, Invoices, Failed Charges |
/admin/reports |
SystemReportsPage |
Revenue, churn, costs | Revenue by Month, Client Churn, Citation Success Rate, API Cost Breakdown, Content Generation Volume, Support Ticket Summary. Export: CSV, PDF |
Admin KPI Data Structure:
interface AdminKPIs {
totalClients: number;
activeClients: number;
trialClients: number;
churnedClients: number;
mrr: number; // INR
arr: number; // INR
activeJobs: number;
failedJobs24h: number;
citationHealth: number; // % verified citations
apiCosts7d: {
claude: number;
openai: number;
dataforseo: number;
serpapi: number;
hyperbrowser: number;
firecrawl: number;
};
recentActivity: AuditLogEntry[];
}
Impersonation Feature: Admin can "impersonate" a client to see their dashboard. Sets x-practice-id header, temporarily gains practiceProcedure access, audit log records impersonation.
6.2 Observability Metrics (Real-Time)#
All metrics are collected via structured logging (Pino) and exposed through health check endpoints. The job queue metrics are polled from BullMQ Redis every 10 seconds on the admin dashboard.
| Metric | Source | Collection Frequency | Target Value | Alert Threshold |
|---|---|---|---|---|
| Queue depth per job type | BullMQ queue.getWaitingCount() |
Real-time (10s poll) | < 20 per queue | > 100 = Warning |
| Job failure rate | BullMQ failed / (completed + failed) |
Rolling 1-hour window | < 2% | > 5% in 1 hour = Warning |
| Average job duration | BullMQ job completion timestamp - start timestamp | Per job completion | < 2x baseline per job type | > 2x baseline = Investigate |
| API cost per client per day | AI audit log aggregation | Daily rollup | < $10/day | > $50/day = Notify admin |
| Citation success rate | Citation.status = "SUBMITTED" / total attempted |
Per batch completion | > 80% | < 70% = Alert |
| NAP consistency percentage | matchStatus = "MATCHED" / total live citations |
Monthly check | > 95% | < 90% = Alert |
| GBP post publish success rate | GbpPost.status = "PUBLISHED" / total scheduled |
Weekly | > 95% | < 90% = Alert |
| Social post publish success rate | SocialPost.status = "PUBLISHED" / total scheduled |
Weekly | > 90% | < 80% = Alert |
| Token refresh success rate | Successful refresh / total attempts | Daily batch | > 98% | < 95% = Alert |
| Directory profile render time | Next.js build + CDN propagation | On publish | < 3 seconds | > 5 seconds = Warning |
| Email delivery rate | EmailLog.status = "DELIVERED" / total sent |
Daily | > 95% | < 90% = Alert |
| Customer dashboard engagement | Login frequency, feature usage | Weekly | > 2 logins/week | < 1 login/month = Churn risk |
Metric Dashboard Refresh Rates:
| Dashboard Section | Refresh Interval | Data Source |
|---|---|---|
| Job monitor table | 10 seconds | BullMQ Redis |
| KPI stat cards | 60 seconds | PostgreSQL aggregated views |
| API cost chart | 5 minutes | AI audit log |
| Citation health | 1 hour | Citation table |
| Revenue chart | 1 hour | Billing table |
6.3 Alert Thresholds & Notifications#
Alert routing: Slack #alerts for warnings, PagerDuty + Slack for critical, email for admin notifications.
| Condition | Severity | Threshold | Recipients | Channel | Auto-Action |
|---|---|---|---|---|---|
| Queue depth > 100 | Warning | Any queue waiting count > 100 | Admin | Slack #alerts | Scale worker container if auto-scaling enabled |
| Job failure rate > 5% in 1 hour | Warning | Failed / total > 5% in rolling 1h | Admin | Slack #alerts | Pause new job ingestion; alert engineering |
| API cost > $50/day per client | Warning | Per-practice daily AI spend > $50 | Admin | Flag for review; throttle non-essential tasks | |
| Citation success rate < 70% | Alert | Submitted / attempted < 70% per batch | Admin + Client | Trigger manual review of failing directories | |
| NAP mismatches > 3 per client | Alert | matchStatus != "MATCHED" count > 3 |
Admin | Slack #alerts | Schedule citation update workflow |
| GBP token expiry < 7 days | Alert | tokenExpiresAt - now < 7 days |
Admin | Trigger token refresh job | |
| Negative review unreplied > 24h | Alert | status = "NEW" and createdAt < now - 24h |
Client + Admin | Escalate to client; admin can force-publish reply | |
| Subscription payment failed | Alert | Stripe/Razorpay webhook payment_failed |
Client + Admin | Retry per payment provider schedule; flag churn risk | |
| System health check fails | Critical | /api/health returns non-200 |
Admin | PagerDuty + Slack | Auto-restart failed service container |
| Disk usage > 80% | Critical | EC2 disk utilization > 80% | Admin | PagerDuty + Slack | Auto-scale storage + alert |
| Memory usage > 90% | Critical | Container memory > 90% | Admin | PagerDuty + Slack | Restart container + alert |
| Dead letter queue > 10 in 24h | Warning | DLQ count > 10 | Admin | Slack #alerts | Manual investigation required |
| Worker CPU > 80% for 5 min | Warning | Container CPU > 80% | Admin | Slack #alerts | Scale to next container tier |
Alert Template Priority Colors:
| Priority | Color | Response SLA |
|---|---|---|
| Critical | Red (#dc2626) | 15 minutes |
| Warning | Amber (#f59e0b) | 2 hours |
| Low | Blue (#2563eb) | 24 hours |
6.4 System Health Monitoring#
Health endpoints provide real-time system status for load balancers, monitoring tools, and admin dashboards.
| Endpoint | Check Components | Response Format | Interval | Failure Action |
|---|---|---|---|---|
/api/health |
PostgreSQL (pg_isready), Redis (PING), Inngest (dev server reachable) | { status: "ok" | "degraded", checks: { db: boolean, redis: boolean, inngest: boolean } } |
Every 30s (Docker healthcheck) | Container restart if 3 consecutive failures |
/api/health/jobs |
Queue depths for all BullMQ queues:gbp-post-publish, social-post-publish, review-monitor, nap-check, email-send, token-refresh, citation-submit, pdf-generate |
{ timestamp, queues: [{ name, waiting, active, completed, failed }], overall: { totalWaiting, totalActive, totalFailed } } |
Every 60s (UptimeRobot) | Alert if any queue > 100 waiting or > 10 failed |
| Worker CPU/Memory Monitoring | Container-level metrics via Dokploy dashboard / AWS CloudWatch | CPU %, Memory %, Network I/O | Real-time | Alert thresholds per 6.3 |
| Disk Usage Monitoring | EC2 volume utilization via CloudWatch | Disk used %, free GB | Every 5 minutes | Alert at > 80%; auto-scale at > 90% |
| SSL Certificate Expiry Monitoring | Certificate expiration date check for *.rankflow.ai and all directory profile URLs |
Days until expiry | Daily | Alert at < 7 days; auto-renew via Cloudflare |
| DNS Propagation Monitoring | DNS resolution check for all client directory URLs and directory profile URLs | Propagated / Pending / Error | On domain change + daily | Alert if Pending > 30 minutes |
Docker Health Checks:
| Service | Test Command | Interval | Timeout | Retries |
|---|---|---|---|---|
| Next.js app | curl -f http://localhost:3000/api/health |
30s | 10s | 3 |
| PostgreSQL | pg_isready -U rankflow |
10s | 5s | 5 |
| Redis | redis-cli ping |
10s | 3s | 5 |
Disaster Recovery RTO/RPO:
| Scenario | RTO | RPO | Recovery Steps |
|---|---|---|---|
| EC2 failure | 30 min | 24h | Launch new EC2, restore from latest S3 backup |
| DB corruption | 1 hour | 24h | Restore from S3 backup, replay WAL if possible |
| Accidental deletion | 15 min | 0 | Point-in-time recovery from backups |
| Region outage | 4 hours | 24h | Spin up in backup region (multi-region S3) |
6.5 Cost & Performance Tracking#
Comprehensive cost tracking enables gross margin calculation and per-client profitability analysis.
| Tracking Dimension | Granularity | Data Source | Storage | Report Location |
|---|---|---|---|---|
| Per-client AI cost | Per request | AI audit log (ai_generation event) |
PostgreSQL ai_usage table |
/admin/reports → API Cost Breakdown |
| Per-task model usage breakdown | Per request | AI router output (model, tokensUsed, costUsd) |
PostgreSQL ai_usage table |
/admin/content → cost column per content piece |
| Monthly API spend by provider | Monthly aggregation | AI audit log grouped by provider | PostgreSQL materialized view | /admin → API Costs chart |
| Infrastructure cost per client | Monthly proration | EC2 + S3 + Cloudflare / total clients | Calculated field | /admin/reports → Infrastructure Cost |
| Gross margin calculation | Monthly | (MRR - COGS) / MRR × 100 | Calculated field | /admin/reports → Revenue by Month |
API Provider Cost Breakdown (per 100 clients/month):
| Provider | Service | Usage @ 100 Clients | Cost (USD) |
|---|---|---|---|
| Anthropic | Claude Sonnet | 30k requests/mo | $150 |
| Anthropic | Claude Haiku | 50k requests/mo | $25 |
| OpenAI | GPT-4o | 10k requests/mo | $50 |
| OpenAI | GPT-4o Mini | 40k requests/mo | $15 |
| DataForSEO | Rank tracking, SERP data | 50k API calls/mo | $100 |
| SerpAPI | Keyword research | 10k calls/mo | $50 |
| Hyperbrowser | Citation form submission | 500 sessions/mo | $50 |
| Firecrawl | NAP verification, scraping | 2k scrapes/mo | $10 |
| Composio | Social media connections | 100 connections | $30 |
| Zernio | Social post scheduling | 500 schedules/mo | $30 |
| Resend | Email delivery | 50k emails/mo | $0 (free tier) |
| Total API | ~$470/mo |
Infrastructure Cost (Fixed):
| Service | Tier | Monthly Cost (USD) |
|---|---|---|
| EC2 t3.xlarge (Dokploy) | 4 vCPU, 16GB, 100GB SSD | $130 |
| S3 (assets + PDFs + backups) | 100GB | $5 |
| Cloudflare Pro | DNS + CDN + SSL | $20 |
| Total Infrastructure | ~$155/mo |
Unit Economics @ 100 Clients:
| Metric | Value |
|---|---|
| Total monthly cost | ~$625 |
| Per-client cost | ~$6.25 |
| ARPU (Average Revenue Per User) | Rs 8,000 (~$95) |
| Gross margin | ~93% |
| API cost as % of revenue | ~5% |
| Infrastructure cost as % of revenue | ~1.6% |
Cost Alert Thresholds:
| Threshold | Action |
|---|---|
| > $50/day for practice | Notify admin; flag for review |
| > $500/month for practice | Throttle non-essential AI tasks; schedule client call |
| > $1,000/day system-wide | Throttle all non-essential tasks; emergency cost control |
| Per-practice monthly AI budget exceeded | Pause content generation; notify client of tier limit |
Performance Benchmarks:
| Operation | Target Duration | Measurement |
|---|---|---|
| Directory profile render | < 1.5s TTFB | Lighthouse |
| GBP post publish | < 30s | BullMQ job duration |
| Social post publish | < 30s | BullMQ job duration |
| Citation submission (batch) | < 15 min | Inngest workflow duration |
| Monthly report generation | < 3 min per client | Inngest workflow duration |
| AI content generation | < 5s (Haiku) / < 15s (Sonnet) | latencyMs in audit log |
| PDF generation | < 30s | Playwright render + S3 upload |
| Email delivery | < 10s | Resend API response time |
| Token refresh | < 5s per account | BullMQ job duration |
| NAP verification (full batch) | < 10 min | Firecrawl scrape × 30 citations |
End of Sections 5-6 — Business Process Flow Document
Section 7: Fail-Safe Conditions & Error Handling#
7.1 Job Failure Handling#
All background jobs are executed through either Inngest (durable workflows) or BullMQ (background job queue). Each job type has a defined retry policy, dead letter queue path, and admin notification trigger.
Retry Policy Registry#
| Job Type | Queue | Max Attempts | Backoff Strategy | Initial Delay | Max Delay | Timeout |
|---|---|---|---|---|---|---|
| Onboarding Pipeline | Inngest | 3 | Exponential | 5s | 60s | 10 min |
| Citation Builder | Inngest | 3 | Exponential | 5s | 60s | 15 min |
| Directory Profile Deploy | Inngest | 3 | Exponential | 5s | 60s | 2 min |
| GBP Post Publish | BullMQ | 3 | Exponential | 5s | 60s | 30 sec |
| Social Post Publish | BullMQ | 3 | Exponential | 10s | 120s | 30 sec |
| Review Monitor | BullMQ | 5 | Exponential | 60s | 300s | 2 min |
| NAP Consistency Check | BullMQ | 3 | Exponential | 300s | 900s | 10 min |
| Monthly Report | Inngest | 3 | Exponential | 5s | 60s | 3 min |
| Content Refresh | Inngest | 3 | Exponential | 5s | 60s | 15 min |
| Token Refresh | BullMQ | 5 | Exponential | 60s | 300s | 1 min |
| Email Send | BullMQ | 3 | Exponential | 5s | 30s | 10 sec |
| PDF Generate | BullMQ | 2 | Exponential | 10s | 30s | 30 sec |
| Citation Verify | Inngest | 3 | Exponential | 5s | 60s | 3 min |
| Profile Refresh | Inngest | 3 | Exponential | 5s | 60s | 10 min |
Exponential Backoff Formula#
Delay(n) = initialDelay × (2 ^ (attempt - 1)) + jitter
Jitter = random(0, 1000) ms
Example for GBP Post Publish (initial 5s):
- Attempt 1: 5s + jitter
- Attempt 2: 10s + jitter
- Attempt 3: 20s + jitter
Dead Letter Queue (DLQ)#
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Job │───→│ Retry 1 │───→│ Retry 2 │───→│ Retry 3 │
│ Fails │ │ (5s) │ │ (10s) │ │ (20s) │
└─────────────┘ └─────────────┘ └─────────────┘ └──────┬──────┘
│
▼
┌─────────────┐
│ Dead Letter│
│ Queue │
│ (Redis) │
└──────┬──────┘
│
▼
┌─────────────┐
│ Admin Email │
│ + Slack │
└─────────────┘
DLQ Schema:
| Field | Type | Description |
|---|---|---|
originalJobId |
string | Preserved from original queue |
payload |
JSON | Full job payload |
error |
string | Final error message |
stack |
string | Stack trace (truncated to 2000 chars) |
failedAt |
ISO8601 | Timestamp of final failure |
attemptsMade |
integer | Total attempts consumed |
Admin Notification on Job Failure#
| Severity | Condition | Channel | Recipients | Content |
|---|---|---|---|---|
| Critical | DLQ receives >10 jobs in 24h | Email + Slack #alerts | Admin team | Count, job types, last error |
| High | Any onboarding or token refresh fails | Email + Slack #alerts | Admin team | Practice ID, error, action needed |
| Medium | Single GBP/social post fails after retries | Slack #jobs | Ops team | Job ID, practice, error summary |
| Low | NAP check or profile refresh fails | Slack #jobs (batched hourly) | Ops team | Batch summary |
Manual Retry Capability#
From /admin/jobs, an admin can:
- View DLQ entries with full error context
- Click Retry — job is re-queued to original queue with same
jobId - Click Retry All — bulk retry up to 50 jobs at once
- Click Archive — move to
dlq_archivetable (retained 90 days) - Click Investigate — deep link to logs with
x-request-id
Idempotency Keys#
All jobs use deterministic IDs to prevent duplicate execution:
// Format: {practiceId}:{jobType}:{date|eventId}
const jobId = `${practiceId}:gbp-post:${new Date().toISOString().slice(0,10)}`;
| Job Category | Idempotency Key Pattern | Example |
|---|---|---|
| Daily/weekly recurring | {practiceId}:{type}:{YYYY-MM-DD} |
abc123:gbp-post:2026-06-12 |
| Monthly recurring | {practiceId}:{type}:{YYYY-MM} |
abc123:report:2026-06 |
| Event-driven | {practiceId}:{type}:{eventId} |
abc123:citation:evt_7x9k2 |
| One-time | {practiceId}:{type}:{timestamp} |
abc123:onboard:1718186400 |
Duplicate Prevention: If a job with the same jobId is already in the queue (waiting, active, delayed, or completed within last 1h), the new add operation is rejected with duplicate status.
7.2 API Rate Limit Protection#
GBP API Quota Tracking#
| Operation | Daily Limit | Per-Minute Limit | Redis Key Pattern | Alert At |
|---|---|---|---|---|
| Business information | 10,000 | 100 | gbp:quota:bizinfo:{accountId}:{date} |
80% daily |
| Posts | 500 | 30 | gbp:quota:posts:{accountId}:{date} |
80% daily |
| Reviews | 1,000 | 60 | gbp:quota:reviews:{accountId}:{date} |
80% daily |
| Photos | 1,000 | 60 | gbp:quota:photos:{accountId}:{date} |
80% daily |
| Insights | 500 | 30 | gbp:quota:insights:{accountId}:{date} |
80% daily |
| Q&A | 500 | 30 | gbp:quota:qa:{accountId}:{date} |
80% daily |
Implementation:
- Redis
INCRon every API call - Daily keys expire after 86400s
- Per-minute keys expire after 60s
- If quota exceeded, job is delayed to next available window
- Admin alert sent when any account hits 80% of daily quota
Social Platform Rate Limits#
| Platform | Limit | Window | Enforcement | Fallback |
|---|---|---|---|---|
| 25 publishes | per user / day | BullMQ limiter:max: 25, duration: 86400000 |
Queue for next day | |
| Facebook Pages | Per-page dynamic | per page / hour | Composio returns rate limit header; respect Retry-After |
Queue with Retry-After delay |
| 150 posts | per user / day | BullMQ limiter:max: 150, duration: 86400000 |
Queue for next day | |
| Twitter/X | 300 tweets | per user / day | BullMQ limiter:max: 300, duration: 86400000 |
Queue for next day |
AI API Cost Caps#
| Plan | Monthly AI Budget (USD) | Per-Task Cap | Alert At | Throttle At |
|---|---|---|---|---|
| Starter | $5.00 | $0.10 | 80% | 100% |
| Standard | $10.00 | $0.15 | 80% | 100% |
| Premium | $20.00 | $0.25 | 80% | 100% |
| Enterprise | $50.00 | $0.50 | 80% | 100% |
Cost Tracking:
- Every LLM call logs
cost_usdtoai_usagetable - Daily rollup per practice
- When 80% reached: email warning to client + admin
- When 100% reached: downgrade to OSS models (Llama 3) only
- Enterprise clients: admin approval required for overage
Circuit Breaker Pattern#
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ CLOSED │────→│ 5 failures │────→│ OPEN │────→│ 30s block │
│ (normal) │ │ in 60s │ │ (blocked) │ │ no requests│
└─────────────┘ └─────────────┘ └─────────────┘ └──────┬──────┘
│
▼
┌─────────────┐
│ HALF-OPEN │
│ (test req) │
└──────┬──────┘
│
┌─────────────────────────────────────┘
│ success
▼
┌─────────────┐
│ CLOSED │
│ (resume) │
└─────────────┘
| Parameter | Value | Description |
|---|---|---|
| Failure threshold | 5 failures | Triggers OPEN state |
| Time window | 60 seconds | Rolling window for failure count |
| Block duration | 30 seconds | All requests rejected |
| Half-open test | 1 request | If success → CLOSED; if fail → extend block 30s |
| Max block extension | 5 times | After 5 extensions, manual admin intervention required |
Applied to: GBP API, Composio API, Zernio API, Claude API, GPT-4 API.
Request Queue Throttling#
// BullMQ limiter config per queue
const limiters = {
gbpPostPublish: { max: 30, duration: 60000 }, // 30/min
socialPostPublish: { max: 25, duration: 60000 }, // 25/min
reviewMonitor: { max: 60, duration: 60000 }, // 60/min
citationSubmit: { max: 10, duration: 60000 }, // 10/min
tokenRefresh: { max: 10, duration: 60000 }, // 10/min
};
7.3 GBP Suspension Prevention#
GBP suspension is the single highest operational risk. The following safeguards are mandatory and non-configurable.
Activity Frequency Guardrails#
| Metric | Limit | Enforcement | Violation Action |
|---|---|---|---|
| Posts per location / week | Max 3 | Hard cap in scheduler | Job rejected, admin alerted |
| Posts per location / day | Max 1 | Hard cap in scheduler | Job rejected |
| Review replies per location / day | Max 10 | Hard cap | Queue overflow to next day |
| Photos per location / week | Max 5 | Hard cap | Job rejected |
| Q&A answers per location / week | Max 5 | Hard cap | Job rejected |
Content Uniqueness Enforcement#
┌─────────────────────────────────────────────────────────────┐
│ Content Uniqueness Pipeline │
│ │
│ AI Generated Content │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Per-Client │───→│ Cross-Acc │───→│ Similarity │ │
│ │ Hash │ │ Deduplicate│ │ Check │ │
│ │ (SHA-256) │ │ (Redis) │ │ (< 80%) │ │
│ └─────────────┘ └─────────────┘ └──────┬──────┘ │
│ │ │
│ ┌────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ PASS → │ │
│ │ Publish │ │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ FAIL → │ │
│ │ Regenerate │ │
│ │ (max 3x) │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Rules:
- No two posts across any two accounts may have >80% text similarity (Levenshtein distance)
- Each post must contain at least 3 unique tokens not present in the last 10 posts for that vertical
- Hashtag sets must differ by at least 40% across accounts
- Image prompts must be unique per post (no stock image reuse)
Gradual Activity Ramp for New Clients#
| Client Age | Max Posts/Week | Max Social Posts/Week | Citation Batch Size |
|---|---|---|---|
| Week 1 | 1 | 1 | 10 (pilot batch) |
| Week 2 | 2 | 2 | 10 (second batch) |
| Week 3 | 3 | 3 | 10 (final batch) |
| Week 4+ | 3 | 4 | All 30 maintained |
Rationale: Sudden burst activity from a new GBP account is a known suspension trigger.
Proxy Rotation for API Calls#
| Parameter | Value |
|---|---|
| Proxy pool size | 50 residential proxies |
| Rotation trigger | Every 10 API calls per account |
| Proxy provider | Bright Data / Oxylabs |
| IP geolocation | Match client city (e.g., Kochi → Kerala IP) |
| Failed proxy retry | 3 attempts with different proxy before hard fail |
Emergency Stop Button#
// System-wide emergency stop
async function emergencyStop(reason: string, practiceId?: string) {
if (practiceId) {
// Per-client stop
await db.gbpAccount.updateMany({
where: { practiceId },
data: { isActive: false, emergencyStoppedAt: new Date(), emergencyStopReason: reason }
});
} else {
// System-wide stop
await db.gbpAccount.updateMany({
where: {},
data: { isActive: false, emergencyStoppedAt: new Date(), emergencyStopReason: reason }
});
}
// Pause all GBP queues
await queues.gbpPostPublish.pause();
await queues.reviewMonitor.pause();
// Cancel scheduled posts for next 24h
await cancelScheduledGbpPosts(practiceId, 24);
// Notify
await notifyEmergencyStop(reason, practiceId);
}
Activation Triggers:
| Trigger | Auto-Stop | Admin Alert | Client Alert |
|---|---|---|---|
| Admin clicks "Emergency Stop" | Yes | Yes | Yes (if per-client) |
| Suspension warning detected in GBP API response | Yes | Yes | Yes |
| >3 accounts receive 403 errors in 1 hour | Yes | Yes | No |
| Google policy update detected | Yes | Yes | No |
Resume Procedure:
- Admin reviews reason and confirms resolution
- Admin clicks "Resume GBP Activity" in dashboard
- System re-enables account with 48h gradual ramp
- All paused posts are rescheduled with new timestamps
Suspension Warning Monitoring#
| Signal | Detection Method | Action |
|---|---|---|
403 Forbidden with ACCOUNT_SUSPENDED |
GBP API error parsing | Immediate emergency stop + admin alert |
429 with RATE_LIMITED + unusual pattern |
Response header analysis | Pause 24h, investigate |
| Review reply rejected with policy violation | Response body parsing | Stop review replies for account |
Post rejected with CONTENT_POLICY_VIOLATION |
Response body parsing | Stop posts, queue for human review |
| Unusual traffic pattern from Google | Proxy logs | Alert, investigate |
7.4 Token Expiry & Refresh#
Automatic Token Refresh#
| Token Type | Expiry | Refresh Trigger | Refresh Window | Storage |
|---|---|---|---|---|
| GBP access_token | 1 hour | 24 hours before expiry | Daily cron at 3:00 AM IST | AES-256-GCM encrypted |
| GBP refresh_token | 6 months (if unused) | 30 days before expiry | Weekly | AES-256-GCM encrypted |
| Meta (Composio) | 60 days | 7 days before expiry | Daily | AES-256-GCM encrypted |
| LinkedIn (Composio) | 60 days | 7 days before expiry | Daily | AES-256-GCM encrypted |
| Twitter (Composio) | 60 days | 7 days before expiry | Daily | AES-256-GCM encrypted |
Daily Token Health Check Cron#
0 3 * * * (Daily at 3:00 AM IST)
│
├─→ Query all tokens with expiry < 24h
├─→ For each token:
│ ├─→ Attempt refresh
│ ├─→ If success: update DB, log success
│ ├─→ If fail (1st attempt): retry in 1h
│ ├─→ If fail (2nd attempt): retry in 4h
│ └─→ If fail (3rd attempt): alert admin + mark for re-auth
│
└─→ Generate daily token health report
Alert on Refresh Failure#
| Attempt | Action | Channel | Escalation |
|---|---|---|---|
| 1st failure | Retry in 1h | Log only | None |
| 2nd failure | Retry in 4h | Slack #tokens | Ops team |
| 3rd failure | Mark NEEDS_REAUTH |
Email + Slack #alerts | Admin + Client |
Graceful Degradation When Tokens Expire#
| Service | Degraded Behavior | Client Impact | Recovery |
|---|---|---|---|
| GBP | Posts queue but don't publish; reviews monitored but not replied | Missed posts, manual review replies | Re-auth → auto-catchup |
| Posts queue but don't publish | Missed posts | Re-auth → manual reschedule | |
| Posts queue but don't publish | Missed posts | Re-auth → manual reschedule | |
| Posts queue but don't publish | Missed posts | Re-auth → manual reschedule | |
| Posts queue but don't publish | Missed posts | Re-auth → manual reschedule |
Customer Re-Auth Prompt#
┌─────────────────────────────────────────────────────────────┐
│ 🔐 Re-Authentication Required │
│ │
│ Your [Google Business / Instagram / Facebook] connection │
│ has expired. To continue automated posting and review │
│ replies, please reconnect: │
│ │
│ [Reconnect Google Business] [Reconnect Instagram] │
│ │
│ What happens if you don't reconnect: │
│ • GBP posts will pause until reconnected │
│ • Review auto-replies will pause │
│ • Your rankings may decline over time │
│ │
│ Need help? Call us: +91-XXXX-XXXXXX │
└─────────────────────────────────────────────────────────────┘
Delivery: Email (immediate) + In-app banner (persistent) + WhatsApp (if connected).
7.5 Content Quality Gates#
AI Content Review Queue (Medical Clients)#
All content for medical clients (type = CLINIC, HOSPITAL, DOCTOR) enters a 24-hour approval window.
┌─────────────┐ ┌─────────────────┐ ┌─────────────┐ ┌─────────────┐
│ AI │───→│ PENDING_REVIEW │───→│ 24h Timer │───→│ AUTO_PUBLISH│
│ Generates │ │ (24h window) │ │ (countdown)│ │ (if no │
│ Content │ │ │ │ │ │ action) │
└─────────────┘ └────────┬────────┘ └─────────────┘ └─────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ APPROVE │ │ REJECT │ │ EDIT │
│→Publish │ │→Regen │ │→Requeue │
└─────────┘ └─────────┘ └─────────┘
| Content Type | Auto-Approve | 24h Auto-Publish | Medical Gate | Non-Medical |
|---|---|---|---|---|
| GBP Posts | No | Yes | Yes | Yes |
| Social Posts | No | Yes | Yes | Yes |
| Directory Profile Articles | No | No (requires explicit approval) | Yes | No |
| FAQ Blocks | No | No (requires explicit approval) | Yes | No |
| Review Replies (5★) | Yes | N/A | No | N/A |
| Review Replies (4★) | Yes | N/A | No | N/A |
| Review Replies (3★) | No | No (manual only) | Yes | N/A |
| Review Replies (1-2★) | No | No (manual only) | Yes | N/A |
| Citation Descriptions | No | Yes | Yes | Yes |
Sentiment-Gated Review Replies#
| Star Rating | AI Reply Generated | Auto-Reply | Approval Required | Auto-Approve Window |
|---|---|---|---|---|
| 5 stars | Yes | Yes | No | Immediate |
| 4 stars | Yes | Yes | No | Immediate |
| 3 stars | Yes | No | Yes | 24 hours |
| 2 stars | Yes | No | Yes | Manual only (no auto) |
| 1 star | Yes | No | Yes | Manual only (no auto) |
Negative Review Workflow:
- Review received → AI generates empathetic, professional reply
- Reply queued in
/dashboard/reviewswith "Pending Approval" badge - Client receives email: "New negative review requires your attention"
- Client can: Approve (publishes immediately), Edit (saves draft), Reject (AI regenerates with feedback), or Write own reply
- If no action in 24h (3★) or 72h (1-2★): Admin is alerted to intervene
Fact-Checking Layer for Medical Claims#
| Claim Type | Detection | Action | Examples |
|---|---|---|---|
| Treatment outcomes | Regex + AI classifier | Flag for review | "100% success rate", "guaranteed cure" |
| Drug recommendations | Medical NER model | Block + alert | "Take aspirin for..." |
| Specialist credentials | Cross-reference with input data | Flag if mismatch | "Board-certified cardiologist" (if not in profile) |
| Prohibited terms | Blocklist match | Block + regenerate | "best", "top", "#1", "miracle" |
| Pricing in posts | Regex | Flag for review | "Rs 500 consultation" |
Blocklist (medical advertising compliance — India):
- "best doctor in [city]"
- "guaranteed results"
- "100% success"
- "no side effects"
- "miracle treatment"
- "cure all diseases"
Template-Based Generation with Constraints#
All AI content is generated from versioned prompt templates stored in the database:
| Template | Constraints | Max Length | Output Format |
|---|---|---|---|
gbp_post_medical |
No claims, empathetic tone, CTA only | 1500 chars | Plain text + CTA |
review_reply_positive |
Thankful, brief, no medical advice | 300 chars | Plain text |
review_reply_negative |
Empathetic, offer resolution, no defense | 500 chars | Plain text |
citation_description |
Unique per site, NAP accurate, no fluff | 500 chars | Structured JSON |
directory_profile_article |
Keyword-rich, factual, schema-ready | 1500 words | Markdown + HTML |
faq_block |
Q&A format, no diagnosis, general info | 10 Q&A pairs | JSON-LD FAQ schema |
Human Review for First Month#
| Client Age | Review Level | Approver |
|---|---|---|
| Days 1-7 | All content | Admin team (100% review) |
| Days 8-14 | All GBP + social posts | Admin team (100% review) |
| Days 15-30 | All GBP posts + negative review replies | Admin team (spot check 50%) |
| Month 2+ | Negative review replies only | Client self-serve |
Content Rejection Workflow#
┌─────────────────────────────────────────────────────────────┐
│ Content Rejection Flow │
│ │
│ Reject Action │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Select │ │
│ │ Reason: │ │
│ │ • Factually│ │
│ │ incorrect│ │
│ │ • Tone │ │
│ │ inappropriate│ │
│ │ • Violates │ │
│ │ policy │ │
│ │ • Custom │ │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Log Reason │───→│ AI Regen │───→│ Re-queue │ │
│ │ + Feedback │ │ (max 3x) │ │ for Review │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │
│ ┌───────────────┘ │
│ │ (if 3x fail) │
│ ▼ │
│ ┌─────────────┐ │
│ │ Escalate │ │
│ │ to Human │ │
│ │ Writer │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
7.6 Emergency Stop Procedures#
GBP Emergency Stop#
| Scope | Trigger | Action | Recovery |
|---|---|---|---|
| Per-client | Admin clicks, suspension warning, or client request | Pause all GBP jobs for practice; cancel next 24h of scheduled posts | Admin manual resume with 48h ramp |
| System-wide | >3 accounts hit 403 in 1h, Google policy update, legal directive | Pause ALL GBP jobs; cancel ALL scheduled posts; notify all clients | Admin manual resume with 72h ramp |
Social Posting Pause#
| Scope | Trigger | Action | Recovery |
|---|---|---|---|
| Per-platform | Rate limit sustained >1h, platform policy change | Pause queue for that platform only | Auto-resume when rate limit clears |
| Per-client | Client request, payment failure | Pause all social for client | Manual resume from admin |
| System-wide | Composio outage, major platform API change | Pause all social queues | Manual resume after verification |
Citation Submission Halt#
| Trigger | Action | Recovery |
|---|---|---|
| Directory site down (detected via health check) | Pause submissions to that directory only | Auto-resume when site returns 200 |
| CAPTCHA solve rate <50% | Pause form-based submissions, alert admin | Manual resume after CAPTCHA provider fix |
| NAP mismatch spike (>20% of citations) | Pause new submissions, investigate | Resume after root cause resolved |
AI Generation Throttle#
| Trigger | Action | Recovery |
|---|---|---|
| AI API cost >$50/day system-wide | Switch all non-critical tasks to OSS models | Auto-resume when daily cost < $40 |
| AI API latency >30s per request | Add 5s delay between requests, reduce concurrency | Auto-resume when latency <10s |
| AI provider outage (Claude or GPT-4) | Route all traffic to fallback provider | Auto-resume when primary returns |
Admin Notification Cascade#
Event Detected
│
▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Immediate │───→│ 5 min │───→│ 15 min │
│ Slack │ │ Email │ │ SMS to │
│ #alerts │ │ admin team │ │ on-call │
└─────────────┘ └─────────────┘ └─────────────┘
│
▼
┌─────────────┐
│ 30 min │
│ Phone call │
│ (critical) │
└─────────────┘
| Severity | Channels | Response Time |
|---|---|---|
| Critical (system-wide stop) | Slack + Email + SMS + Phone | 5 minutes |
| High (per-client stop) | Slack + Email | 15 minutes |
| Medium (queue pause) | Slack | 1 hour |
| Low (throttle) | Slack (batched) | 4 hours |
7.7 Data Integrity Safeguards#
Database Transaction Wrapping#
All multi-table mutations are wrapped in Prisma transactions:
| Operation | Tables Involved | Transaction Level | Rollback On |
|---|---|---|---|
| Onboarding | User, Practice, Location, Subscription | Serializable | Any step failure |
| Citation batch | Citation (×30), JobLog | Read Committed | >5 failures |
| Content publish | ContentPiece, ScheduledPost, AuditLog | Read Committed | Publish failure |
| Plan change | Subscription, Invoice, Practice | Serializable | Payment failure |
| Cancellation | Practice, Citation, SocialAccount, GBPAccount | Serializable | Any step failure |
NAP Snapshot Storage for Rollback#
Every citation stores a napSnapshot JSON at time of creation:
{
"name": "Dr. Smith Dental Clinic",
"address": "123 MG Road, Kochi, Kerala 682016",
"phone": "+91-98765-43210",
"email": "contact@drsmithdental.com",
"website": "https://directory.com/clinics/kochi/drsmith",
"category": "Dentist",
"hours": "Mon-Sat 9:00-18:00",
"capturedAt": "2026-06-01T08:30:00Z"
}
Retention: 1 year post-cancellation (DPDPA compliance). Use: If NAP is corrupted during update, restore from last snapshot.
Citation URL Backup Before Deletion#
| Field | Stored | Purpose |
|---|---|---|
directoryUrl |
S3 archive | Proof of prior existence |
screenshotUrl |
S3 (permanent) | Visual proof of listing |
napSnapshot |
DB (1 year) | Rollback data |
submissionResponse |
DB (90 days) | API response audit |
Directory Profile Version History#
| Version | Trigger | Retention |
|---|---|---|
| v1 (initial) | Onboarding publish | Permanent |
| v2+ (monthly refresh) | Content regeneration | Last 12 versions |
| Rollback | Admin action | Any previous version restorable |
Schema:
model DirectoryProfileVersion {
id String @id @default(cuid())
directoryProfileId String
version Int
content Json
schema Json
publishedAt DateTime
publishedBy String // "ai" or "admin:{userId}"
rollbackTarget Boolean @default(false)
}
Audit Log of All Changes#
Every create, update, delete operation is logged:
| Action | Entity | Old Value | New Value | Actor | IP | Timestamp |
|---|---|---|---|---|---|---|
| UPDATE | Practice | {name: "Old"} |
{name: "New"} |
user_abc | 1.2.3.4 | 2026-06-12T06:00:00Z |
| DELETE | Citation | {url: "..."} |
null |
system | — | 2026-06-12T06:00:00Z |
| CREATE | GBPAccount | null |
{email: "..."} |
user_abc | 1.2.3.4 | 2026-06-12T06:00:00Z |
Retention: 7 years (Indian tax/compliance requirement).
Query: /admin/audit-logs with filters by practice, user, action, date range.
Soft Delete (Not Hard Delete)#
| Entity | Soft Delete Field | Hard Delete After | Reason |
|---|---|---|---|
| Practice | deletedAt, status: CANCELLED |
1 year | DPDPA + recovery |
| User | deletedAt |
1 year | DPDPA + recovery |
| Citation | status: REMOVED |
90 days | Rollback possible |
| ContentPiece | status: ARCHIVED |
1 year | Version history |
| Review | reviewerName: [REDACTED], comment: [REDACTED] |
Never | Anonymized only |
| Invoice | Never deleted | Never | Tax compliance |
| AuditLog | Never deleted | 7 years | Compliance |
Recovery Process:
- Admin searches
/admin/deletedfor soft-deleted practices - Clicks "Restore" → confirmation dialog
- System restores: Practice → Locations → Citation URLs (if <90 days) → Directory profile (if directory URL available)
- Client re-auths GBP/social if tokens expired
- Full recovery within 24h
Section 8: Cancellation & Offboarding Flow#
8.1 Cancellation Triggers#
┌─────────────────────────────────────────────────────────────┐
│ Cancellation Triggers │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Customer │ │ Payment │ │ Terms of │ │
│ │ Initiated │ │ Failure │ │ Service │ │
│ │ (portal) │ │ (3 retries)│ │ Violation │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┴────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Admin │ │
│ │ Suspension │ │
│ │ (fraud) │ │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Status: │ │
│ │ CANCELLING │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
| Trigger | Detection | Immediate Action | Notification |
|---|---|---|---|
| Customer-initiated | Client clicks "Cancel" in /dashboard/settings |
Status →CANCELLING |
Email confirmation to client |
| Payment failure | Stripe/Razorpay webhook payment_failed |
Retry 1 (immediate) | Email to client |
| Payment failure (2nd) | Retry 2 (Day 3) | Retry 2 | Email to client |
| Payment failure (3rd) | Retry 3 (Day 7) | Status →CANCELLING |
Email + SMS to client |
| Terms of service violation | Admin flags (fake business, spam, illegal activity) | Status →SUSPENDED |
Email to client with reason |
| Admin-initiated suspension | Admin clicks "Suspend" with reason | Status →SUSPENDED |
Email to client |
8.2 Grace Period & Retention Attempts#
7-Day Grace Period Timeline#
Day 0 (Cancellation Triggered)
│
├─→ Status: CANCELLING
├─→ All services CONTINUE running
├─→ Retention email #1 sent immediately
├─→ Downgrade offer presented in dashboard
│
Day 1
├─→ Retention email #1 follow-up (if not opened)
├─→ Pause option highlighted
│
Day 3
├─→ Retention email #2 sent
├─→ Personal call scheduled for high-value clients (Premium/Enterprise)
│
Day 5
├─→ Retention email #3 (final offer)
├─→ Exit survey link included
│
Day 7 (End of Grace Period)
├─→ Status: CANCELLED
├─→ Decommissioning begins
└─→ Final invoice generated (prorated if applicable)
Retention Email Sequence#
| Day | Subject | Content | CTA | Target |
|---|---|---|---|---|
| 0 | "We're sorry to see you go — can we help?" | Acknowledge cancellation, offer support call | "Schedule a Call" | All cancelling |
| 1 | "Your rankings are still climbing" | Show last 30 days of improvement | "Stay and Save 20%" | All cancelling |
| 3 | "A smaller plan might be perfect for you" | Downgrade options with feature comparison | "Switch to Starter" | Standard+ |
| 5 | "Before you go: your SEO results" | Full performance report, what they'll lose | "Pause Instead" | All cancelling |
Downgrade Offer#
| Current Plan | Downgrade To | Discount | Lock-in |
|---|---|---|---|
| Enterprise (Rs 20K) | Premium (Rs 12K) | 25% off first month | None |
| Premium (Rs 12K) | Standard (Rs 8K) | 25% off first month | None |
| Standard (Rs 8K) | Starter (Rs 4K) | 25% off first month | None |
| Starter (Rs 4K) | — | Annual billing (2 months free) | 12 months |
Pause Option#
| Parameter | Value |
|---|---|
| Max pause duration | 30 days |
| Pause cost | Rs 500 (retainer) |
| Services paused | All posting, citation building, content refresh |
| Services continued | Directory profile hosting, NAP monitoring, review monitoring (no replies) |
| Reactivation | One-click in dashboard or auto-resume after 30 days |
| Max pauses per year | 2 |
Exit Survey#
| Question | Type | Purpose |
|---|---|---|
| "Why are you leaving?" | Select: Too expensive, Not seeing results, Found alternative, Business closed, Other | Churn categorization |
| "How satisfied were you with..." | 1-5 scale: Results, Support, Dashboard, Reports | NPS component |
| "What would have kept you?" | Free text | Product insight |
| "Can we contact you in 3 months?" | Yes/No | Win-back permission |
8.3 Data & Asset Decommissioning#
Decommissioning Schedule#
| Day | Action | System | Impact |
|---|---|---|---|
| 0 | Directory profile unpublish | Cloudflare DNS + Next.js | 404 on directory URL/directory profile URL |
| 0 | Directory URL release | Cloudflare API | Directory URL available for reassignment |
| 0 | Custom domain DNS removal | Cloudflare API | CNAME record deleted |
| 0 | Social account disconnection | Composio API + DB | Tokens revoked, connections deleted |
| 0 | GBP token revocation | Google OAuth revoke | Access removed, refresh token invalidated |
| 1 | Citation deletion begins | Submission engine | 30 directories queued for removal |
| 3 | Social/GBP activity stops | Job scheduler | No new posts scheduled |
| 7 | Citation deletion complete | Submission engine | All 30 citations removed |
| 7 | NAP data removal from blogs | Owned blog DB | Client pages deleted, SSG re-render |
| 7 | Final report generated | Report engine | Exportable PDF + JSON |
| 30 | Soft delete data purge | DB cron | Non-essential data anonymized |
| 365 | Hard delete eligible | Admin action | Full removal after DPDPA retention |
Directory Profile Unpublish (Day 0)#
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Status: │───→│ Cloudflare │───→│ Next.js │───→│ S3 Assets │
│ CANCELLED │ │ DNS Delete │ │ ISR Purge │ │ Archive │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
| Asset | Action | Retention |
|---|---|---|
| Directory URL DNS | Delete A/CNAME record | — |
| Custom domain DNS | Delete CNAME, notify client | — |
| Next.js page | Purge from ISR cache | — |
| S3 assets (images) | Move to archive/{practiceId}/ |
90 days |
| Page content versions | Mark isActive: false |
1 year |
Directory URL Release#
| Step | Action | Verification |
|---|---|---|
| 1 | Remove single domain DNS entry | dig confirms NXDOMAIN |
| 2 | Mark directory URL available: true in DB |
Admin dashboard shows released |
| 3 | 30-day quarantine before reassignment | Prevents accidental reuse |
| 4 | SSL cert removed from Cloudflare | Certificate list updated |
Directory Profile URL DNS Removal#
| Step | Action | Client Communication |
|---|---|---|
| 1 | Delete CNAME from Cloudflare | — |
| 2 | Email client: "Remove CNAME from your registrar" | Instructions + screenshot |
| 3 | 7-day grace for client to point elsewhere | — |
| 4 | After 7 days: mark domain released |
— |
Social Account Disconnection#
| Platform | Action | Token Handling |
|---|---|---|
| Revoke Composio connection | Access token deleted from DB | |
| Revoke Composio connection | Access token deleted from DB | |
| Revoke Composio connection | Access token deleted from DB | |
| Twitter/X | Revoke Composio connection | Access token deleted from DB |
GBP Token Revocation#
| Step | Action | Verification |
|---|---|---|
| 1 | Call Google revokeToken endpoint |
HTTP 200 confirmed |
| 2 | Delete accessToken + refreshToken from DB | DB query confirms null |
| 3 | Mark GBP account isActive: false |
Dashboard shows disconnected |
| 4 | Cancel all pending GBP posts | Queue depth = 0 for practice |
8.4 Citation Removal Process#
Citation Deletion from 30 Directories#
┌─────────────────────────────────────────────────────────────┐
│ Citation Removal Pipeline (Day 1-7) │
│ │
│ For each of 30 directories: │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ API-based │ │ Form-based │ │ Owned Blog │ │
│ │ (Practo, │ │ (Justdial, │ │ (Direct │ │
│ │ Yelp) │ │ Sulekha) │ │ DB delete) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Call │ │ Browser │ │ DELETE │ │
│ │ DELETE │ │ automation │ │ FROM DB │ │
│ │ endpoint │ │ + CAPTCHA │ │ + SSG │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └──────────────────┴──────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Screenshot │ │
│ │ proof of │ │
│ │ removal │ │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Update DB │ │
│ │ status: │ │
│ │ REMOVED │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
| Directory Type | Deletion Method | Success Rate | Screenshot |
|---|---|---|---|
| API-based | Direct DELETE request | 95% | 404 confirmation |
| Form-based | Browser automation (Hyperbrowser) | 70% | "Listing removed" page |
| Owned blog | Direct DB delete + SSG re-render | 100% | Before/after comparison |
| Email-based | Manual email request | 60% | Reply confirmation |
NAP Data Removal from Owned Blog Sites#
| Step | Action | Verification |
|---|---|---|
| 1 | Delete client profile page from owned blog DB | SELECT returns 0 rows |
| 2 | Trigger SSG re-render for affected site | Build completes successfully |
| 3 | Verify 404 on old URL | HTTP status = 404 |
| 4 | Update sitemap.xml | Client URL absent |
| 5 | Submit updated sitemap to Google | Search Console confirmation |
Directory Listing Takedown Requests#
For directories that don't support automated deletion:
| Directory | Takedown Method | SLA | Contact |
|---|---|---|---|
| Justdial | Support ticket + email | 7 days | support@justdial.com |
| Sulekha | Email request | 14 days | support@sulekha.com |
| IndiaMART | Account dashboard | 3 days | Self-serve |
| Lybrate | Email + phone | 7 days | support@lybrate.com |
Screenshot Proof of Removal#
| Requirement | Implementation |
|---|---|
| Every deletion attempt | Screenshot captured via Hyperbrowser |
| Success confirmation | Screenshot of "removed" or 404 page |
| Failure documentation | Screenshot of error + reason logged |
| Storage | S3 citations/{practiceId}/removal/{directory}.png |
| Retention | 1 year |
Removal Completion Report#
Generated automatically when all 30 citations are processed:
| Section | Content |
|---|---|
| Summary | Removed: X, Failed: Y, Pending: Z |
| Per-Directory Table | Directory, Status, Screenshot URL, Date |
| Failed Items | Reason, Retry plan, Manual action needed |
| NAP Consistency | Final scan results |
| Client Confirmation | "Your citations have been removed" email |
8.5 Final Report & Export#
Final Performance Report#
| Metric | Included | Source |
|---|---|---|
| Overall SEO score | Yes | Last monthly report |
| GBP performance trend | Yes | 6-month history |
| Citation count over time | Yes | Monthly snapshots |
| Review score trend | Yes | Monthly snapshots |
| Social activity summary | Yes | Lifetime totals |
| Ranking positions | Yes | Last known positions |
| ROI calculation | Yes | (Revenue attributed / Cost) |
Data Export (DPDPA Compliance)#
| Data Category | Format | Included | Excluded |
|---|---|---|---|
| Practice profile | JSON | Name, address, phone, category, hours | Internal IDs |
| Locations | JSON | All location data | — |
| GBP accounts | JSON | Account email, connected date | Tokens (revoked) |
| Social accounts | JSON | Platform, handle, connected date | Tokens (revoked) |
| Citations | CSV | Directory, URL, status, dates | Submission credentials |
| Content pieces | JSON | All generated content | AI cost data |
| Reviews | CSV | Rating, comment, reply, date | Reviewer names (anonymized) |
| Reports | PDF links | All monthly reports | — |
| Jobs | CSV | Type, status, dates | Internal error logs |
| Audit logs | CSV | Last 90 days | System internals |
| Invoices | All invoices | — |
Export Delivery:
- ZIP file generated via background job
- Uploaded to S3 with presigned URL (7-day expiry)
- Email sent to client with download link
- Admin notified of export completion
Citation List Export#
| Field | Description |
|---|---|
directory_name |
e.g., "Justdial" |
directory_url |
Live URL at time of cancellation |
status |
SUBMITTED, VERIFIED, REMOVED |
submitted_at |
ISO timestamp |
removed_at |
ISO timestamp (if applicable) |
screenshot_url |
S3 link to proof |
Review History Export#
| Field | Description |
|---|---|
rating |
1-5 stars |
comment |
Review text (anonymized if exported post-cancellation) |
reply_text |
AI or manual reply |
review_date |
ISO timestamp |
replied_at |
ISO timestamp |
platform |
GBP, Practo, etc. |
Account Closure Confirmation#
┌─────────────────────────────────────────────────────────────┐
│ ✅ Your RankFlow AI Account Has Been Closed │
│ │
│ Account: Dr. Smith Dental Clinic │
│ Closed on: 12 June 2026 │
│ │
│ What we've done: │
│ • All 30 citations removed from directories │
│ • Directory profile taken offline │
│ • Social accounts disconnected │
│ • GBP access revoked │
│ │
│ Your data export: │
│ • Download link (expires in 7 days): [Download ZIP] │
│ │
│ Reactivate anytime: │
│ • Your data is retained for 1 year │
│ • Reactivation takes 24-48 hours │
│ • [Reactivate My Account] │
│ │
│ Questions? Reply to this email or call +91-XXXX-XXXXXX │
└─────────────────────────────────────────────────────────────┘
Section 9: Tool & Feature Gap Analysis#
9.1 Current Tool Inventory#
| Category | Tool/Feature | Technology | Status | Docs |
|---|---|---|---|---|
| Core Platform | Next.js 14+ App Router | React, TypeScript | ✅ Built | scope_brief_extracted.txt |
| tRPC API Layer | Type-safe RPC | ✅ Built | research_technical_v3.md |
|
| Prisma ORM | PostgreSQL | ✅ Built | scope_brief_extracted.txt |
|
| Better Auth + RBAC | Credentials + OAuth | ✅ Built | docs/security-compliance.md |
|
| Client Dashboard | 13 pages | ✅ Built | scope_brief_extracted.txt |
|
| Admin Dashboard | 9 pages | ✅ Built | scope_brief_extracted.txt |
|
| AI Engine | Multi-LLM Router | Claude + GPT-4 + Llama/Mistral | ✅ Built | scope_brief_extracted.txt |
| Prompt Template System | DB-stored, versioned | ✅ Built | scope_brief_extracted.txt |
|
| Content Generation | 6 task types | ✅ Built | scope_brief_extracted.txt |
|
| Schema Generation | JSON-LD (LocalBusiness, etc.) | ✅ Built | scope_brief_extracted.txt |
|
| Directory Profile | SSG / ISR | Next.js middleware | ✅ Built | scope_brief_extracted.txt |
| Single Domain DNS | directory.com |
✅ Built | docs/infrastructure-devops.md |
|
| Directory Profile URL | CNAME + SSL | ✅ Built | scope_brief_extracted.txt |
|
| 3-5 Templates | Vertical-specific | ✅ Built | scope_brief_extracted.txt |
|
| GBP Pipeline | OAuth 2.0 Flow | Google OAuth | ✅ Built | docs/gbp-social-pipeline.md |
| Post Scheduler | 2-3x/week | ✅ Built | docs/job-queue-workflows.md |
|
| Review Monitor | Daily poll | ✅ Built | docs/gbp-social-pipeline.md |
|
| Auto-Reply | Sentiment-gated | ✅ Built | docs/gbp-social-pipeline.md |
|
| Insights Fetch | Daily metrics | ✅ Built | docs/gbp-social-pipeline.md |
|
| Token Refresh | 24h before expiry | ✅ Built | docs/gbp-social-pipeline.md |
|
| Social Integration | Composio Auth | Meta OAuth | ✅ Built | docs/gbp-social-pipeline.md |
| Zernio Scheduling | Batch API | ✅ Built | docs/gbp-social-pipeline.md |
|
| 25 posts/day | ✅ Built | docs/gbp-social-pipeline.md |
||
| Per-page limits | ✅ Built | docs/gbp-social-pipeline.md |
||
| 150 posts/day | ✅ Built | docs/gbp-social-pipeline.md |
||
| Twitter/X | 300 tweets/day | ✅ Built | docs/gbp-social-pipeline.md |
|
| Citation Network | 30-Site Network | 25 directories + 5 blogs | ✅ Built | docs/citation-network.md |
| Submission Engine | API + Form + Browser | ✅ Built | docs/citation-network.md |
|
| NAP Monitor | Monthly crawl | ✅ Built | docs/citation-network.md |
|
| Owned Blog Sites | 5 niche sites | ✅ Built | docs/citation-network.md |
|
| Screenshot Proof | S3 storage | ✅ Built | docs/citation-network.md |
|
| Reporting | Monthly PDF Report | Playwright + A4 | ✅ Built | docs/email-reports-pdf.md |
| Weekly Digest Email | Top 3 stats | ✅ Built | docs/email-reports-pdf.md |
|
| Alert Emails | Event-driven | ✅ Built | docs/email-reports-pdf.md |
|
| Email Tracking | Resend webhooks | ✅ Built | docs/email-reports-pdf.md |
|
| Billing | Stripe | International cards | ✅ Built | scope_brief_extracted.txt |
| Razorpay | India UPI/cards | ✅ Built | scope_brief_extracted.txt |
|
| 4 Plans | Starter/Standard/Premium/Enterprise | ✅ Built | scope_brief_extracted.txt |
|
| Subscription Lifecycle | Trial → Active → Past_due → Cancelled | ✅ Built | scope_brief_extracted.txt |
|
| GST Invoicing | PDF invoice | ✅ Built | scope_brief_extracted.txt |
|
| Job Queue | Inngest | Durable workflows | ✅ Built | docs/job-queue-workflows.md |
| BullMQ | Background jobs | ✅ Built | docs/job-queue-workflows.md |
|
| Redis | Cache + Queue | ✅ Built | docs/infrastructure-devops.md |
|
| Dead Letter Queue | Failed job archive | ✅ Built | docs/job-queue-workflows.md |
|
| Scheduled Jobs | Cron patterns | ✅ Built | docs/job-queue-workflows.md |
|
| Security | AES-256-GCM Encryption | At-rest tokens | ✅ Built | docs/security-compliance.md |
| RBAC | ADMIN/CLIENT/EDITOR/VIEWER | ✅ Built | docs/security-compliance.md |
|
| DPDPA 2023 | Consent, export, deletion | ✅ Built | docs/security-compliance.md |
|
| Audit Logging | 7-year retention | ✅ Built | docs/security-compliance.md |
|
| Rate Limiting | Per-route limits | ✅ Built | docs/security-compliance.md |
|
| Input Validation | Zod + DOMPurify | ✅ Built | docs/security-compliance.md |
9.2 Missing Tools / Features#
Gap analysis against the objective: "Getting local businesses to higher ranking."
| # | Missing Feature | Gap Severity | Why It Matters | Impact on Ranking | Effort |
|---|---|---|---|---|---|
| 1 | Competitor Rank Tracking | 🔴 Critical | Can't measure relative position without knowing who you're competing against | High — informs strategy | Medium |
| 2 | Keyword Research Tool | 🔴 Critical | Clients don't know what patients search for; AI content may target wrong terms | High — drives all content | Medium |
| 3 | Backlink Monitoring | 🟡 High | Citation network is only one backlink source; missing organic link growth | Medium — authority signal | Medium |
| 4 | Website Audit Scanner | 🟡 High | Directory profile may have technical SEO issues (speed, mobile, broken links) | Medium — Core Web Vitals | Low |
| 5 | Google Search Console Integration | 🔴 Critical | Only GSC shows actual search queries, impressions, CTR | High — real search data | Medium |
| 6 | Google Analytics Integration | 🟡 High | Landing profile views data is essential for ROI proof | Medium — traffic validation | Low |
| 7 | Call Tracking | 🟡 High | Medical clients live on phone calls; can't prove ROI without call data | High — conversion proof | Medium |
| 8 | Appointment Booking Integration | 🟡 High | "Book Now" is the ultimate CTA; missing for medical vertical | High — conversion rate | Medium |
| 9 | SMS Notifications | 🟢 Medium | Urgent alerts (negative review, suspension warning) need instant delivery | Low — UX improvement | Low |
| 10 | WhatsApp Business Integration | 🟡 High | India = WhatsApp-first; patients expect WhatsApp booking | High — local relevance | Medium |
| 11 | Vernacular Language QA | 🟡 High | Malayalam/Tamil AI output quality is uneven; no human QA layer | Medium — local trust | Medium |
| 12 | White-Label Agency Portal | 🟡 High | Real scale = 10 agencies × 10 clients; no white-label = direct sales bottleneck | High — distribution | High |
| 13 | API for Third-Party Integrations | 🟢 Medium | CRMs, practice management software want to push data to RankFlow | Low — ecosystem | High |
| 14 | Mobile App | 🟢 Medium | Doctors check phones, not laptops; dashboard is desktop-only | Low — convenience | High |
| 15 | Chrome Extension for Quick GBP Updates | 🟢 Medium | Quick post/reply without logging into dashboard | Low — power user | Medium |
9.3 Future Enhancement Roadmap#
2026 ──────────────────────────────────────────────────────────────►
Phase 1: CORE (Months 1-3) [████████████] NOW
├─ 30 citations + GBP + Social
├─ Directory profile + DNS
├─ AI engine + job queue
├─ Billing + reporting
└─ 10 beta clients (Kerala)
Phase 2: SCALE (Months 4-6) [ ] Month 4-6
├─ White-label agency portal
├─ Competitor rank tracking
├─ Google Search Console integration
├─ Keyword research tool
├─ 50 paying clients (South India)
└─ Referral partner program
Phase 3: MOBILE & CONVERSION (Months 7-9) [ ] Month 7-9
├─ Mobile app (React Native)
├─ Call tracking (Twilio)
├─ WhatsApp Business integration
├─ Appointment booking (Calendly/native)
├─ Vernacular language QA layer
├─ 100+ clients (PAN India)
└─ AI engine optimization (GEO)
Phase 4: PLATFORM (Months 10-12) [ ] Month 10-12
├─ Public API platform
├─ Marketplace (app store for SEO tools)
├─ AI chatbot (patient-facing)
├─ Chrome extension
├─ 500-client runway
├─ Rs 12L+ MRR target
└─ API for third-party integrations
| Phase | Timeline | Key Deliverables | Success Criteria |
|---|---|---|---|
| Phase 1 | Now | Core platform + 30 citations + GBP + Social + Billing | 10 beta clients active, <5% churn |
| Phase 2 | Month 4-6 | White-label, competitor tracking, GSC integration, keyword research | 50 paying clients, 2 agency partners |
| Phase 3 | Month 7-9 | Mobile app, call tracking, WhatsApp, booking, vernacular QA | 100+ clients, 50% mobile usage |
| Phase 4 | Month 10-12 | API platform, marketplace, AI chatbot, Chrome extension | 500-client runway, Rs 12L MRR |
9.4 Integration Wishlist#
| Integration | Purpose | Priority | Phase | API Status | Complexity |
|---|---|---|---|---|---|
| Practo API | Medical vertical — profile sync, appointment data, reviews | 🔴 Critical | Phase 1 | Limited public API; may need scraping | High |
| Google Search Console API | Real search query data, impression/CTR, index status | 🔴 Critical | Phase 2 | Stable, well-documented | Medium |
| Google Analytics 4 API | Landing profile views, user behavior, conversion events | 🟡 High | Phase 2 | Stable | Low |
| Meta Business Suite API | Direct posting (bypass Composio), deeper insights | 🟡 High | Phase 2 | Stable but complex permissions | Medium |
| WhatsApp Business API | Patient communication, booking confirmations, alerts | 🟡 High | Phase 3 | Requires Meta Business verification | Medium |
| Twilio | SMS alerts, call tracking, phone number provisioning | 🟡 High | Phase 3 | Stable, India-supported | Medium |
| Calendly / Native Booking | Appointment scheduling embedded in directory profile | 🟡 High | Phase 3 | Calendly API stable; native = high effort | Medium |
| HubSpot CRM | Lead sync, deal tracking, marketing automation | 🟢 Medium | Phase 4 | Excellent API | Low |
| Zoho CRM | India-popular CRM integration | 🟢 Medium | Phase 4 | Good API | Low |
| Practo / Lybrate / 1mg | Indian medical directory APIs (if available) | 🟡 High | Phase 1-2 | Fragmented; mostly scraping | High |
| Justdial API | Business listing management | 🟢 Medium | Phase 2 | Limited; form-based preferred | High |
| Sulekha API | Service directory management | 🟢 Medium | Phase 2 | Limited | High |
Section 10: Appendix — Touchpoint Matrix#
Complete Lifecycle Touchpoint Registry (50+ Touchpoints)#
| # | Touchpoint | Actor | Frequency | Channel | Trigger | Success Criteria | Failure Handling |
|---|---|---|---|---|---|---|---|
| 1 | Directory profile visit | Prospect | One-time | Web | Ad / organic / referral | Page load <2s, CTA click | Retargeting pixel fires |
| 2 | Pricing page view | Prospect | One-time | Web | Navigation | Time on page >30s | Exit-intent popup |
| 3 | Signup form submit | Prospect | One-time | Web | CTA click | Valid email, no duplicate | Inline validation + error message |
| 4 | Welcome email | System | One-time | Account creation | Delivered, opened | Retry in 4h; alert if bounced | |
| 5 | Onboarding form — Business info | Client | One-time | Web | Welcome email CTA | All required fields valid | Save draft, email reminder Day 1, 3 |
| 6 | Onboarding form — GBP OAuth | Client | One-time | Web | Step 5 of onboarding | Token received, account linked | Video guide + support call offer |
| 7 | Onboarding form — Social connect | Client | One-time | Web | Optional step | Connection ID stored | Skip allowed, reminder later |
| 8 | Onboarding completion | System | One-time | Internal | All steps done | Status:ONBOARDED |
Escalate to admin if stuck >7d |
| 9 | AI content generation | System | One-time | Internal | Onboarding complete | 30 citations + LP content in <60s | Retry 3x; fallback to OSS models |
| 10 | Citation submission (batch 1) | System | One-time | Internal | Content ready | 10 citations submitted | Retry per directory; log failures |
| 11 | Citation submission (batch 2) | System | One-time | Internal | Day 3 | 10 citations submitted | Retry per directory |
| 12 | Citation submission (batch 3) | System | One-time | Internal | Day 5 | 10 citations submitted | Retry per directory |
| 13 | Directory profile publish | System | One-time | Internal | Content ready | Live at directory URL, 200 OK | DNS retry, admin alert |
| 14 | First GBP post | System | One-time | Internal | GBP OAuth complete | Published, post ID stored | Queue for next day if quota exceeded |
| 15 | Welcome report email | System | One-time | Day 1 post-onboarding | Delivered with PDF | Retry 3x; manual send if fail | |
| 16 | Weekly GBP post | System | 2-3x/week | API | Cron (Mon/Wed/Fri 9AM) | Published, client notified | Queue for next slot; alert if 3 fails |
| 17 | Weekly social post | System | 2-4x/week | API | Cron schedule | Published, external post ID stored | Queue for next day; fallback to manual |
| 18 | Daily review monitor | System | Daily | API | Cron (8AM) | New reviews fetched, replies queued | Retry 5x; alert if fail |
| 19 | Positive review auto-reply | System | Event-driven | API | 4-5 star review detected | Reply published within 5 min | Queue for manual if fail |
| 20 | Negative review approval request | System | Event-driven | Email + Dashboard | 1-3 star review detected | Client notified within 10 min | SMS fallback if email unopened 1h |
| 21 | Negative review reply publish | Client | Event-driven | Dashboard | Client clicks "Approve" | Reply published, status updated | Reminder email at 24h, 72h |
| 22 | Content approval request | System | Event-driven | Email + Dashboard | AI content generated (medical) | Client sees pending content | Auto-publish at 24h if no action |
| 23 | Content approval action | Client | Event-driven | Dashboard | Client approves/rejects | Status updated, published or regenerated | Admin notified if rejected 3x |
| 24 | Monthly NAP consistency check | System | Monthly | Internal | Cron (1st of month 2AM) | All 30 citations scanned | Retry 3x; alert mismatches |
| 25 | NAP mismatch alert | System | Event-driven | Email + Slack | Mismatch detected | Admin sees alert with details | Escalate if >20% mismatches |
| 26 | Monthly report generation | System | Monthly | Internal | Cron (1st of month 4AM) | PDF generated, data gathered | Retry 3x; manual generation if fail |
| 27 | Monthly report email | System | Monthly | Report ready | Delivered with PDF attachment | Retry 3x; dashboard notification | |
| 28 | Weekly digest email | System | Weekly | Cron (Monday 8AM) | Delivered, 3 stats shown | Batched with monthly if fail | |
| 29 | GBP position drop alert | System | Event-driven | Email + Dashboard | Rank falls >5 positions | Client + admin notified | Admin investigates within 4h |
| 30 | Citation removed alert | System | Event-driven | Email + Dashboard | NAP check returns NOT_FOUND | Client + admin notified | Auto-resubmission queued |
| 31 | Token expiry warning | System | Event-driven | Email + Dashboard | Token expires in <7 days | Client sees re-auth banner | SMS + WhatsApp fallback |
| 32 | Token refresh failure | System | Event-driven | Email + Slack | Refresh fails 3x | Admin + client notified | Manual re-auth required |
| 33 | Subscription invoice | System | Monthly | Stripe/Razorpay cron | Delivered with PDF | Retry 3x; dashboard notification | |
| 34 | Payment success | System | Event-driven | Webhook received | Receipt delivered | Log only | |
| 35 | Payment failure (1st retry) | System | Event-driven | Webhook received | Client notified, retry scheduled | — | |
| 36 | Payment failure (2nd retry) | System | Event-driven | Email + SMS | Day 3 | Client notified | Support call triggered for Premium+ |
| 37 | Payment failure (3rd retry) | System | Event-driven | Email + SMS | Day 7 | Cancellation triggered | Retention sequence activated |
| 38 | Plan upgrade | Client | Event-driven | Web | Client clicks "Upgrade" | Prorated charge, features enabled | Support chat if payment fails |
| 39 | Plan downgrade | Client | Event-driven | Web | Client clicks "Downgrade" | Effective next billing cycle | Confirmation email |
| 40 | Cancellation initiation | Client | Event-driven | Web | Client clicks "Cancel" | Status →CANCELLING |
Retention sequence Day 0 |
| 41 | Retention email (Day 1) | System | Event-driven | Cancellation triggered | Opened or clicked | — | |
| 42 | Retention email (Day 3) | System | Event-driven | Day 3 | Opened or clicked | Support call for Premium+ | |
| 43 | Retention email (Day 5) | System | Event-driven | Day 5 | Opened or clicked | Final offer | |
| 44 | Pause subscription | Client | Event-driven | Web | Client clicks "Pause" | Status →PAUSED, Rs 500 charge |
Confirmation email |
| 45 | Exit survey | Client | One-time | Web | Day 5 or post-cancellation | Submitted | Optional, no penalty |
| 46 | Decommissioning start | System | One-time | Internal | Day 7 post-cancellation | Directory profile 404, DNS removed | Admin alert if any step fails |
| 47 | Citation removal (batch) | System | One-time | Internal | Day 1-7 | Screenshot proof per directory | Retry 3x; manual fallback |
| 48 | Final report & export | System | One-time | Internal | Day 7 | ZIP generated, email sent | Manual generation if fail |
| 49 | Account closure confirmation | System | One-time | Day 7 | Delivered with reactivation link | — | |
| 50 | Data deletion (DPDPA) | System | One-time | Internal | Day 365 post-cancellation | Hard delete eligible data | Audit log retained 7 years |
| 51 | Admin daily summary | System | Daily | Email + Slack | Cron (9AM) | KPIs, failed jobs, new signups | — |
| 52 | Admin job failure alert | System | Event-driven | Slack | Job fails after max retries | Error context, retry link | PagerDuty if >10 in 24h |
| 53 | Admin API cost alert | System | Event-driven | Email + Slack | Daily cost >$50 | Breakdown by provider | Throttle AI if sustained |
| 54 | Admin GBP suspension warning | System | Event-driven | Slack + SMS | Suspension signal detected | Immediate emergency stop | Phone call if system-wide |
| 55 | Client support ticket | Client | On-demand | Email / Chat / Phone | Client initiates | Response <4h (Standard), <1h (Premium) | Escalation rules |
| 56 | Client dashboard login | Client | Daily/Weekly | Web | Manual | Session valid, data loads <2s | Password reset flow |
| 57 | Client profile update | Client | On-demand | Web | Form submit | Changes saved, audit logged | Validation errors inline |
| 58 | Client reactivation | Client | One-time | Web | Clicks reactivation link | Status →REACTIVATING |
Support call if >90 days |
| 59 | Emergency stop activation | Admin | On-demand | Dashboard | Admin clicks button | All GBP activity paused | Confirmation modal required |
| 60 | Emergency stop resume | Admin | On-demand | Dashboard | Admin clicks resume | Gradual ramp over 48h | Monitoring alert if issues |
Touchpoint Frequency Summary#
| Frequency | Count | Touchpoints |
|---|---|---|
| Real-time / Event-driven | 24 | #9-10, 12-14, 16-23, 29-34, 37-42, 45, 47-49, 52-54, 56-58 |
| Daily | 4 | #18, 31, 51, 56 |
| Weekly | 3 | #16-17, 28 |
| Monthly | 5 | #24, 26-27, 33, 56 |
| One-time (lifecycle) | 16 | #1-8, 11, 15, 40, 43-46, 48, 50, 58 |
| On-demand | 8 | #38-39, 41, 44, 55, 57, 59-60 |
End of Business Process Flow Document — Sections 7-10
Section 11: Addendum — Directory Profile System 2.0#
Reference: For the full technical specification, see
/docs/directory-profile-plan.md(57 KB, 7 sections). This addendum provides the business process integration points.
11.1 The Four New Capabilities#
| # | Capability | What Changed | Impact |
|---|---|---|---|
| 1 | Structured Media Onboarding | Logo + photos + copy collected in dedicated Step 2b | Sites are personalized, not generic |
| 2 | Composable Design System | 8 layouts × 12 palettes × 8 typography × 12 sections = 9,216+ unique combinations | Every client gets a unique site |
| 3 | AI Chat-Based Editor | Natural language editing: "make the button green", "change the heading" | No-code editing for non-technical clients |
| 4 | WordPress Plugin + JS Tag | External sites get schema, reviews, NAP sync, citation monitoring | Capture clients who already have websites |
11.2 Revised Onboarding Flow (Directory Profile Focus)#
Step 1: Account Creation & Plan Selection [C]
↓
Step 2: Business Profile Capture [C]
├── NAP data, services, hours, USPs
└── Logo + Photos upload (structured, required)
↓
Step 2b: DESIGN & MEDIA COLLECTION [C] ← NEW
├── Sub-step 2b.1: Brand Identity Upload
│ ├── Logo (required, 2MB, PNG/SVG/JPG)
│ ├── Hero Photo (optional, 5MB)
│ ├── Doctor Portrait (optional, 2MB)
│ ├── Clinic Photos (up to 5, 2MB each)
│ └── Team Photos (up to 3, 2MB each)
├── Sub-step 2b.2: Design Preferences
│ ├── Layout Engine (8 options, AI-suggested)
│ ├── Color Palette (12 options, AI from logo)
│ ├── Typography Pair (8 options)
│ ├── Section Selection (12 modules, toggleable)
│ └── Section Order (drag-and-drop)
└── Sub-step 2b.3: Copy & Tone Input
├── Tagline / Headline (10-80 chars)
├── About Us Story (100-500 chars)
├── USP / Differentiator (50-200 chars)
├── Tone of Voice (5 options)
└── Testimonials (up to 3, 100-300 chars each)
↓
Step 3: Consent & Terms Acceptance [C]
↓
Step 4: Payment Method Setup [C] + [S]
↓
Step 5: Directory URL Assignment [S]
↓
Step 6: Directory Profile Generation [S] ← REVISED
├── Uses Step 2b design preferences (layout, palette, typography)
├── Uses Step 2b uploaded photos (hero, portrait, clinic, team)
├── Uses Step 2b copy/tone (tagline, about, USP, testimonials)
├── AI generates content for selected sections (Claude Sonnet/Haiku)
├── Composable design system applies design tokens
├── Schema JSON-LD generated (LocalBusiness + Service + FAQ + Review)
└── Images processed (Sharp variants: webp, blur placeholder, OG)
↓
Step 7: Directory Profile Deployment [S]
├── SSG render with ISR (Next.js)
├── Cloudflare CDN cache (global)
└── Live at directory URL (< 2.5s LCP)
↓
Step 8: AI Chat Editor Preview [C] ← NEW
├── Client sees first preview
├── AI chat: "Would you like to change anything?"
├── Client can edit via natural language:
│ ├── "Change heading to 'Best Dental Clinic in Anna Nagar'"
│ ├── "Make the CTA button green"
│ ├── "Add a team section after about"
│ └── "Write a better about section mentioning my 15 years"
├── Edit commands: TEXT_EDIT, COLOR_EDIT, SECTION_ADD/REMOVE,
│ SECTION_REORDER, LAYOUT_CHANGE, TYPOGRAPHY_CHANGE,
│ IMAGE_UPLOAD, CONTENT_GENERATE
├── Undo/redo system (full history stack)
└── Final approval [C] → Deploy updated site
↓
Step 9: GBP OAuth Request [S] → [C]
... (remaining steps)
11.3 External Site Integration Path (New Onboarding Branch)#
Onboarding Step 2: Business Profile
↓
System asks: "Do you have an existing website?"
↓
┌────────────────────────┐ ┌────────────────────────┐ ┌────────────────────────┐
│ No website │ │ Yes, WordPress │ │ Yes, other platform │
│ (default) │ │ │ │ (Wix, custom, etc.) │
│ │ │ │ │ │
│ → Build on RankFlow │ │ → Install plugin │ │ → Add JS snippet │
│ → Full design system │ │ → Schema injection │ │ → Schema injection │
│ → AI editor │ │ → Review widget │ │ → Review widget │
│ → Full automation │ │ → NAP sync │ │ → NAP monitoring │
│ │ │ → Citation health │ │ → Analytics │
│ │ │ → Content sync │ │ │
└────────────────────────┘ └────────────────────────┘ └────────────────────────┘
11.4 Key Metrics for the New System#
| Metric | Target | Measurement |
|---|---|---|
| Directory profile uniqueness | > 95% | No two clients share same layout+palette+typography combo |
| Onboarding completion | > 80% | From signup to approved site |
| AI editor usage | > 60% | Clients who make at least 1 edit via chat |
| External site adoption | > 30% | Clients who connect existing site |
| WordPress plugin installs | > 100 (Month 6) | Active plugin connections |
| Image processing time | < 30s | From upload to all variants ready |
| Site generation time | < 90s | From Step 6 start to live preview |
| AI editor response time | < 3s | From chat message to preview update |
| LCP (Largest Contentful Paint) | < 2.5s | Core Web Vitals |
| CLS (Cumulative Layout Shift) | < 0.1 | Core Web Vitals |
11.5 What This Changes in the Existing Document#
| Existing Section | Change | New Reference |
|---|---|---|
| Step 2 (Business Profile) | Logo/Photos now REQUIRED and structured | §11.2 Step 2b.1 |
| Step 6 (Directory Profile Generation) | Now uses composable design system, not 5 fixed templates | §11.2 Step 6 |
| Step 7 (Directory Profile Deployment) | Now includes AI chat editor preview | §11.2 Step 8 |
| Section 5.8 (Directory Profile Automation) | Updated to include 8 layout engines, 12 palettes, 12 sections | §2 of directory-profile-plan.md |
| Section 9.2 (Missing Features) | AI chat editor, WordPress plugin, external site integration now PLANNED | §11.1 |
| Section 10 (Touchpoint Matrix) | Add: Step 2b, Step 8, External site path | §11.2, §11.3 |
End of Addendum: Directory Profile System 2.0
For full technical specification: See /docs/directory-profile-plan.md
For original 10 sections: See Sections 1-10 above