AI Services
RankFlow AI — Image Generation & Vernacular Content Strategy
Version: 2.0.0
docs/specs/ai/ai-services-05-image-vernacular.mdOn this page
- 1. Image Generation Strategy
- 1.1 Philosophy
- 1.2 Image Use Cases
- 1.3 Image Budget per Client per Month
- 2. Image Generation Pipeline
- 2.1 Pipeline Architecture
- 2.2 Image Generation Interface
- 3. DALL-E Integration
- 3.1 DALL-E 3 Configuration
- 3.2 DALL-E Prompt Engineering
- 3.3 DALL-E Safety & Moderation
- 4. Gemini Image Integration
- 4.1 Gemini Image Configuration
- 4.2 Gemini Use Cases
- 5. Image Quality & Review
- 5.1 Automated Image Review
- 5.2 Stock Image Fallback
- 6. Vernacular Content Strategy
- 6.1 Why Vernacular?
- 6.2 Supported Languages
- 6.3 Vernacular Content Types
- 7. Translation Pipeline
- 7.1 Translation Pipeline Architecture
- 7.2 Translation Interface
- 7.3 Batch Translation
- 8. Cultural Adaptation
- 8.1 Cultural Adaptation Framework
- 8.2 Cultural Adaptation Rules
- 9. Multilingual Content Management
- 9.1 Content Language Variants
- 9.2 Language Switching
- 9.3 Language-Specific GBP
- 10. Vernacular SEO
- 10.1 Vernacular Keyword Strategy
- 10.2 Vernacular SEO Implementation
- 10.3 Vernacular Content Calendar
- 11. Cost & Performance
- 11.1 Vernacular Content Cost per Client per Month
- 11.2 Image Generation Cost per Client per Month
- 11.3 Combined Vernacular + Image Cost
- 12. Database Schema
Version: 2.0.0 Date: 2026-06-16 Scope: Image generation pipeline, DALL-E/Gemini integration, vernacular translation strategy, cultural adaptation, and multilingual content management Target Audience: AI Engineers, Content Strategists, Designers, Product Team Service Path:
src/server/services/ai/images/,src/server/services/ai/vernacular/
1. Image Generation Strategy#
1.1 Philosophy#
Images are not an afterthought — they are a critical part of the content ecosystem. Every GBP post, social post, and landing page benefits from custom-generated imagery that matches the practice's brand identity.
1.2 Image Use Cases#
| # | Use Case | Platform | Frequency | AI Model | Cost/Image |
|---|---|---|---|---|---|
| 1 | GBP Post Images | Google Business | 2-3x/week | DALL-E 3 | ~$0.04 |
| 2 | Social Post Images | Instagram, FB, LI | 2-4x/week | DALL-E 3 | ~$0.04 |
| 3 | Landing Page Hero | Website | 1x (onboarding) | DALL-E 3 | ~$0.04 |
| 4 | Service Illustrations | Website | 1x (onboarding) | DALL-E 3 | ~$0.04 |
| 5 | Blog Post Featured | Blog | 2-3x/week | DALL-E 3 | ~$0.04 |
| 6 | Team/Facility Photos | Website | 1x (onboarding) | Gemini (existing photo enhancement) | ~$0.02 |
| 7 | Promotional Graphics | Social | 1-2x/month | DALL-E 3 | ~$0.04 |
| 8 | Seasonal/Holiday | Social, GBP | 4-5x/year | DALL-E 3 | ~$0.04 |
1.3 Image Budget per Client per Month#
| Plan | Images/Month | Cost/Month | ARPU | Image Cost % |
|---|---|---|---|---|
| Starter | 12 | ~$0.50 | $48 | ~1.0% |
| Growth | 36 | ~$1.50 | $144 | ~1.0% |
| Pro | 120 | ~$5.00 | $480 | ~1.0% |
2. Image Generation Pipeline#
2.1 Pipeline Architecture#
┌─────────────────────────────────────────────────────────────┐
│ IMAGE GENERATION PIPELINE │
│ │
│ Step 1: Image Prompt Generation (LLM) │
│ ├─ Input: Task type, practice context, image requirements │
│ ├─ Model: Claude Haiku (~$0.002) │
│ ├─ Output: Detailed image generation prompt │
│ └─ Includes: Style, subject, lighting, composition, mood │
│ │
│ Step 2: Prompt Enhancement (optional) │
│ ├─ Add brand color palette │
│ ├─ Add cultural context (Indian setting, local landmarks) │
│ ├─ Add diversity requirements (Indian patients, families) │
│ └─ Add negative prompt (what to avoid) │
│ │
│ Step 3: Image Generation (AI Image Model) │
│ ├─ Primary: DALL-E 3 (OpenAI) │
│ ├─ Fallback: Gemini Image (Google) │
│ ├─ Output: Image URL + metadata │
│ └─ Cost: ~$0.04 per image (1024x1024) │
│ │
│ Step 4: Quality Check │
│ ├─ Safety filter (NSFW, inappropriate content) │
│ ├─ Brand alignment check (color, style, subject) │
│ ├─ Cultural appropriateness check │
│ └─ If failed: Regenerate with adjusted prompt │
│ │
│ Step 5: Storage & CDN │
│ ├─ Upload to S3/R2 │
│ ├─ Generate CDN URL │
│ ├─ Generate thumbnail versions │
│ └─ Store metadata in database │
│ │
│ Step 6: Content Integration │
│ ├─ Attach to GBP post, social post, or web page │
│ ├─ Generate alt text (GPT-4o Mini, ~$0.001) │
│ └─ Update content with image URL │
│ │
│ Step 7: Audit & Logging │
│ ├─ Log image generation cost │
│ ├─ Log prompt and result │
│ └─ Track usage per practice │
└─────────────────────────────────────────────────────────────┘
2.2 Image Generation Interface#
// src/server/services/ai/images/types.ts
interface ImageGenerateRequest {
task: ImageTaskType; // "gbp_post", "social_post", "hero", "blog", etc.
practiceId: string;
// Image requirements
subject: string; // What the image should depict
style: ImageStyle; // "photorealistic", "illustration", "minimalist", "warm"
aspectRatio: AspectRatio; // "1:1", "4:5", "16:9", "1.91:1"
// Context
platform?: Platform; // "instagram", "facebook", "linkedin", "gbp", "website"
colorPalette?: string[]; // Brand colors to incorporate
includePeople?: boolean; // Whether to include people in the image
diversityNote?: string; // "Indian family", "diverse patients", "South Indian setting"
// Optional
existingImageUrl?: string; // For image-to-image generation (editing)
requestId: string;
userId?: string;
}
interface ImageGenerateResponse {
imageUrl: string; // CDN URL
thumbnailUrl: string; // Smaller version for previews
metadata: {
model: "dall-e-3" | "gemini";
size: string; // "1024x1024", "1024x1792", etc.
costUsd: number;
latencyMs: number;
prompt: string; // The actual prompt used
negativePrompt?: string;
revisionPrompt?: string; // If revised from initial
safetyCheck: "PASS" | "WARN" | "FAIL";
brandAlignment: "PASS" | "WARN" | "FAIL";
culturalCheck: "PASS" | "WARN" | "FAIL";
};
}
// Aspect ratios by platform:
const PLATFORM_ASPECT_RATIOS: Record<Platform, AspectRatio[]> = {
"instagram": ["1:1", "4:5"],
"facebook": ["1:1", "1.91:1"],
"linkedin": ["1.91:1", "1:1"],
"twitter": ["16:9", "1:1"],
"gbp": ["1:1", "4:3"],
"website": ["16:9", "4:3", "1:1"],
};
3. DALL-E Integration#
3.1 DALL-E 3 Configuration#
// src/server/services/ai/images/providers/dalle.ts
import { createOpenAI } from "@ai-sdk/openai";
import { generateImage } from "ai";
const openai = createOpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
export async function generateWithDalle(
prompt: string,
options: ImageOptions
): Promise<ImageResult> {
const startTime = Date.now();
const result = await generateImage({
model: openai.image("dall-e-3"),
prompt,
size: options.aspectRatio === "16:9" ? "1792x1024"
: options.aspectRatio === "9:16" ? "1024x1792"
: "1024x1024",
quality: "standard", // "standard" or "hd"
style: options.style === "photorealistic" ? "vivid" : "natural",
});
return {
imageUrl: result.url,
metadata: {
model: "dall-e-3",
size: result.size,
costUsd: 0.04, // Standard quality
latencyMs: Date.now() - startTime,
prompt,
},
};
}
// DALL-E 3 Pricing (as of 2026):
// Standard quality (1024x1024): $0.04 per image
// Standard quality (1024x1792, 1792x1024): $0.08 per image
// HD quality (1024x1024): $0.08 per image
// HD quality (1024x1792, 1792x1024): $0.12 per image
3.2 DALL-E Prompt Engineering#
DALL-E 3 works best with detailed, descriptive prompts. The prompt generation layer creates these automatically.
// Prompt enhancement for DALL-E 3:
function enhancePromptForDalle(basePrompt: string, context: ImageContext): string {
const enhancements = [
// Style enhancement
context.style === "photorealistic" ? "photorealistic, high-quality photograph, professional photography" : "",
context.style === "illustration" ? "flat vector illustration, clean lines, modern design" : "",
context.style === "warm" ? "warm lighting, inviting atmosphere, soft natural light" : "",
context.style === "minimalist" ? "minimalist design, clean composition, ample white space" : "",
// Cultural context
context.diversityNote ? `${context.diversityNote}, culturally appropriate setting` : "",
// Quality tags
"high resolution, detailed, professional",
// Negative space (avoid)
"no text, no watermark, no logo, no blurry areas",
];
return `${basePrompt}. ${enhancements.filter(Boolean).join(", ")}.`;
}
3.3 DALL-E Safety & Moderation#
// DALL-E has built-in safety filters, but we add an additional layer:
const IMAGE_SAFETY_CHECKS = [
// NSFW detection
"no_nudity",
"no_violence",
"no_gore",
"no_hate_symbols",
// Medical appropriateness
"no_medical_gore", // No graphic medical images
"no_misleading_medical", // No images that suggest unproven treatments
// Cultural appropriateness
"no_stereotypes",
"no_cultural_appropriation",
// Brand safety
"no_competitor_logos",
"no_misleading_imagery",
];
// If DALL-E rejects a prompt (safety violation):
// 1. Log the rejection with prompt and reason
// 2. Adjust the prompt to remove problematic elements
// 3. Retry with revised prompt (max 2 attempts)
// 4. If still failing: Use stock image fallback
4. Gemini Image Integration#
4.1 Gemini Image Configuration#
Gemini is used as a fallback and for specific use cases like image editing and existing photo enhancement.
// src/server/services/ai/images/providers/gemini.ts
import { createGoogleGenerativeAI } from "@ai-sdk/google";
import { generateImage } from "ai";
const google = createGoogleGenerativeAI({
apiKey: process.env.GOOGLE_API_KEY,
});
export async function generateWithGemini(
prompt: string,
options: ImageOptions
): Promise<ImageResult> {
const startTime = Date.now();
const result = await generateImage({
model: google.image("gemini-2.5-flash"),
prompt,
size: options.aspectRatio === "16:9" ? "1024x576" : "1024x1024",
});
return {
imageUrl: result.url,
metadata: {
model: "gemini-2.5-flash",
size: result.size,
costUsd: 0.02, // Estimated cost
latencyMs: Date.now() - startTime,
prompt,
},
};
}
4.2 Gemini Use Cases#
| Use Case | Why Gemini | Example |
|---|---|---|
| Image Editing | Can edit existing images | "Add a holiday banner to this clinic photo" |
| Photo Enhancement | Can improve existing photos | "Make this photo brighter and more professional" |
| Long Prompt Understanding | Better at complex prompts | "A busy dental clinic with 5 Indian patients, a female dentist in white coat, modern equipment, warm lighting, Kochi city view through window" |
| Fallback | When DALL-E is unavailable | Same prompt, different model |
5. Image Quality & Review#
5.1 Automated Image Review#
// After generation, images are reviewed automatically:
interface ImageReviewResult {
safety: "PASS" | "WARN" | "FAIL";
brandAlignment: "PASS" | "WARN" | "FAIL";
culturalAppropriateness: "PASS" | "WARN" | "FAIL";
quality: "PASS" | "WARN" | "FAIL";
issues: string[];
suggestedPromptChanges?: string;
}
// Review checks:
// 1. Safety: Use AWS Rekognition or Google Vision API for NSFW detection
// 2. Brand Alignment: Check if image colors match brand palette (color histogram analysis)
// 3. Cultural Appropriateness: Check for cultural stereotypes or inappropriate depictions
// 4. Quality: Check resolution, blur, artifacts (OpenCV/image processing)
// If any check FAILs:
// - Image is rejected
// - Prompt is adjusted based on issues
// - Regeneration is triggered (max 2 attempts)
// - If still failing: Use stock image from Unsplash/Pexels (free, safe)
5.2 Stock Image Fallback#
If AI image generation fails after 2 attempts, the system falls back to stock images:
// Stock image fallback:
const STOCK_IMAGE_SOURCES = [
"unsplash", // Free, high quality, API available
"pexels", // Free, high quality, API available
"pixabay", // Free, large library
];
// Search query construction:
// "dental clinic interior" + "Kochi" + "India" + "modern" + "professional"
// If no relevant stock image found:
// - Use a generic category image (e.g., "healthcare" or "dental")
// - Log the failure for admin review
// - Alert admin to upload a custom image
6. Vernacular Content Strategy#
6.1 Why Vernacular?#
For Indian practices (especially in Kerala, Tamil Nadu, Karnataka, etc.), a significant portion of the target audience prefers content in their local language. Vernacular content is not just translation — it's cultural adaptation.
6.2 Supported Languages#
| Language | Code | Script | Primary Regions | Priority |
|---|---|---|---|---|
| Malayalam | ml |
Malayalam | Kerala | High |
| Tamil | ta |
Tamil | Tamil Nadu | High |
| Hindi | hi |
Devanagari | North India | High |
| Telugu | te |
Telugu | Andhra Pradesh, Telangana | Medium |
| Kannada | kn |
Kannada | Karnataka | Medium |
| Gujarati | gu |
Gujarati | Gujarat | Low |
| Marathi | mr |
Devanagari | Maharashtra | Low |
| Bengali | bn |
Bengali | West Bengal | Low |
6.3 Vernacular Content Types#
| Content Type | Malayalam | Tamil | Hindi | Frequency |
|---|---|---|---|---|
| Landing Page (Hero) | ✅ | ✅ | ✅ | Onboarding |
| Landing Page (About) | ✅ | ✅ | ✅ | Onboarding |
| Landing Page (Services) | ✅ | ✅ | ✅ | Onboarding |
| Landing Page (FAQ) | ✅ | ✅ | ✅ | Onboarding |
| GBP Posts | ✅ | ✅ | ✅ | 1-2x/month |
| Social Posts | ✅ | ✅ | ✅ | 1-2x/month |
| Blog Posts | ✅ | ✅ | ✅ | 1x/month |
| Citation Descriptions | ✅ | ✅ | ✅ | Onboarding |
| Review Replies | ✅ | ✅ | ✅ | As needed |
| Email Content | ✅ | ✅ | ✅ | As needed |
7. Translation Pipeline#
7.1 Translation Pipeline Architecture#
┌─────────────────────────────────────────────────────────────┐
│ TRANSLATION PIPELINE │
│ │
│ Step 1: Source Content Preparation │
│ ├─ Extract content from source (landing page, post, etc.) │
│ ├─ Identify translatable text (not URLs, phone numbers) │
│ ├─ Preserve formatting markers ({{variable}}, markdown) │
│ └─ Segment into translation units (paragraphs, sentences) │
│ │
│ Step 2: Translation (LLM) │
│ ├─ Model: Claude Sonnet (best for nuanced translation) │
│ ├─ Input: Source text + context + cultural notes │
│ ├─ Output: Translated text in target language │
│ └─ Cost: ~$0.008 per 1000 words (~$0.01 per page) │
│ │
│ Step 3: Post-Translation Processing │
│ ├─ Re-insert formatting markers │
│ ├─ Verify variable substitution ({{practiceName}} stays) │
│ ├─ Check for mixed script (ensure all target script) │
│ └─ Normalize whitespace and punctuation │
│ │
│ Step 4: Quality Evaluation │
│ ├─ Back-translation check (translate back to English) │
│ ├─ Cultural appropriateness check │
│ ├─ Readability check (sentence length, complexity) │
│ └─ Brand voice consistency check │
│ │
│ Step 5: Human Review (optional) │
│ ├─ For medical content: Mandatory human review │
│ ├─ For marketing content: Spot-check by native speaker │
│ └─ For social posts: Admin approval │
│ │
│ Step 6: Publishing │
│ ├─ Store translated content in database │
│ ├─ Update content record with language variant │
│ ├─ Generate URL with language prefix (/ml/, /ta/, /hi/) │
│ └─ Add hreflang tags for SEO │
│ │
│ Step 7: Audit & Logging │
│ ├─ Log translation cost │
│ ├─ Log quality scores │
│ └─ Track per-language usage │
└─────────────────────────────────────────────────────────────┘
7.2 Translation Interface#
// src/server/services/ai/vernacular/types.ts
interface TranslateRequest {
content: string; // Source content (English)
targetLanguage: LanguageCode; // "ml", "ta", "hi", etc.
contentType: ContentType; // "landing_page", "social_post", "blog", etc.
practiceId: string;
// Context
preserveFormatting: boolean; // Keep markdown, HTML, variables
includeCulturalNotes: boolean; // Add cultural context to translation
requestId: string;
}
interface TranslateResponse {
translatedContent: string;
sourceLanguage: "en";
targetLanguage: LanguageCode;
metadata: {
model: string; // "claude-sonnet"
costUsd: number;
latencyMs: number;
wordCount: number;
characterCount: number;
quality: {
backTranslationScore: number; // 0-100 (how close back-translation is to source)
culturalScore: number; // 0-100 (cultural appropriateness)
readabilityScore: number; // 0-100 (target language readability)
};
humanReviewRequired: boolean;
humanReviewStatus?: "pending" | "approved" | "rejected";
};
}
// Language codes
const LANGUAGE_CODES: Record<LanguageCode, LanguageInfo> = {
"ml": { name: "Malayalam", script: "Malayalam", regions: ["Kerala"], formalityDefault: "formal" },
"ta": { name: "Tamil", script: "Tamil", regions: ["Tamil Nadu"], formalityDefault: "formal" },
"hi": { name: "Hindi", script: "Devanagari", regions: ["North India"], formalityDefault: "formal" },
"te": { name: "Telugu", script: "Telugu", regions: ["Andhra Pradesh", "Telangana"], formalityDefault: "formal" },
"kn": { name: "Kannada", script: "Kannada", regions: ["Karnataka"], formalityDefault: "formal" },
};
7.3 Batch Translation#
For bulk content (e.g., onboarding a new client with 5 landing page sections in 3 languages):
// Batch translation saves cost by grouping content:
// Instead of 15 individual API calls (5 sections × 3 languages):
// → 3 batch calls (1 per language, all sections in one prompt)
// Cost savings: ~40% (fewer system prompts, fewer API calls)
interface BatchTranslateRequest {
items: {
id: string;
content: string;
contentType: ContentType;
}[];
targetLanguage: LanguageCode;
practiceId: string;
}
// Batch prompt:
// "Translate the following 5 sections into Malayalam.
// Preserve all formatting and variables.
// Section 1: [content]
// Section 2: [content]
// ..."
8. Cultural Adaptation#
8.1 Cultural Adaptation Framework#
Translation is not enough. Content must be culturally adapted for the target audience.
| Aspect | English (Default) | Malayalam Adaptation | Tamil Adaptation | Hindi Adaptation |
|---|---|---|---|---|
| Formality | Semi-formal | Formal (ningal) | Formal (ningal) | Formal (aap) |
| Tone | Warm | Respectful warmth | Respectful warmth | Professional warmth |
| Family Reference | "Your family" | "Kudumbam" (കുടുംബം) | "Kudumbam" (குடும்பம்) | "Parivar" (परिवार) |
| Greetings | "Hello" | "Namaskaram" (നമസ്കാരം) | "Vanakkam" (வணக்கம்) | "Namaste" (नमस्ते) |
| Local Landmarks | "MG Road" | "MG Road / Lulu Mall" | "T Nagar / Marina Beach" | "Connaught Place" |
| Festivals | "Holiday" | "Onam, Vishu" | "Pongal, Tamil New Year" | "Diwali, Holi" |
| Food References | "Healthy diet" | "Sadya, coconut oil" | "Idli, sambar" | "Roti, dal" |
| Medical Terms | "Root canal" | "Root canal / മൂലദന്തചികിത്സ" | "Root canal / மூலக் காரணம்" | "Root canal / मूल दांत चिकित्सा" |
| Trust Building | "Since 2015" | "2015 മുതൽ Kochi-യിൽ വിശ്വസ്തർ" | "2015 முதல் Kochi-யில் நம்பகமானவர்கள்" | "2015 से Kochi में विश्वसनीय" |
8.2 Cultural Adaptation Rules#
// Cultural adaptation is applied during translation:
const CULTURAL_RULES: Record<LanguageCode, CulturalRule[]> = {
"ml": [
{ type: "formality", rule: "Use 'നിങ്ങൾ' (ningal) for patients, 'താങ്കൾ' (thangal) for elderly" },
{ type: "reference", rule: "Reference Kerala culture: Onam, Vishu, monsoon season" },
{ type: "tone", rule: "Warm but respectful, family-centric" },
{ type: "medical", rule: "Use Malayalam medical terms where common, English where standard" },
],
"ta": [
{ type: "formality", rule: "Use 'நீங்கள்' (ningal) for formal, 'நீ' (nee) for casual" },
{ type: "reference", rule: "Reference Tamil culture: Pongal, Jallikattu, Tamil New Year" },
{ type: "tone", rule: "Respectful and warm, community-oriented" },
{ type: "medical", rule: "Use Tamil medical terms where common" },
],
"hi": [
{ type: "formality", rule: "Use 'आप' (aap) for formal, 'तुम' (tum) for semi-formal" },
{ type: "reference", rule: "Reference North Indian culture: Diwali, Holi, family values" },
{ type: "tone", rule: "Professional but warm, hierarchical respect" },
{ type: "medical", rule: "Use Hindi medical terms where widely understood" },
],
};
9. Multilingual Content Management#
9.1 Content Language Variants#
Every piece of content can exist in multiple language variants:
// Content language variant model:
interface ContentVariant {
id: string;
contentId: string; // Parent content (English = default)
language: LanguageCode; // "en", "ml", "ta", "hi"
content: string; // Translated content
status: "draft" | "pending_review" | "approved" | "published";
// Translation metadata
translatedBy: "ai" | "human" | "hybrid";
translatorId?: string; // User ID if human-translated
// Quality
qualityScore: number;
backTranslationScore: number;
culturalScore: number;
// Review
reviewedBy?: string;
reviewedAt?: Date;
// SEO
slug: string; // Language-specific URL slug
metaTitle: string;
metaDescription: string;
createdAt: Date;
updatedAt: Date;
}
// Default language is always English (en)
// All other languages are variants linked to the English parent
9.2 Language Switching#
// URL structure for multilingual content:
// English (default): /dr-smith-dental/
// Malayalam: /ml/dr-smith-dental/
// Tamil: /ta/dr-smith-dental/
// Hindi: /hi/dr-smith-dental/
// Language switching logic:
// 1. User visits /dr-smith-dental/ (English default)
// 2. If user has language preference cookie → redirect to /{lang}/
// 3. If browser language is Malayalam → show /ml/ version
// 4. If content not available in that language → show English with "Available in English" banner
// 5. User can manually switch language via language selector
// Hreflang tags for SEO:
// <link rel="alternate" hreflang="en" href="https://rankflow.ai/dr-smith-dental/" />
// <link rel="alternate" hreflang="ml" href="https://rankflow.ai/ml/dr-smith-dental/" />
// <link rel="alternate" hreflang="ta" href="https://rankflow.ai/ta/dr-smith-dental/" />
// <link rel="alternate" hreflang="x-default" href="https://rankflow.ai/dr-smith-dental/" />
9.3 Language-Specific GBP#
// Google Business Profile supports multilingual posts:
// - Primary language: English
// - Secondary languages: Malayalam, Tamil, Hindi (if available)
// GBP multilingual strategy:
// 1. Primary GBP listing: English (default)
// 2. Posts: English + 1 vernacular language per week (rotate)
// 3. Description: English + vernacular (if space allows)
// 4. Reviews: Reply in the language the review was written in
// 5. Q&A: Answer in English + vernacular if question is in vernacular
// GBP post rotation:
// Week 1: English + Malayalam
// Week 2: English + Tamil
// Week 3: English + Hindi
// Week 4: English only (if no vernacular for this practice)
10. Vernacular SEO#
10.1 Vernacular Keyword Strategy#
| Language | Example Keywords | Search Volume | Difficulty |
|---|---|---|---|
| Malayalam | "കൊച്ചിയിലെ മികച്ച ഡെന്റൽ ക്ലിനിക്" | Medium | Low |
| Malayalam | "ദന്തചികിത്സ കൊച്ചി" | Medium | Low |
| Tamil | "கோச்சியில் சிறந்த பல் மருத்துவமனை" | Medium | Low |
| Tamil | "பல் மருத்துவம் கோச்சி" | Medium | Low |
| Hindi | "कोची में सबसे अच्छा डेंटल क्लिनिक" | High | Medium |
| Hindi | "दांत का इलाज कोची" | High | Medium |
10.2 Vernacular SEO Implementation#
// Vernacular SEO rules:
// 1. Each language variant gets its own URL (/ml/, /ta/, /hi/)
// 2. Language-specific meta titles and descriptions
// 3. Language-specific hreflang tags
// 4. Language-specific sitemap entries
// 5. Language-specific GBP posts (if applicable)
// 6. Language-specific social media posts (if practice has vernacular pages)
// Vernacular keyword optimization:
// - Translate target keywords into vernacular
// - Use vernacular keywords in:
// - H1, H2 headings
// - Meta title and description
// - First 100 words of content
// - Alt text for images
// - GBP post content
// - Social media captions
// - Citation descriptions
10.3 Vernacular Content Calendar#
┌─────────────────────────────────────────────────────────────┐
│ VERNACULAR CONTENT CALENDAR (Example: Kerala Practice) │
│ │
│ Weekly: │
│ - English GBP post: 2-3x │
│ - Malayalam GBP post: 1x (every Tuesday) │
│ - English social post: 2-4x │
│ - Malayalam social post: 1x (every Thursday) │
│ │
│ Monthly: │
│ - English blog post: 2-3x │
│ - Malayalam blog post: 1x (mid-month) │
│ │
│ Quarterly: │
│ - Landing page content refresh: All languages │
│ - Citation description updates: All languages │
│ - FAQ updates: All languages │
│ │
│ Special Occasions: │
│ - Onam (Malayalam): Special GBP + social post │
│ - Vishu (Malayalam): Special GBP + social post │
│ - Pongal (Tamil): Special GBP + social post (if TN) │
│ - Diwali (Hindi): Special GBP + social post (if North) │
│ │
│ Review Replies: │
│ - Reply in the language the review was written in │
│ - If review is in Malayalam → reply in Malayalam │
│ - If review is in English → reply in English │
└─────────────────────────────────────────────────────────────┘
11. Cost & Performance#
11.1 Vernacular Content Cost per Client per Month#
| Language | Content Type | Monthly Volume | Cost/Item | Monthly Cost |
|---|---|---|---|---|
| Malayalam | GBP Post | 4 | ~$0.005 | ~$0.02 |
| Malayalam | Social Post | 4 | ~$0.005 | ~$0.02 |
| Malayalam | Blog Post | 1 | ~$0.012 | ~$0.012 |
| Tamil | GBP Post | 4 | ~$0.005 | ~$0.02 |
| Tamil | Social Post | 4 | ~$0.005 | ~$0.02 |
| Tamil | Blog Post | 1 | ~$0.012 | ~$0.012 |
| Hindi | GBP Post | 4 | ~$0.005 | ~$0.02 |
| Hindi | Social Post | 4 | ~$0.005 | ~$0.02 |
| Hindi | Blog Post | 1 | ~$0.012 | ~$0.012 |
| Total (3 languages) | ~$0.15 |
11.2 Image Generation Cost per Client per Month#
| Plan | Images/Month | Cost/Month |
|---|---|---|
| Starter | 12 | ~$0.50 |
| Growth | 36 | ~$1.50 |
| Pro | 120 | ~$5.00 |
11.3 Combined Vernacular + Image Cost#
| Plan | Text (Vernacular) | Images | Total | ARPU | AI Cost % |
|---|---|---|---|---|---|
| Starter | ~$0.15 | ~$0.50 | ~$0.65 | $48 | ~1.4% |
| Growth | ~$0.45 | ~$1.50 | ~$1.95 | $144 | ~1.4% |
| Pro | ~$1.50 | ~$5.00 | ~$6.50 | $480 | ~1.4% |
12. Database Schema#
-- Image Generation Records
CREATE TABLE ai_images (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
practice_id UUID NOT NULL REFERENCES practices(id) ON DELETE CASCADE,
task_type VARCHAR(50) NOT NULL, -- "gbp_post", "social_post", "hero", etc.
-- Image details
prompt TEXT NOT NULL,
enhanced_prompt TEXT,
negative_prompt TEXT,
image_url VARCHAR(500) NOT NULL,
thumbnail_url VARCHAR(500),
-- Model info
model VARCHAR(50) NOT NULL,
size VARCHAR(20) NOT NULL,
style VARCHAR(50),
-- Quality checks
safety_check VARCHAR(10) NOT NULL,
brand_alignment VARCHAR(10) NOT NULL,
cultural_check VARCHAR(10) NOT NULL,
quality_check VARCHAR(10) NOT NULL,
-- Cost
cost_usd DECIMAL(10, 6) NOT NULL,
latency_ms INTEGER,
-- Usage
used_in_content_id UUID,
used_in_content_type VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW(),
INDEX idx_practice_task (practice_id, task_type)
);
-- Content Language Variants
CREATE TABLE content_variants (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
content_id UUID NOT NULL, -- References the parent content
language VARCHAR(10) NOT NULL, -- "ml", "ta", "hi", etc.
content TEXT NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT "draft",
translated_by VARCHAR(20) NOT NULL DEFAULT "ai", -- "ai", "human", "hybrid"
translator_id UUID REFERENCES users(id),
-- Quality scores
quality_score INTEGER,
back_translation_score INTEGER,
cultural_score INTEGER,
-- Review
reviewed_by UUID REFERENCES users(id),
reviewed_at TIMESTAMP,
-- SEO
slug VARCHAR(200) NOT NULL,
meta_title VARCHAR(200),
meta_description VARCHAR(300),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(content_id, language),
INDEX idx_content_language (content_id, language)
);
-- Translation Usage Log
CREATE TABLE ai_translation_usage (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
practice_id UUID NOT NULL REFERENCES practices(id) ON DELETE CASCADE,
content_id UUID NOT NULL,
source_language VARCHAR(10) NOT NULL DEFAULT "en",
target_language VARCHAR(10) NOT NULL,
word_count INTEGER NOT NULL,
character_count INTEGER NOT NULL,
model VARCHAR(50) NOT NULL,
cost_usd DECIMAL(10, 6) NOT NULL,
latency_ms INTEGER,
quality_scores JSONB,
created_at TIMESTAMP DEFAULT NOW()
);
-- Language Preferences (per practice)
CREATE TABLE practice_language_preferences (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
practice_id UUID NOT NULL REFERENCES practices(id) ON DELETE CASCADE,
language VARCHAR(10) NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
priority INTEGER DEFAULT 1, -- 1 = highest
-- Content generation settings
auto_generate_gbp BOOLEAN DEFAULT FALSE,
auto_generate_social BOOLEAN DEFAULT FALSE,
auto_generate_blog BOOLEAN DEFAULT FALSE,
-- Review settings
requires_human_review BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(practice_id, language)
);
End of Image Generation & Vernacular Content Documentation — RankFlow AI v2.0.0