diff --git a/.claude/worktrees/laughing-montalcini b/.claude/worktrees/laughing-montalcini new file mode 160000 index 00000000..cb6eca44 --- /dev/null +++ b/.claude/worktrees/laughing-montalcini @@ -0,0 +1 @@ +Subproject commit cb6eca448357c3f217590739edf4b982f9a3582e diff --git a/v2/Igny8 V2 New Final Plans/IGNY8 Self-Hosted AI Infrastructure/Potential-SaaS-Projects-Alorig-Systems.docx b/v2/Igny8 V2 New Final Plans/IGNY8 Self-Hosted AI Infrastructure/Potential-SaaS-Projects-Alorig-Systems.docx new file mode 100644 index 00000000..b472dcde Binary files /dev/null and b/v2/Igny8 V2 New Final Plans/IGNY8 Self-Hosted AI Infrastructure/Potential-SaaS-Projects-Alorig-Systems.docx differ diff --git a/v2/Igny8 V2 New Final Plans/IGNY8 Self-Hosted AI Infrastructure/architecture (1).jsx b/v2/Igny8 V2 New Final Plans/IGNY8 Self-Hosted AI Infrastructure/architecture (1).jsx new file mode 100644 index 00000000..fb05df21 --- /dev/null +++ b/v2/Igny8 V2 New Final Plans/IGNY8 Self-Hosted AI Infrastructure/architecture (1).jsx @@ -0,0 +1,860 @@ +import { useState } from "react"; + +const Section = ({ title, children, defaultOpen = false }) => { + const [open, setOpen] = useState(defaultOpen); + return ( +
+ + {open &&
{children}
} +
+ ); +}; + +const Badge = ({ color, children }) => { + const colors = { + blue: "bg-blue-100 text-blue-800", + green: "bg-green-100 text-green-800", + purple: "bg-purple-100 text-purple-800", + orange: "bg-orange-100 text-orange-800", + red: "bg-red-100 text-red-800", + gray: "bg-gray-100 text-gray-800", + teal: "bg-teal-100 text-teal-800", + }; + return ( + + {children} + + ); +}; + +const ServerBox = ({ title, subtitle, color, children }) => { + const borderColors = { + blue: "border-blue-400 bg-blue-50", + purple: "border-purple-400 bg-purple-50", + green: "border-green-400 bg-green-50", + }; + return ( +
+

{title}

+

{subtitle}

+ {children} +
+ ); +}; + +const AppBlock = ({ name, purpose, port, badge }) => ( +
+
+
+ {name} + {badge && {badge.text}} +
+

{purpose}

+
+ {port && :{port}} +
+); + +const CostRow = ({ item, monthly, notes }) => ( +
+
+ {item} + {notes &&

{notes}

} +
+ {monthly} +
+); + +const Step = ({ num, title, code }) => ( +
+
+ + {num} + + {title} +
+ {code && ( +
+        {code}
+      
+ )} +
+); + +const Arrow = ({ label }) => ( +
+ {label} + + + +
+); + +export default function Architecture() { + const [tab, setTab] = useState("overview"); + + const tabs = [ + { id: "overview", label: "Architecture" }, + { id: "hostinger", label: "Hostinger VPS" }, + { id: "vastai", label: "Vast.ai GPU" }, + { id: "models", label: "AI Models" }, + { id: "setup", label: "Setup Guide" }, + { id: "costs", label: "Costs" }, + ]; + + return ( +
+
+

IGNY8 Self-Hosted AI Infrastructure

+

Hostinger VPS + Vast.ai GPU — Zero API Costs Architecture

+
+ +
+ {tabs.map((t) => ( + + ))} +
+ + {tab === "overview" && ( +
+
+ + + + + + + + + + + + + + + + + +
+ +
+

How They Connect

+
+
+ Hostinger + → LiteLLM proxy → + Vast.ai Ollama + Text generation (OpenAI-compatible API) +
+
+ Flowise + → LiteLLM → + Qwen3 models + IGNY8 content writing pipeline +
+
+ IGNY8 App + → HTTP API → + ComfyUI + Image/video generation requests +
+
+ Open WebUI + → Ollama API → + Any loaded model + Client chat interface +
+
+
+ +
+

Zero API Cost Model

+
+

• All LLM inference runs on your own GPU — no OpenAI/Anthropic API charges

+

• Image generation uses open-source FLUX.1/SD 3.5 — no Midjourney/DALL-E costs

+

• Video generation uses Wan 2.1/LTX-Video — no Runway/Sora costs

+

• Only fixed costs: Hostinger VPS (~$12-25/mo) + Vast.ai GPU (~$200/mo)

+

• Total: ~$215-225/month for unlimited AI generation

+
+
+
+ )} + + {tab === "hostinger" && ( +
+
+
+
+

KVM 4 or higher recommended

+

4 vCPU, 16GB RAM, 200GB NVMe — handles Plesk + all CPU services comfortably

+
+
+

What runs on Hostinger (CPU-only):

+
+
Plesk — Web hosting panel
+
Flowise — AI workflow engine
+
Open WebUI — Chat interface
+
Chroma — Vector DB
+
LiteLLM — API proxy
+
Nginx — Reverse proxy
+
+
+
+ Important: Don't install Ollama on Hostinger — it will be too slow on CPU. All AI inference goes through LiteLLM → Vast.ai GPU server. +
+
+
+ +
+
{`# docker-compose.yml on Hostinger VPS
+
+version: '3.8'
+
+services:
+  flowise:
+    image: flowiseai/flowise
+    ports:
+      - "3000:3000"
+    volumes:
+      - flowise_data:/root/.flowise
+    environment:
+      - FLOWISE_USERNAME=admin
+      - FLOWISE_PASSWORD=your_secure_password
+    restart: always
+
+  chromadb:
+    image: chromadb/chroma
+    ports:
+      - "8000:8000"
+    volumes:
+      - chroma_data:/chroma/chroma
+    restart: always
+
+  litellm:
+    image: ghcr.io/berriai/litellm:main-latest
+    ports:
+      - "4000:4000"
+    volumes:
+      - ./litellm_config.yaml:/app/config.yaml
+    command: ["--config", "/app/config.yaml"]
+    restart: always
+
+  open-webui:
+    image: ghcr.io/open-webui/open-webui:main
+    ports:
+      - "3001:8080"
+    environment:
+      # Point to Vast.ai Ollama (via SSH tunnel)
+      - OLLAMA_BASE_URL=http://litellm:4000
+    volumes:
+      - openwebui_data:/app/backend/data
+    restart: always
+
+volumes:
+  flowise_data:
+  chroma_data:
+  openwebui_data:`}
+
+ +
+
{`# litellm_config.yaml
+# Routes all AI requests to your Vast.ai GPU server
+
+model_list:
+  - model_name: qwen3-32b
+    litellm_params:
+      model: ollama/qwen3:32b
+      api_base: http://VAST_AI_IP:11434
+      
+  - model_name: qwen3-30b-moe
+    litellm_params:
+      model: ollama/qwen3:30b-a3b
+      api_base: http://VAST_AI_IP:11434
+
+  - model_name: qwen3-14b
+    litellm_params:
+      model: ollama/qwen3:14b
+      api_base: http://VAST_AI_IP:11434
+
+  - model_name: qwen3-8b
+    litellm_params:
+      model: ollama/qwen3:8b
+      api_base: http://VAST_AI_IP:11434
+
+general_settings:
+  master_key: sk-your-master-key-here`}
+
+ Security: Use SSH tunnel or WireGuard VPN between Hostinger and Vast.ai. Never expose Ollama port directly to the internet. +
+
+ +
+
{`# /etc/nginx/sites-available/ai-services
+
+# Flowise — IGNY8 AI workflows
+server {
+    listen 443 ssl;
+    server_name flowise.yourdomain.com;
+    ssl_certificate /etc/letsencrypt/live/...;
+    location / {
+        proxy_pass http://localhost:3000;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection "upgrade";
+    }
+}
+
+# Open WebUI — Client chat
+server {
+    listen 443 ssl;
+    server_name chat.yourdomain.com;
+    ssl_certificate /etc/letsencrypt/live/...;
+    location / {
+        proxy_pass http://localhost:3001;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection "upgrade";
+    }
+}
+
+# LiteLLM — API endpoint
+server {
+    listen 443 ssl;
+    server_name api.yourdomain.com;
+    ssl_certificate /etc/letsencrypt/live/...;
+    location / {
+        proxy_pass http://localhost:4000;
+    }
+}`}
+
+
+ )} + + {tab === "vastai" && ( +
+
+
+
+

GPU

+

2x RTX 3090 (48GB total)

+
+
+

CPU

+

AMD EPYC 7543 (13.5/128 cores)

+
+
+

RAM

+

54GB / 516GB

+
+
+

Storage

+

442GB NVMe

+
+
+

Location

+

Bulgaria

+
+
+

Cost

+

$0.277/hr (~$200/mo)

+
+
+
+ Note: 97.2% reliability = ~20hrs downtime/month. For production, consider m:24191 (Czechia, 99.38% reliability, $0.288/hr) or set up auto-failback to a paid API in LiteLLM config. +
+
+ +
+
+
+
+ Text Gen + Ollama + Qwen3 Models +
+

IGNY8 content writing, SEO content, chat responses

+
+

• Qwen3 32B (dense) — ~20GB VRAM, best quality

+

• Qwen3 30B-A3B (MoE) — ~19GB VRAM, fastest

+

• Qwen3 14B — ~9GB VRAM, for concurrent tasks

+

• Load models on demand via Ollama

+
+
+ +
+
+ Image Gen + ComfyUI + FLUX.1 / Stable Diffusion +
+

Blog images, social media graphics, product visuals for IGNY8

+
+

• FLUX.1 [dev] — best quality, ~12GB VRAM

+

• Stable Diffusion 3.5 — wide ecosystem, ~8GB VRAM

+

• SDXL-Lightning — fast generation, ~6GB VRAM

+

• All via ComfyUI API (port 8188)

+
+
+ +
+
+ Video Gen + Wan 2.1 / LTX-Video via ComfyUI +
+

Short videos for social media, product demos

+
+

• Wan 2.1 (14B) — best quality, uses full 48GB

+

• Wan 2.1 (1.3B) — fast, only ~8GB VRAM

+

• LTX-Video — fastest, ~12GB VRAM, 768x512

+

• ⚠️ Unload LLM before running video gen (shared VRAM)

+
+
+
+
+ +
+
+

48GB total — you can't run everything simultaneously

+
+
+

Mode 1: Content Writing (Default)

+

Qwen3 32B (~20GB) + FLUX.1 image gen (~12GB) = ~32GB

+

✓ Fits comfortably, both can run simultaneously

+
+
+

Mode 2: Fast Throughput

+

Qwen3 30B-A3B MoE (~19GB) + FLUX.1 (~12GB) = ~31GB

+

✓ Blazing fast text + images together

+
+
+

Mode 3: Video Generation

+

Unload LLM → Wan 2.1 14B uses full 48GB

+

⚠️ Schedule video jobs during off-peak, unload text model first

+
+
+

Ollama auto-unloads models after 5min idle. Use OLLAMA_KEEP_ALIVE to control.

+
+
+ +
+
{`# Run on Hostinger VPS — creates persistent tunnel to Vast.ai
+# This makes Vast.ai's ports available on localhost
+
+# Install autossh for persistent tunnels
+apt install autossh
+
+# Create tunnel (run as systemd service)
+autossh -M 0 -N \\
+  -L 11434:localhost:11434 \\   # Ollama
+  -L 8188:localhost:8188 \\     # ComfyUI
+  -o "ServerAliveInterval=30" \\
+  -o "ServerAliveCountMax=3" \\
+  -i /root/.ssh/vastai_key \\
+  root@VAST_AI_IP -p VAST_SSH_PORT
+
+# Now on Hostinger:
+# localhost:11434 → Vast.ai Ollama
+# localhost:8188 → Vast.ai ComfyUI`}
+
+
+ )} + + {tab === "models" && ( +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ModelVRAMSpeedBest ForLicense
Qwen3 32B ⭐~20GB~15-25 tok/sLong-form SEO content, articlesApache 2.0
Qwen3 30B-A3B ⭐~19GB~40-60 tok/sFast chat, SEO meta, bulk contentApache 2.0
Qwen3 14B~9GB~30-50 tok/sConcurrent light tasksApache 2.0
Qwen3 8B~5GB~50-80 tok/sClassification, tagging, simple tasksApache 2.0
+
+
+ IGNY8 Strategy: Use 30B-A3B MoE as default (fast bulk content), switch to 32B dense for premium long-form articles. Ollama handles model switching automatically. +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ModelVRAMSpeedQualityLicense
FLUX.1 [dev] ⭐~12GB~8-15s/imgExcellent — rivals MidjourneyNon-commercial*
Stable Diffusion 3.5 ⭐~8GB~5-10s/imgVery good + huge ecosystemCommunity
SDXL-Lightning~6GB~1-2s/imgGood for fast iterationsOpen
Z-Image-Turbo~16GB<1s/imgExcellent + text renderingApache 2.0
+
+
+ *FLUX.1 [dev] licensing: Free for non-commercial. For IGNY8 commercial use, either get BFL license or use SD 3.5 / Z-Image-Turbo (Apache 2.0, fully commercial). +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ModelVRAMResolutionDurationLicense
Wan 2.1 (1.3B) ⭐~8GB480p5-8s clipsApache 2.0
LTX-Video ⭐~12GB768x5125-7s clipsApache 2.0
Wan 2.1 (14B)~40GB+720p5-10s clipsApache 2.0
Wan2GP (optimized)~12GB720p8-15s clipsOpen
+
+
+ Best approach: Use Wan 2.1 1.3B or LTX-Video for quick social clips alongside the LLM. For premium 720p video, schedule Wan 14B during off-peak (requires unloading LLM). +
+
+ +
+
+

48GB VRAM Budget — Practical Combos:

+
+ 🟢 Combo A (Daily IGNY8 ops): Qwen3 30B-A3B (19GB) + SD 3.5 images (8GB) + Wan 1.3B video (8GB) = 35GB ✓ +
+
+ 🔵 Combo B (Premium content): Qwen3 32B (20GB) + FLUX.1 images (12GB) = 32GB ✓ +
+
+ 🟠 Combo C (Video focus): Wan 14B video (40GB+) = needs all VRAM, unload everything else +
+
+ 🟣 Combo D (Multi-client chat): Qwen3 14B (9GB) × multiple concurrent users = fast, lightweight +
+
+
+
+ )} + + {tab === "setup" && ( +
+
+ + + +
+ +
+ + + + /etc/systemd/system/vastai-tunnel.service << 'EOF' +[Unit] +Description=SSH Tunnel to Vast.ai GPU +After=network.target + +[Service] +ExecStart=/usr/bin/autossh -M 0 -N \\ + -L 11434:localhost:11434 \\ + -L 8188:localhost:8188 \\ + -o "ServerAliveInterval=30" \\ + -o "ServerAliveCountMax=3" \\ + -o "StrictHostKeyChecking=no" \\ + -i /root/.ssh/vastai_key \\ + root@VAST_IP -p PORT +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target +EOF + +systemctl enable vastai-tunnel +systemctl start vastai-tunnel`} /> +
+ +
+ + + +
+
+ )} + + {tab === "costs" && ( +
+
+
+ + + + +
+
+
+ Total Monthly + ~$235-245/mo +
+

For unlimited AI text + image + video generation

+
+
+ +
+
+
+

If Using APIs Instead:

+
+

• OpenAI GPT-4o: ~$0.005/1K tokens → 1M tokens/day = $150/mo just for text

+

• Midjourney: $30/mo (limited) or $0.01-0.04/image

+

• Runway Gen-3: $0.05/sec video → 100 videos/mo = $250/mo

+

• DALL-E 3: $0.04/image → 500 images/mo = $20/mo

+

Conservative estimate: $400-600+/month with scale

+
+
+
+

Your Self-Hosted Setup:

+
+

• Unlimited text generation — $0 marginal cost

+

• Unlimited image generation — $0 marginal cost

+

• Unlimited video generation — $0 marginal cost

+

• Fixed cost regardless of usage volume

+

Fixed: ~$240/month — scales to infinity

+
+
+
+
+ +
+
+

Break-even point: Once IGNY8 processes ~50+ articles/month with images, self-hosting is cheaper than APIs.

+

At scale: If IGNY8 generates 500+ articles + 1000+ images + 100+ videos per month, you're saving $300-500+/month vs APIs.

+

Added bonus: No rate limits, no API key management, no vendor lock-in, full data privacy.

+

Revenue potential: Sell the same infrastructure as a service to Alorig clients — chat.yourdomain.com as a white-label AI assistant.

+
+
+
+ )} + +
+

Architecture Summary

+

Hostinger VPS handles web hosting (Plesk), AI orchestration (Flowise, LiteLLM, Open WebUI), and vector storage (Chroma). All AI inference routes through an SSH tunnel to Vast.ai's 2x RTX 3090 GPU server running Ollama (text), ComfyUI (images + video). Zero API costs — fixed monthly spend of ~$240 for unlimited generation.

+
+
+ ); +} diff --git a/v2/Igny8 V2 New Final Plans/IGNY8-Industry-Sector-Master-List.md b/v2/Igny8 V2 New Final Plans/IGNY8-Industry-Sector-Master-List.md new file mode 100644 index 00000000..8736a677 --- /dev/null +++ b/v2/Igny8 V2 New Final Plans/IGNY8-Industry-Sector-Master-List.md @@ -0,0 +1,602 @@ +# IGNY8 Industry & Sector Master List v2 + +**Validation test for every sector:** "Could someone build and sustain a dedicated SEO-driven website for this sector alone? Does it have its own distinct attribute framework?" + +**Validation test for industry grouping:** "Do all sectors within this industry share a common business domain, but each requires a fundamentally different set of attributes?" + +--- + +## 1. Healthcare & Medical +1. General Practice & Family Medicine +2. Dentistry & Oral Health +3. Mental Health & Counseling +4. Physiotherapy & Rehabilitation +5. Dermatology & Skin Clinics +6. Eye Care & Optometry +7. Chiropractic Care +8. Cosmetic & Plastic Surgery +9. Pediatrics & Child Health +10. Orthopedics & Sports Medicine +11. Cardiology & Heart Health +12. Oncology & Cancer Care +13. Home Healthcare Services +14. Urgent Care & Walk-In Clinics + +## 2. Wellness & Alternative Medicine +1. Massage Therapy & Bodywork +2. Acupuncture & Traditional Chinese Medicine +3. Ayurveda & Herbal Medicine +4. Homeopathic Medicine +5. Naturopathy & Holistic Health +6. Nutrition & Dietetics +7. Yoga & Meditation Services +8. Wellness Retreats & Spas +9. Functional & Integrative Medicine +10. Energy Healing & Reiki + +## 3. Health & Fitness +1. Gyms & Fitness Centers +2. Personal Training Services +3. Yoga Studios +4. Pilates Studios +5. Martial Arts Schools +6. CrossFit & Functional Training +7. Dance Studios +8. Swimming & Aquatic Fitness +9. Sports Coaching & Academies +10. Kids & Youth Fitness Programs + +## 4. Health Products & Supplements +1. Dietary Supplements & Vitamins +2. Fitness Equipment & Gear +3. Massage & Therapy Devices +4. Relaxation & Sleep Products +5. Weight Loss Products +6. Senior Health & Mobility Aids +7. Medical Equipment & Supplies +8. First Aid & Safety Products +9. Disability & Accessibility Products +10. Health Monitoring Devices + +## 5. Beauty & Personal Care +1. Skincare Products & Brands +2. Haircare Products & Brands +3. Makeup & Cosmetics +4. Fragrances & Perfumes +5. Men's Grooming Products +6. Nail Care Products +7. Organic & Natural Beauty +8. Beauty Tools & Devices +9. Anti-Aging Products & Treatments +10. Sun Care & Tanning Products + +## 6. Beauty & Personal Care Services +1. Hair Salons & Styling +2. Barber Shops +3. Nail Salons +4. Spa & Wellness Centers +5. Skin Treatment & Facial Clinics +6. Laser Hair Removal Services +7. Tattoo & Body Art Studios +8. Eyebrow & Lash Services +9. Bridal & Occasion Styling +10. Mobile Beauty Services + +## 7. Apparel & Fashion +1. Womenswear +2. Menswear +3. Kidswear & Baby Clothing +4. Footwear +5. Fashion Accessories (Bags, Scarves, Belts) +6. Sportswear & Activewear +7. Luxury & Designer Fashion +8. Ethnic & Cultural Wear +9. Uniforms & Workwear +10. Plus Size & Inclusive Fashion +11. Sustainable & Eco Fashion +12. Lingerie & Sleepwear + +## 8. Jewelry & Watches +1. Fine Jewelry (Gold, Diamond, Gemstone) +2. Fashion & Costume Jewelry +3. Wedding & Bridal Jewelry +4. Luxury Watches +5. Casual & Fashion Watches +6. Handmade & Artisan Jewelry +7. Men's Jewelry & Accessories +8. Religious & Cultural Jewelry +9. Jewelry Repair & Custom Design +10. Smart Watches & Wearables + +## 9. Pets & Animals +1. Dog Products & Supplies +2. Cat Products & Supplies +3. Bird & Aviary Supplies +4. Aquarium & Fish Supplies +5. Small Animal Supplies (Rabbit, Hamster) +6. Reptile & Exotic Pet Supplies +7. Pet Food & Nutrition +8. Pet Grooming Products & Services +9. Veterinary Services +10. Pet Training & Behavior + +## 10. Home & Furniture +1. Living Room Furniture +2. Bedroom Furniture & Mattresses +3. Kitchen & Dining Furniture +4. Office & Home Office Furniture +5. Outdoor & Patio Furniture +6. Children's Furniture & Nursery +7. Bathroom Furniture & Fixtures +8. Storage & Organization Solutions +9. Custom & Bespoke Furniture +10. Antique & Vintage Furniture + +## 11. Home Decor & Interior +1. Home Decor & Accessories +2. Wall Art & Frames +3. Lighting & Lamps +4. Curtains, Blinds & Window Treatments +5. Rugs & Carpets +6. Bedding, Pillows & Linen +7. Candles, Fragrances & Aromatherapy +8. Vases, Planters & Indoor Greenery +9. Mirrors & Decorative Glass +10. Interior Design Services + +## 12. Home Appliances & Kitchen +1. Large Kitchen Appliances +2. Small Kitchen Appliances & Gadgets +3. Cookware & Bakeware +4. Kitchen Utensils & Tools +5. Food Storage & Organization +6. Coffee & Beverage Machines +7. Laundry Appliances +8. Vacuum Cleaners & Floor Care +9. Air Purifiers & Climate Control +10. Home Water Filtration + +## 13. Garden & Outdoor Living +1. Garden Tools & Equipment +2. Plants, Seeds & Gardening +3. Outdoor Furniture & Decor +4. Lawn Care & Landscaping Products +5. BBQ & Outdoor Cooking +6. Greenhouses & Grow Equipment +7. Fencing & Garden Structures +8. Irrigation & Water Features +9. Pest & Weed Control +10. Swimming Pool Supplies & Equipment + +## 14. Electronics & Gadgets +1. Mobile Phones & Accessories +2. Laptops & Computers +3. Audio & Headphones +4. Cameras & Photography +5. Smart Home Devices +6. Wearable Technology +7. Gaming Consoles & Accessories +8. Drones & Robotics +9. Networking & Wi-Fi Equipment +10. Computer Components & PC Building +11. Printers & Office Equipment +12. TV & Home Entertainment + +## 15. Baby & Kids +1. Baby Gear (Strollers, Car Seats, Carriers) +2. Baby Clothing & Accessories +3. Toys & Games +4. Nursery Furniture & Decor +5. Baby Feeding & Nursing +6. Baby Health & Safety +7. Kids Educational Products +8. Kids Outdoor & Play Equipment +9. Maternity & Pregnancy Products +10. Diapering & Potty Training + +## 16. Sports & Outdoors +1. Cycling & Bikes +2. Running & Athletics Gear +3. Swimming & Water Sports +4. Camping & Hiking Gear +5. Team Sports Equipment (Soccer, Cricket, Basketball) +6. Golf Equipment & Accessories +7. Fishing Gear & Tackle +8. Hunting & Shooting Sports +9. Winter Sports (Skiing, Snowboarding) +10. Racquet Sports (Tennis, Badminton, Squash) +11. Combat & Martial Arts Equipment +12. Boating & Marine Equipment + +## 17. Automotive +1. Auto Repair & Maintenance Services +2. Auto Parts & Accessories +3. Car Detailing & Care Products +4. Tires & Wheels +5. Car Dealerships (New & Used) +6. Car Rental & Leasing +7. Auto Body & Collision Repair +8. Electric Vehicles & EV Accessories +9. Motorcycles & Powersports +10. Commercial Vehicles & Fleet +11. Car Audio & Electronics +12. Automotive Tools & Equipment + +## 18. Food & Beverage (Products) +1. Specialty & Gourmet Food +2. Organic & Health Food +3. Snacks & Confectionery +4. Coffee & Tea Products +5. Halal Food Products +6. Vegan & Plant-Based Food +7. Baby & Kids Food +8. Spices, Sauces & Condiments +9. Bakery & Baking Supplies +10. Beverages & Drinks + +## 19. Food & Beverage (Services) +1. Restaurants & Dining +2. Cafes & Coffee Shops +3. Fast Food & Quick Service +4. Bakeries & Pastry Shops +5. Catering Services +6. Food Delivery & Meal Kits +7. Food Trucks & Street Food +8. Bars & Nightlife +9. Butcher & Meat Shops +10. Cloud Kitchens & Virtual Restaurants + +## 20. Home Services +1. Plumbing Services +2. Electrical Services +3. HVAC (Heating & Cooling) +4. Roofing Services +5. Landscaping & Lawn Care +6. Residential Cleaning Services +7. Pest Control Services +8. Painting & Decorating Services +9. Flooring Installation & Services +10. Window & Door Installation +11. Garage Door Services +12. Locksmith Services +13. Moving & Relocation Services +14. Handyman & General Repairs +15. Swimming Pool Services + +## 21. Construction & Building +1. General Contracting +2. Residential Construction +3. Commercial Construction +4. Interior Design & Fit-Out +5. Architecture & Design +6. Concrete & Masonry +7. Structural Steel & Fabrication +8. Carpentry & Woodworking +9. Demolition & Site Preparation +10. Plumbing & Mechanical Contractors (Commercial) + +## 22. Real Estate & Property +1. Residential Real Estate +2. Commercial Real Estate +3. Property Management +4. Property Development +5. Real Estate Investment +6. Vacation & Short-Term Rentals +7. Co-Working & Office Space +8. Warehouse & Industrial Property +9. Land Sales & Development +10. Real Estate Agents & Brokers + +## 23. Legal Services +1. Personal Injury Law +2. Family & Divorce Law +3. Criminal Defense +4. Corporate & Business Law +5. Immigration Law +6. Employment & Labor Law +7. Estate Planning & Probate +8. Intellectual Property Law +9. Real Estate & Property Law +10. Tax Law & Disputes + +## 24. Financial Services & Insurance +1. Banking & Personal Finance +2. Insurance (Auto, Health, Home, Life) +3. Accounting & Bookkeeping +4. Tax Preparation & Planning +5. Investment & Wealth Management +6. Mortgage & Home Loans +7. Business Loans & SME Finance +8. Financial Planning & Advisory +9. Islamic Finance & Banking +10. Cryptocurrency & Digital Assets +11. Debt Management & Credit Repair +12. Payroll & HR Finance + +## 25. Education & Training +1. Online Learning & E-Learning Platforms +2. Tutoring & Academic Support +3. Test Preparation (SAT, GRE, IELTS, etc.) +4. Vocational & Skills Training +5. Language Schools & Courses +6. Driving Schools +7. Music & Arts Education +8. Early Childhood & Preschool Education +9. Higher Education & Universities +10. Corporate Training & Development +11. IT & Coding Training +12. Special Needs Education + +## 26. Hospitality & Tourism +1. Hotels & Resorts +2. Travel Agencies & Tour Operators +3. Vacation Rentals & Homestays +4. Adventure & Eco Tourism +5. Medical Tourism +6. Business & Corporate Travel +7. Cruise & Ocean Travel +8. Destination Weddings & Honeymoons +9. Airlines & Air Travel +10. Hajj & Umrah Travel Services + +## 27. Technology & Software +1. Project Management Software +2. CRM & Sales Tools +3. HR & Recruitment Software +4. Accounting & Finance Software +5. Marketing Automation & Email Tools +6. Cybersecurity Solutions +7. Data Analytics & BI Tools +8. E-Commerce Platforms & Tools +9. Customer Support & Help Desk +10. Collaboration & Communication Tools +11. Cloud & Infrastructure Services +12. Website Builders & CMS +13. AI & Machine Learning Platforms +14. ERP & Business Management Systems + +## 28. IT & Tech Services +1. IT Consulting & Managed Services +2. Web Design & Development +3. Mobile App Development +4. Software Development & Custom Solutions +5. Cloud Migration & Management +6. Network & Infrastructure Services +7. Data Recovery & Backup Services +8. IT Support & Help Desk Services +9. Digital Transformation Consulting +10. Internet Service Providers & Hosting + +## 29. Marketing & Advertising +1. Digital Marketing Agencies +2. SEO Services +3. Social Media Marketing +4. Content Marketing & Strategy +5. PPC & Paid Advertising +6. Email Marketing Services +7. Branding & Brand Strategy +8. Influencer Marketing +9. PR & Communications +10. Video Marketing & Production + +## 30. Media & Creative Services +1. Photography Services +2. Videography & Film Production +3. Graphic Design & Branding +4. Animation & Motion Graphics +5. Music Production & Audio +6. Podcast Production +7. Content Writing & Copywriting +8. Printing & Publishing +9. Sign Making & Signage +10. Promotional Products & Merchandise + +## 31. Staffing & Recruitment +1. General Recruitment Agencies +2. IT & Tech Recruitment +3. Healthcare Recruitment +4. Executive Search & Headhunting +5. Temporary & Contract Staffing +6. Blue Collar & Industrial Staffing +7. International Recruitment & Manpower +8. Recruitment Technology & Job Boards + +## 32. Professional & Business Services +1. Management Consulting +2. Business Process Outsourcing (BPO) +3. Virtual Assistants & Remote Support +4. Translation & Localization +5. Market Research & Analytics +6. Engineering & Technical Consulting +7. Environmental & Sustainability Consulting +8. Import/Export & Trade Consulting +9. Franchise Consulting +10. Business Coaching & Mentoring + +## 33. Agriculture & Farming +1. Agricultural Equipment & Machinery +2. Seeds, Fertilizers & Agrochemicals +3. Livestock & Poultry Farming +4. Dairy & Dairy Products +5. Irrigation & Water Management +6. Organic Farming & Products +7. Aquaculture & Fisheries +8. Horticulture & Nurseries +9. Agri-Tech & Precision Farming +10. Agricultural Consulting + +## 34. Logistics & Transport +1. Freight & Cargo Shipping +2. Courier & Parcel Delivery +3. Warehousing & Storage +4. Fleet Management & Tracking +5. Moving & Relocation Services (Commercial) +6. Cold Chain Logistics +7. Customs Brokerage & Import/Export +8. Last Mile Delivery +9. Trucking & Road Transport +10. Maritime & Ocean Shipping + +## 35. Energy & Utilities +1. Solar Energy & Installation +2. Generators & Power Solutions +3. Wind Energy +4. Battery & Energy Storage +5. Electrical Contracting +6. Energy Auditing & Management +7. Water Treatment & Purification +8. EV Charging Infrastructure +9. Oil & Gas Services + +## 36. Events & Weddings +1. Wedding Planning & Coordination +2. Event Planning & Management +3. Venue Hire & Banquet Halls +4. Event & Wedding Photography +5. Event & Wedding Catering +6. DJ, Music & Entertainment +7. Event Decoration & Floristry +8. Wedding Attire & Bridal +9. Corporate Events & Conferences +10. Party & Event Rentals + +## 37. Security & Safety +1. Home Security & Alarm Systems +2. Commercial Security Services +3. CCTV & Video Surveillance +4. Fire Safety & Protection +5. Access Control Systems +6. Cybersecurity Services +7. Security Guard & Patrol +8. Private Investigation +9. Workplace Safety & Compliance + +## 38. Cleaning & Waste Management +1. Residential Cleaning +2. Commercial & Office Cleaning +3. Carpet & Upholstery Cleaning +4. Window Cleaning +5. Pressure Washing & Exterior Cleaning +6. Industrial Cleaning +7. Janitorial Supplies & Equipment +8. Disinfection & Sanitization +9. Waste Management & Recycling +10. Junk Removal & Hauling + +## 39. Manufacturing & Industrial +1. Metal & Steel Manufacturing +2. Plastic & Polymer Products +3. Textile & Fabric Manufacturing +4. Chemical Products & Coatings +5. Packaging & Containers +6. Industrial Machinery & Equipment +7. Electronics Manufacturing +8. Food Processing +9. Pharmaceutical Manufacturing +10. Automotive Parts Manufacturing + +## 40. Religious & Cultural +1. Islamic Products & Supplies +2. Hajj & Umrah Services +3. Modest Fashion & Islamic Clothing +4. Religious Books & Educational Materials +5. Halal Products & Certification +6. Cultural Handicrafts & Artifacts +7. Pilgrimage & Spiritual Travel +8. Religious Education & Courses + +## 41. Nonprofit & Social Enterprise +1. Charitable Organizations +2. Community Development +3. Social Enterprise & Impact +4. Fundraising & Donor Platforms +5. Environmental & Conservation NGOs +6. Humanitarian & Relief Organizations +7. Youth & Education Nonprofits + +## 42. Telecom & Connectivity +1. Internet Service Providers +2. Mobile & Wireless Services +3. VoIP & Business Communication +4. Managed IT & Network Services +5. Domain & Web Hosting +6. Cable & Satellite Services +7. Telecom Equipment & Infrastructure + +## 43. Office & Stationery +1. Office Furniture +2. Office Supplies & Stationery +3. Writing Instruments & Art Supplies +4. Bags, Backpacks & Luggage +5. Planners, Diaries & Organizers +6. Gift Items & Novelties +7. Paper & Printing Supplies + +## 44. Books & Media +1. Books & Publishing +2. E-Books & Digital Content +3. Magazines & Periodicals +4. Music & Vinyl +5. Board Games & Puzzles +6. Educational Materials & Textbooks +7. Audiobooks & Podcasts + +## 45. Tobacco & Vaping +1. Vaping & E-Cigarettes +2. Cigars & Tobacco Products +3. Smoking Accessories +4. CBD & Hemp Products + +--- + +## Summary + +| # | Industry | Sectors | Notes | +|---|----------|---------|-------| +| 1 | Healthcare & Medical | 14 | Specialized medical practices | +| 2 | Wellness & Alternative Medicine | 10 | Non-conventional health services | +| 3 | Health & Fitness | 10 | Exercise & fitness service businesses | +| 4 | Health Products & Supplements | 10 | Health-related e-commerce | +| 5 | Beauty & Personal Care | 10 | Beauty product e-commerce | +| 6 | Beauty & Personal Care Services | 10 | Beauty service businesses | +| 7 | Apparel & Fashion | 12 | Clothing e-commerce | +| 8 | Jewelry & Watches | 10 | Jewelry/watch e-commerce & services | +| 9 | Pets & Animals | 10 | Pet products & services | +| 10 | Home & Furniture | 10 | Furniture e-commerce | +| 11 | Home Decor & Interior | 10 | Decor products & services | +| 12 | Home Appliances & Kitchen | 10 | Appliance e-commerce | +| 13 | Garden & Outdoor Living | 10 | Outdoor products | +| 14 | Electronics & Gadgets | 12 | Consumer electronics e-commerce | +| 15 | Baby & Kids | 10 | Baby/kids products | +| 16 | Sports & Outdoors | 12 | Sports equipment & gear | +| 17 | Automotive | 12 | Auto products & services | +| 18 | Food & Beverage (Products) | 10 | Food product e-commerce | +| 19 | Food & Beverage (Services) | 10 | Restaurant & food service businesses | +| 20 | Home Services | 15 | Trade & maintenance services | +| 21 | Construction & Building | 10 | Construction trades | +| 22 | Real Estate & Property | 10 | Property business | +| 23 | Legal Services | 10 | Law practices | +| 24 | Financial Services & Insurance | 12 | Finance & insurance | +| 25 | Education & Training | 12 | Education businesses | +| 26 | Hospitality & Tourism | 10 | Travel & hospitality | +| 27 | Technology & Software | 14 | SaaS products | +| 28 | IT & Tech Services | 10 | IT service businesses | +| 29 | Marketing & Advertising | 10 | Marketing agencies & services | +| 30 | Media & Creative Services | 10 | Creative service businesses | +| 31 | Staffing & Recruitment | 8 | Recruitment businesses | +| 32 | Professional & Business Services | 10 | Consulting & advisory | +| 33 | Agriculture & Farming | 10 | Agri products & services | +| 34 | Logistics & Transport | 10 | Shipping & logistics | +| 35 | Energy & Utilities | 9 | Energy products & services | +| 36 | Events & Weddings | 10 | Event service businesses | +| 37 | Security & Safety | 9 | Security products & services | +| 38 | Cleaning & Waste Management | 10 | Cleaning service businesses | +| 39 | Manufacturing & Industrial | 10 | Manufacturing businesses | +| 40 | Religious & Cultural | 8 | Religious products & services | +| 41 | Nonprofit & Social Enterprise | 7 | Nonprofit organizations | +| 42 | Telecom & Connectivity | 7 | Telecom businesses | +| 43 | Office & Stationery | 7 | Office product e-commerce | +| 44 | Books & Media | 7 | Books & media e-commerce | +| 45 | Tobacco & Vaping | 4 | Restricted product e-commerce | + +**Total: 45 Industries, 449 Sectors** diff --git a/v2/Igny8 V2 New Final Plans/IGNY8-Plugin-Build-Plan.md b/v2/Igny8 V2 New Final Plans/IGNY8-Plugin-Build-Plan.md new file mode 100644 index 00000000..3c567940 --- /dev/null +++ b/v2/Igny8 V2 New Final Plans/IGNY8-Plugin-Build-Plan.md @@ -0,0 +1,798 @@ +# IGNY8 WordPress Plugin — Complete Build Plan + +**By:** Alorig Systems +**For:** AI Agent (Claude Code / Opus 4.6 in VSCode) +**Version:** 1.0 +**Date:** March 2026 +**Status:** Reference Document for Development + +--- + +## Executive Summary + +The IGNY8 WordPress Plugin is the **first site-level SEO plugin for WordPress**. Unlike Yoast, RankMath, or AIOSEO — which optimize individual pages against individual keywords — IGNY8 analyzes and optimizes your entire site's architecture, taxonomy structure, internal linking graph, and topical authority. + +**Two modes:** +1. **Standalone (Free):** Full SEO plugin replacing Yoast/RankMath — meta tags, schema, sitemaps, redirects, social OG, analytics, GSC, internal linking analysis, site-level architecture insights. No IGNY8 app account needed. +2. **Connected (Premium):** Links to IGNY8 SaaS platform — AI content generation, SAG blueprint sync, automated taxonomy creation, content pipeline, automated publishing, full site architecture generation. + +**Distribution:** Free on WordPress.org repository. Connected features require IGNY8 app subscription. + +--- + +## Part 1: Product Positioning + +### 1.1 What Exists Today (Page-Level Plugins) + +Every current SEO plugin does essentially the same thing: +- Set a focus keyword per page +- Analyze keyword density, heading usage, meta length +- Generate XML sitemap +- Add meta tags and OG tags +- Basic schema markup +- Redirect manager + +They optimize pages in isolation. They have no concept of how pages relate to each other, whether your site has topical gaps, whether your taxonomy structure creates authority, or whether your internal linking flows power to the right pages. + +### 1.2 What IGNY8 Plugin Does Differently + +**Site-Level Intelligence (Free):** +- Taxonomy coverage analysis: "You have 45 categories but only 12 have content — 33 are empty archive pages hurting your authority" +- Orphan page detection: "These 28 posts have zero internal links pointing to them" +- Topical gap analysis: "Your site covers 'dog food' extensively but has zero content about 'dog nutrition' — a closely related topic your competitors rank for" +- Internal link graph visualization: which pages are over-linked, under-linked, or isolated +- Cluster detection: automatically groups existing content into topical clusters and identifies imbalances +- Thin content identification: pages below content thresholds that need expansion +- Cannibalization detection: multiple pages targeting the same keyword + +**Site Architecture Generation (Connected):** +- SAG blueprint sync: receive the full dimensional structure (attributes, clusters, keywords) from IGNY8 platform +- Automated taxonomy creation: create all WordPress taxonomies, terms, and hierarchies from the SAG blueprint +- Content pipeline: pull AI-generated content for posts, pages, term descriptions, hub pages +- Publishing automation: scheduled publishing with review workflow +- Ongoing optimization: content updates, new cluster detection, gap filling + +### 1.3 The Free → Connected Funnel + +User installs free plugin → sees site-level insights they've never had before → dashboard shows: "IGNY8 has identified 23 topical gaps and 15 missing taxonomy terms. Connect to IGNY8 to generate the full blueprint and auto-fill these gaps." → User signs up for IGNY8 app → Connects via API key → Full architecture generation begins. + +The free plugin must be genuinely excellent. Not a crippled demo. A real replacement for RankMath that makes people switch. + +--- + +## Part 2: Module Architecture + +### 2.1 Module Map + +| Module | Free | Connected | Replaces | +|---|---|---|---| +| **SEO Core** | ✅ Full | ✅ Enhanced | Yoast, RankMath, AIOSEO | +| **Schema** | ✅ Full | ✅ Enhanced | Schema Pro, JSON-LD plugins | +| **Sitemap** | ✅ Full | ✅ Full | Yoast sitemap, XML Sitemap Generator | +| **Redirects** | ✅ Full | ✅ Full | Redirection plugin | +| **Social & OG** | ✅ Full | ✅ Enhanced | Social Warfare, OG plugins | +| **Analytics** | ✅ Full | ✅ Full | MonsterInsights, GA plugins | +| **Site Intelligence** | ✅ Basic | ✅ Full | Nothing (unique) | +| **Internal Linking** | ✅ Suggestions | ✅ Auto-linking | Link Whisper | +| **GSC Integration** | ✅ Dashboard | ✅ Full + Indexing API | Search Console plugins | +| **Content Sync** | ❌ | ✅ Full | — | +| **SAG Structure** | ❌ | ✅ Full | — | +| **Taxonomy Manager** | ❌ | ✅ Full | — | +| **Socializer** | ✅ Basic sharing | ✅ Auto-posting | Buffer, Hootsuite | +| **SMTP** | ✅ Full | ✅ Full | WP Mail SMTP | + +### 2.2 Free vs Connected Feature Split + +**SEO Core — Free:** +- Focus keyword per post/page +- SEO title + meta description with SERP preview +- Canonical URL management +- Robots meta (index/noindex, follow/nofollow) +- Content analysis (keyword density, headings, readability, internal links) +- Title tag template system (site-wide patterns) +- Breadcrumb generation + schema +- Webmaster verification codes + +**SEO Core — Connected additions:** +- Multi-keyword optimization (primary + secondary keywords from cluster) +- Cluster-aware content scoring ("this post covers 60% of its cluster's keyword targets") +- Auto-suggest missing headings based on cluster keyword gaps +- Content freshness scoring and update recommendations + +**Site Intelligence — Free (Basic):** +- Total page count by type (posts, pages, products, terms) +- Orphan pages list (no internal links) +- Thin content list (below word count threshold) +- Empty taxonomy terms list +- Basic internal link count per page +- Duplicate title/meta detection +- Cannibalization warnings (same keyword on multiple pages) + +**Site Intelligence — Connected (Full):** +- Full SAG gap analysis (missing clusters, missing terms, missing attribute values) +- Cluster health scores (content coverage, link density, keyword rankings per cluster) +- Competitor gap comparison (connected to IGNY8 platform competitor analysis) +- Architecture blueprint with recommended new pages/terms +- Priority queue: which gaps to fill first (by volume, difficulty, existing authority) +- Topical authority scoring per cluster + +**Internal Linking — Free:** +- Link audit: total internal links, broken links, nofollow links +- Per-post link count and suggestions ("this post could link to these 5 related posts") +- Orphan content detection +- Link equity distribution overview + +**Internal Linking — Connected:** +- SAG-aware automatic link suggestions based on cluster relationships +- Bulk link insertion tool +- Link template rules ("always link [keyword] to [URL]") +- Contextual link placement (AI-determined best anchor text and position) +- Link priority scoring based on cluster importance + +**Socializer — Free:** +- Lightweight share buttons (pure CSS/JS, no external dependencies) +- Position options: floating, above/below content, inline +- Networks: Facebook, X, LinkedIn, Pinterest, WhatsApp, Telegram, Email, Copy Link +- Social profile links management (site-wide) +- OG tags (handled by SEO Core module) + +**Socializer — Connected:** +- Auto-post to social platforms on WordPress publish +- Per-platform message templates +- Scheduling (publish now or delay) +- Platform API connections: X, Facebook Pages, LinkedIn, Instagram +- Dynamic OG image generation from post title + featured image +- Social post performance tracking (clicks, engagement) +- Bulk social scheduling for existing content + +--- + +## Part 3: Plugin File Structure + +``` +igny8/ +├── igny8.php # Plugin header, bootstrap, module loader +├── readme.txt # WordPress.org readme +├── uninstall.php # Cleanup on uninstall +│ +├── includes/ +│ ├── class-igny8.php # Main plugin class +│ ├── class-module-manager.php # Module registration + activation +│ ├── class-api-client.php # IGNY8 platform API client (for connected mode) +│ ├── class-connection.php # API key validation, connection status +│ ├── class-utils.php # Shared utilities +│ ├── class-ajax.php # Shared AJAX handler +│ ├── class-rest-api.php # Plugin REST endpoints for theme communication +│ ├── class-compatibility.php # Detect and disable conflicting plugins +│ │ +│ ├── modules/ +│ │ │ +│ │ ├── seo/ +│ │ │ ├── class-seo-module.php # Module entry, hooks +│ │ │ ├── class-meta-box.php # Post/page SEO meta box +│ │ │ ├── class-title-tag.php # Title tag management + templates +│ │ │ ├── class-meta-tags.php # Meta description, robots, canonical +│ │ │ ├── class-content-analysis.php # Real-time SEO scoring +│ │ │ ├── class-breadcrumbs.php # Breadcrumb generation + shortcode +│ │ │ ├── class-opengraph.php # OG + Twitter Card meta tags +│ │ │ ├── class-robots-txt.php # Virtual robots.txt manager +│ │ │ ├── class-verification.php # Webmaster tool verification codes +│ │ │ └── views/ +│ │ │ ├── meta-box.php # Meta box template +│ │ │ └── settings.php # SEO settings page template +│ │ │ +│ │ ├── schema/ +│ │ │ ├── class-schema-module.php # Module entry +│ │ │ ├── class-schema-generator.php # JSON-LD output +│ │ │ ├── class-schema-article.php # Article, BlogPosting, NewsArticle +│ │ │ ├── class-schema-local-business.php # LocalBusiness + subtypes +│ │ │ ├── class-schema-product.php # Product (WooCommerce integration) +│ │ │ ├── class-schema-faq.php # FAQPage +│ │ │ ├── class-schema-howto.php # HowTo +│ │ │ ├── class-schema-organization.php # Organization / Person +│ │ │ ├── class-schema-webpage.php # WebPage, CollectionPage +│ │ │ ├── class-schema-breadcrumb.php # BreadcrumbList +│ │ │ ├── class-schema-service.php # Service (for service CPT) +│ │ │ └── class-schema-custom.php # Custom schema field (advanced users) +│ │ │ +│ │ ├── sitemap/ +│ │ │ ├── class-sitemap-module.php # Module entry +│ │ │ ├── class-sitemap-index.php # Sitemap index generator +│ │ │ ├── class-sitemap-posts.php # Post type sitemaps +│ │ │ ├── class-sitemap-taxonomies.php # Taxonomy sitemaps +│ │ │ ├── class-sitemap-images.php # Image sitemap +│ │ │ └── class-sitemap-xsl.php # XSL stylesheet for browser viewing +│ │ │ +│ │ ├── redirects/ +│ │ │ ├── class-redirects-module.php # Module entry +│ │ │ ├── class-redirect-manager.php # CRUD for redirects +│ │ │ ├── class-404-monitor.php # 404 logging + one-click redirect +│ │ │ ├── class-auto-redirect.php # Auto-redirect on slug change +│ │ │ └── views/ +│ │ │ └── redirects-admin.php # Redirect management page +│ │ │ +│ │ ├── analytics/ +│ │ │ ├── class-analytics-module.php # Module entry +│ │ │ ├── class-ga-connector.php # Google Analytics (GA4) +│ │ │ ├── class-gtm-connector.php # Google Tag Manager +│ │ │ ├── class-pixel-manager.php # Facebook, TikTok, Pinterest pixels +│ │ │ └── class-script-manager.php # Custom header/footer scripts +│ │ │ +│ │ ├── site-intelligence/ +│ │ │ ├── class-intelligence-module.php # Module entry +│ │ │ ├── class-site-audit.php # Full site audit runner +│ │ │ ├── class-orphan-detector.php # Pages with no internal links +│ │ │ ├── class-thin-content.php # Below-threshold content +│ │ │ ├── class-empty-terms.php # Taxonomy terms with no content +│ │ │ ├── class-cannibalization.php # Keyword cannibalization detection +│ │ │ ├── class-duplicate-meta.php # Duplicate titles/descriptions +│ │ │ ├── class-cluster-detector.php # Auto-group existing content into clusters +│ │ │ ├── class-gap-analysis.php # [Connected] SAG gap analysis +│ │ │ ├── class-cluster-health.php # [Connected] Per-cluster scoring +│ │ │ └── views/ +│ │ │ ├── dashboard.php # Site intelligence dashboard +│ │ │ └── audit-results.php # Detailed audit results page +│ │ │ +│ │ ├── linking/ +│ │ │ ├── class-linking-module.php # Module entry +│ │ │ ├── class-link-auditor.php # Internal link audit +│ │ │ ├── class-link-suggestions.php # Per-post link suggestions +│ │ │ ├── class-orphan-links.php # Orphan content list +│ │ │ ├── class-link-graph.php # Link equity distribution map +│ │ │ ├── class-auto-linker.php # [Connected] Automatic link insertion +│ │ │ ├── class-link-rules.php # [Connected] Keyword → URL link rules +│ │ │ └── views/ +│ │ │ ├── link-audit.php # Link audit page +│ │ │ └── link-suggestions.php # Suggestions interface +│ │ │ +│ │ ├── gsc/ +│ │ │ ├── class-gsc-module.php # Module entry +│ │ │ ├── class-gsc-auth.php # Google OAuth flow +│ │ │ ├── class-gsc-dashboard.php # Search performance dashboard +│ │ │ ├── class-gsc-keywords.php # Keyword position tracking +│ │ │ ├── class-gsc-indexing.php # [Connected] Indexing API requests +│ │ │ ├── class-gsc-url-inspection.php # [Connected] URL inspection status +│ │ │ └── views/ +│ │ │ ├── gsc-dashboard.php # GSC data display +│ │ │ └── gsc-connect.php # OAuth connection page +│ │ │ +│ │ ├── socializer/ +│ │ │ ├── class-socializer-module.php # Module entry +│ │ │ ├── class-share-buttons.php # Frontend share buttons (pure CSS/JS) +│ │ │ ├── class-social-profiles.php # Site-wide social links +│ │ │ ├── class-auto-poster.php # [Connected] Auto-post on publish +│ │ │ ├── class-twitter-api.php # [Connected] X/Twitter API +│ │ │ ├── class-facebook-api.php # [Connected] Facebook Pages API +│ │ │ ├── class-linkedin-api.php # [Connected] LinkedIn API +│ │ │ ├── class-og-image-generator.php # [Connected] Dynamic OG images +│ │ │ └── views/ +│ │ │ ├── share-settings.php # Share button configuration +│ │ │ └── social-accounts.php # Connected accounts management +│ │ │ +│ │ ├── smtp/ +│ │ │ ├── class-smtp-module.php # Module entry +│ │ │ ├── class-smtp-mailer.php # Override wp_mail() +│ │ │ ├── class-email-log.php # Send log +│ │ │ └── class-email-test.php # Test email utility +│ │ │ +│ │ ├── content-sync/ # [Connected only] +│ │ │ ├── class-sync-module.php # Module entry +│ │ │ ├── class-content-puller.php # Pull content from IGNY8 app +│ │ │ ├── class-content-mapper.php # Map IGNY8 content types → WP post types +│ │ │ ├── class-image-downloader.php # Download + attach AI images +│ │ │ ├── class-sync-queue.php # Sync job queue + status +│ │ │ ├── class-publish-scheduler.php # Scheduled publishing with review +│ │ │ └── views/ +│ │ │ ├── sync-dashboard.php # Sync status + controls +│ │ │ └── content-review.php # Review queue before publish +│ │ │ +│ │ └── sag/ # [Connected only] +│ │ ├── class-sag-module.php # Module entry +│ │ ├── class-blueprint-sync.php # Receive SAG blueprint from IGNY8 app +│ │ ├── class-taxonomy-builder.php # Create WP taxonomies from SAG attributes +│ │ ├── class-term-builder.php # Create taxonomy terms from attribute values +│ │ ├── class-cluster-manager.php # Cluster → hub page mapping +│ │ ├── class-structure-visualizer.php # Visual site structure map +│ │ └── views/ +│ │ ├── sag-dashboard.php # SAG structure overview +│ │ ├── blueprint-review.php # Review blueprint before applying +│ │ └── structure-map.php # Visual cluster/taxonomy map +│ │ +│ ├── admin/ +│ │ ├── class-admin-menu.php # Admin menu registration +│ │ ├── class-dashboard.php # Main plugin dashboard +│ │ ├── class-setup-wizard.php # First-run setup wizard +│ │ ├── class-compatibility-notice.php # Notices for conflicting plugins +│ │ ├── views/ +│ │ │ ├── dashboard.php # Main dashboard template +│ │ │ ├── wizard/ +│ │ │ │ ├── step-1-site-type.php # Site type selection +│ │ │ │ ├── step-2-seo-import.php # Import from Yoast/RankMath +│ │ │ │ ├── step-3-basics.php # Site name, logo, org type +│ │ │ │ ├── step-4-social.php # Social profiles +│ │ │ │ ├── step-5-connect.php # IGNY8 API key (optional) +│ │ │ │ └── step-6-done.php # Summary + next steps +│ │ │ └── connect-prompt.php # "Connect to IGNY8" upsell card +│ │ └── assets/ +│ │ ├── admin.css +│ │ ├── admin.js +│ │ ├── meta-box.css +│ │ └── meta-box.js +│ │ +│ ├── frontend/ +│ │ ├── class-head-output.php # All tag output (meta, schema, OG) +│ │ ├── class-share-output.php # Share button HTML/CSS/JS +│ │ └── assets/ +│ │ ├── share-buttons.css # Share button styles (<3KB) +│ │ └── share-buttons.js # Share button JS (<2KB) +│ │ +│ ├── data/ +│ │ ├── class-installer.php # Database table creation +│ │ ├── class-migrator.php # Version migration handler +│ │ └── class-importer.php # Import from Yoast/RankMath/AIOSEO +│ │ +│ └── integrations/ +│ ├── class-woocommerce.php # WooCommerce-specific SEO/schema +│ └── class-theme-bridge.php # Communication layer with companion theme +│ +└── languages/ + └── igny8.pot +``` + +--- + +## Part 4: Data Architecture + +### 4.1 Custom Database Tables + +```sql +-- Redirects +{prefix}igny8_redirects + id BIGINT AUTO_INCREMENT PRIMARY KEY + source_url VARCHAR(500) NOT NULL + target_url VARCHAR(500) NOT NULL + type SMALLINT DEFAULT 301 -- 301, 302, 307 + hits INT DEFAULT 0 + last_hit DATETIME NULL + created_at DATETIME NOT NULL + is_active TINYINT(1) DEFAULT 1 + INDEX idx_source (source_url(191)) + +-- 404 Log +{prefix}igny8_404_log + id BIGINT AUTO_INCREMENT PRIMARY KEY + url VARCHAR(500) NOT NULL + referrer VARCHAR(500) NULL + user_agent VARCHAR(500) NULL + ip_hash VARCHAR(64) NULL -- Hashed for privacy + hits INT DEFAULT 1 + first_hit DATETIME NOT NULL + last_hit DATETIME NOT NULL + is_resolved TINYINT(1) DEFAULT 0 + redirect_id BIGINT NULL -- FK to redirects table + INDEX idx_url (url(191)) + +-- Internal Links Map +{prefix}igny8_link_map + id BIGINT AUTO_INCREMENT PRIMARY KEY + source_post_id BIGINT NOT NULL + target_post_id BIGINT NOT NULL + anchor_text VARCHAR(500) NULL + is_follow TINYINT(1) DEFAULT 1 + link_position VARCHAR(20) NULL -- content, sidebar, footer + last_crawled DATETIME NOT NULL + INDEX idx_source (source_post_id) + INDEX idx_target (target_post_id) + +-- Site Audit Results +{prefix}igny8_audit_results + id BIGINT AUTO_INCREMENT PRIMARY KEY + audit_type VARCHAR(50) NOT NULL -- orphan, thin, cannibalization, etc. + post_id BIGINT NULL + term_id BIGINT NULL + severity VARCHAR(20) NOT NULL -- critical, warning, info + message TEXT NOT NULL + data LONGTEXT NULL -- JSON extra data + audit_date DATETIME NOT NULL + is_resolved TINYINT(1) DEFAULT 0 + INDEX idx_type_date (audit_type, audit_date) + +-- Email Log (SMTP module) +{prefix}igny8_email_log + id BIGINT AUTO_INCREMENT PRIMARY KEY + to_email VARCHAR(320) NOT NULL + subject VARCHAR(500) NOT NULL + status VARCHAR(20) NOT NULL -- sent, failed + error_message TEXT NULL + sent_at DATETIME NOT NULL + +-- Form Entries (if forms included — see note below) +-- Forms may move to theme plugin instead + +-- Sync Queue (Connected mode) +{prefix}igny8_sync_queue + id BIGINT AUTO_INCREMENT PRIMARY KEY + igny8_content_id VARCHAR(100) NOT NULL + content_type VARCHAR(50) NOT NULL + sync_status VARCHAR(20) NOT NULL -- pending, synced, failed, review + wp_post_id BIGINT NULL + wp_term_id BIGINT NULL + data LONGTEXT NULL -- JSON payload from IGNY8 + created_at DATETIME NOT NULL + synced_at DATETIME NULL + error_message TEXT NULL + INDEX idx_status (sync_status) +``` + +### 4.2 Post Meta Keys + +All IGNY8 post meta keys use the `_igny8_` prefix: + +``` +_igny8_focus_keyword -- Primary focus keyword +_igny8_secondary_keywords -- JSON array of secondary keywords +_igny8_seo_title -- Custom SEO title (overrides template) +_igny8_meta_description -- Meta description +_igny8_canonical_url -- Canonical URL override +_igny8_robots_index -- 1 = index, 0 = noindex +_igny8_robots_follow -- 1 = follow, 0 = nofollow +_igny8_og_title -- OG title override +_igny8_og_description -- OG description override +_igny8_og_image -- OG image override (attachment ID) +_igny8_twitter_title -- Twitter card title override +_igny8_twitter_description -- Twitter card description override +_igny8_schema_type -- Schema type override (Article, HowTo, FAQ, etc.) +_igny8_schema_custom -- Custom JSON-LD (advanced) +_igny8_seo_score -- Last calculated SEO score (0-100) +_igny8_content_score -- Content quality score +_igny8_readability_score -- Readability score +_igny8_cluster_id -- [Connected] Mapped cluster ID +_igny8_related_links -- JSON array: [{post_id, anchor_text, priority}] +_igny8_link_suggestions -- JSON array of suggested internal links +_igny8_last_analysis -- Timestamp of last content analysis +_igny8_igny8_content_id -- [Connected] ID in IGNY8 platform +_igny8_sync_status -- [Connected] synced, pending, modified +``` + +### 4.3 Term Meta Keys + +``` +_igny8_term_seo_title -- SEO title for term archive +_igny8_term_meta_description -- Meta description for term archive +_igny8_term_robots_index -- index/noindex +_igny8_term_og_image -- OG image for term +_igny8_term_content -- Rich HTML content for term landing page +_igny8_term_cluster_id -- [Connected] Mapped cluster ID +_igny8_term_sag_attribute -- [Connected] SAG attribute this term belongs to +_igny8_term_sag_level -- [Connected] Primary, Secondary, Tertiary +_igny8_term_faq -- JSON array of FAQ items for term +_igny8_term_related_terms -- JSON array of related term IDs +_igny8_term_igny8_id -- [Connected] ID in IGNY8 platform +``` + +### 4.4 Options Keys + +``` +igny8_version -- Plugin version (for migrations) +igny8_active_modules -- JSON array of enabled module slugs +igny8_seo_settings -- JSON: title templates, separator, defaults +igny8_schema_settings -- JSON: org type, name, logo, knowledge graph +igny8_sitemap_settings -- JSON: included post types, taxonomies +igny8_social_profiles -- JSON: {facebook, twitter, linkedin, youtube, ...} +igny8_analytics_settings -- JSON: GA ID, GTM ID, pixel IDs +igny8_redirect_settings -- JSON: auto-redirect on slug change, etc. +igny8_smtp_settings -- JSON: host, port, user, pass, encryption +igny8_share_settings -- JSON: networks, position, style +igny8_linking_settings -- JSON: auto-link rules, max links per post +igny8_intelligence_settings -- JSON: audit schedule, thresholds +igny8_gsc_token -- Encrypted Google OAuth token +igny8_gsc_property -- Selected Search Console property +igny8_api_key -- [Connected] IGNY8 platform API key +igny8_api_connected -- [Connected] boolean +igny8_site_id -- [Connected] IGNY8 site ID +igny8_last_sync -- [Connected] last sync timestamp +igny8_sag_blueprint -- [Connected] JSON: full SAG structure cache +``` + +--- + +## Part 5: Theme ↔ Plugin Contract + +The IGNY8 plugin communicates with the companion theme (and any theme) through a defined interface. The theme is never required — the plugin works with any theme. But the companion theme knows how to read IGNY8 data natively. + +### 5.1 How Theme Reads Plugin Data + +The plugin registers a public API class that the theme (or any theme) can use: + +```php +// Theme checks if IGNY8 is active: +if (function_exists('igny8')) { + $seo_title = igny8()->seo->get_title($post_id); + $breadcrumbs = igny8()->seo->get_breadcrumbs(); + $related_links = igny8()->linking->get_related_links($post_id); + $schema = igny8()->schema->get_json_ld($post_id); + $share_buttons = igny8()->socializer->render_share_buttons($post_id); + $term_content = igny8()->seo->get_term_content($term_id); + $cluster_nav = igny8()->linking->get_cluster_navigation($post_id); +} +``` + +### 5.2 What Theme Reads for Display + +| Data | Source | Theme Usage | +|---|---|---| +| Related links | `_igny8_related_links` post meta | "Related Articles" section | +| Cluster navigation | Plugin API: cluster siblings | "More in this topic" sidebar/footer | +| Term landing page content | `_igny8_term_content` term meta | Term archive template hero section | +| Term FAQs | `_igny8_term_faq` term meta | FAQ accordion on term pages | +| Related terms | `_igny8_term_related_terms` term meta | "Related topics" block on term pages | +| Breadcrumbs | Plugin API or shortcode `[igny8_breadcrumbs]` | Breadcrumb display | +| Share buttons | Plugin API or shortcode `[igny8_share]` | Share button display | +| SAG attribute label | `_igny8_term_sag_attribute` term meta | Attribute-based navigation sections | +| SEO scores | `_igny8_seo_score` post meta | Optional score badge in admin | + +### 5.3 REST API Endpoints (Plugin Provides) + +For advanced theme features or AJAX interactions: + +``` +GET /wp-json/igny8/v1/related/{post_id} -- Related content for a post +GET /wp-json/igny8/v1/cluster/{cluster_id} -- All content in a cluster +GET /wp-json/igny8/v1/term/{term_id}/content -- Term landing page data +GET /wp-json/igny8/v1/structure/overview -- Site structure summary +POST /wp-json/igny8/v1/sync/trigger -- [Connected] Trigger sync +GET /wp-json/igny8/v1/audit/summary -- Site audit summary +``` + +--- + +## Part 6: SEO Import System + +Critical for adoption. Users switching from Yoast or RankMath need a seamless migration. + +### 6.1 Supported Imports + +| Source Plugin | Data Imported | +|---|---| +| **Yoast SEO** | Focus keyword, SEO title, meta description, robots meta, canonical, OG settings, redirects (premium), XML sitemap settings | +| **RankMath** | Focus keywords (multiple), SEO title, meta description, robots, canonical, OG, schema type, redirects, 404 monitor data | +| **AIOSEO** | Title, description, robots, canonical, OG, schema | + +### 6.2 Import Process + +1. Plugin detects installed SEO plugins on activation +2. Setup wizard offers import in Step 2 +3. Import runs in background (Celery-style via WP Cron for large sites) +4. Progress bar shows completion +5. After import, option to deactivate source plugin +6. All imported data stored in IGNY8's own meta keys (no dependency on source plugin data) + +--- + +## Part 7: Setup Wizard + +### Step 1: Site Type +Select site type for default schema and configuration: +- Blog / Content Site +- Business / Corporate +- eCommerce (WooCommerce) +- Local Business / Services +- SaaS / Software +- Portfolio / Agency + +### Step 2: SEO Import +- Detects Yoast, RankMath, AIOSEO +- One-click import of all SEO data +- Shows count of posts/pages/terms to import + +### Step 3: Site Basics +- Site name (for title tag template) +- Organization or Person (for schema) +- Logo upload (for schema) +- Default title separator + +### Step 4: Social Profiles +- Facebook, X/Twitter, LinkedIn, YouTube, Instagram, Pinterest URLs +- Default social sharing image + +### Step 5: Connect to IGNY8 (Optional) +- API key input field +- "Don't have an account? Sign up free" link +- Connection test + site pairing +- Skip option (clearly labeled, no pressure) + +### Step 6: Done +- Summary of configuration +- "Run your first site audit" CTA +- Links to key settings pages +- Quick tips for getting started + +--- + +## Part 8: Compatibility Layer + +### 8.1 Conflicting Plugin Detection + +On activation, detect and warn about: +- Yoast SEO (meta tags, sitemap conflict) +- RankMath (meta tags, sitemap, schema conflict) +- AIOSEO (meta tags conflict) +- XML Sitemap Generator (sitemap conflict) +- Schema plugins (duplicate schema) +- Redirection plugin (redirect conflict) + +Show admin notice: "IGNY8 replaces [Plugin Name]. We can import your data and you can then deactivate it. [Import & Deactivate] [Dismiss]" + +### 8.2 WooCommerce Integration + +When WooCommerce is active: +- Product schema auto-generated from WooCommerce data +- Product category term meta available +- Product attribute taxonomies detected and included in SAG structure +- Shop/product archive pages get SEO meta box +- Product sitemap includes price, availability, images + +### 8.3 Theme Bridge + +When companion theme is active: +- Plugin detects `current_theme_supports('igny8')` +- Enables enhanced data passing (related links, cluster nav, term content) +- Disables features the theme handles natively (breadcrumb HTML, share button HTML) +- Plugin focuses on data + `` output; theme handles visual display + +When any other theme: +- Plugin handles all output itself (breadcrumbs via shortcode, share buttons via auto-insertion) +- All features work independently +- Less visually integrated but fully functional + +--- + +## Part 9: Build Execution Plan + +### Phase 1: Foundation (Days 1-3) + +| Day | Task | +|---|---| +| 1 | Plugin skeleton: main file, module manager, admin menu, dashboard page | +| 1 | Module base class, activation/deactivation lifecycle, option storage | +| 2 | Setup wizard: 6-step flow, site type config, social profiles | +| 2 | Database installer: create all custom tables | +| 3 | REST API base: endpoint registration, authentication | +| 3 | Compatibility layer: detect conflicting plugins, admin notices | + +### Phase 2: SEO Core (Days 4-7) + +| Day | Task | +|---|---| +| 4 | SEO meta box: focus keyword, title, description, SERP preview | +| 4 | Title tag management: templates, separator, dynamic tokens | +| 5 | Meta tags output: description, robots, canonical in `` | +| 5 | Content analysis: keyword density, heading check, readability scoring | +| 6 | OG + Twitter Card meta tags | +| 6 | Breadcrumbs: generation, shortcode, schema | +| 7 | Robots.txt manager, verification codes | +| 7 | SEO settings page: global defaults, title templates, noindex rules | + +### Phase 3: Schema + Sitemap + Redirects (Days 8-10) + +| Day | Task | +|---|---| +| 8 | Schema generator: Article, Organization, WebPage, BreadcrumbList, WebSite+SearchAction | +| 8 | Schema: FAQPage, HowTo, LocalBusiness, Service | +| 9 | Schema: Product (WooCommerce), custom schema field | +| 9 | XML sitemap: index, post type sitemaps, taxonomy sitemaps, image sitemap | +| 10 | Redirects: CRUD, 404 monitor, auto-redirect on slug change, CSV import/export | + +### Phase 4: Site Intelligence (Days 11-13) + +| Day | Task | +|---|---| +| 11 | Site audit runner: orchestrate all checks | +| 11 | Orphan detector, thin content scanner, empty terms checker | +| 12 | Cannibalization detection, duplicate meta finder | +| 12 | Cluster detector (auto-group existing content by topic similarity) | +| 13 | Intelligence dashboard: audit results, scores, charts | +| 13 | Scheduled re-audit via WP Cron | + +### Phase 5: Internal Linking (Days 14-15) + +| Day | Task | +|---|---| +| 14 | Link crawl: scan all content, build link map table | +| 14 | Link audit page: per-post counts, broken links, orphans | +| 15 | Link suggestions: analyze content and suggest internal links | +| 15 | Link graph visualization (simple table/chart, not full D3 graph) | + +### Phase 6: Socializer + Analytics + SMTP (Days 16-18) + +| Day | Task | +|---|---| +| 16 | Share buttons: pure CSS/JS, position options, network selection | +| 16 | Social profiles management | +| 17 | Analytics: GA4 connector, GTM, pixel manager, custom scripts | +| 17 | SMTP: mailer override, email log, test email | +| 18 | GSC: OAuth flow, dashboard, keyword tracking display | + +### Phase 7: SEO Import (Days 19-20) + +| Day | Task | +|---|---| +| 19 | Yoast importer: read all Yoast meta keys, map to IGNY8 keys | +| 19 | RankMath importer: read all RankMath meta keys, map to IGNY8 keys | +| 20 | AIOSEO importer | +| 20 | Import UI: progress bar, background processing, completion report | + +### Phase 8: Connected Mode — Content Sync (Days 21-23) + +| Day | Task | +|---|---| +| 21 | API client: authenticate with IGNY8 platform, connection management | +| 21 | Content puller: fetch content from IGNY8 API | +| 22 | Content mapper: map IGNY8 content types to WP post types, handle images | +| 22 | Sync queue: pending/synced/failed status, retry logic | +| 23 | Publish scheduler: review queue, scheduled publishing | +| 23 | Sync dashboard: status, controls, history | + +### Phase 9: Connected Mode — SAG Structure (Days 24-27) + +| Day | Task | +|---|---| +| 24 | Blueprint sync: receive SAG structure JSON from IGNY8 platform | +| 24 | Blueprint review UI: show proposed taxonomies/terms before applying | +| 25 | Taxonomy builder: create WordPress taxonomies from SAG attributes | +| 25 | Term builder: create terms from attribute values, set hierarchies | +| 26 | Cluster manager: map clusters to hub pages/terms | +| 26 | Term content sync: populate term descriptions and landing page content | +| 27 | Structure visualizer: visual map of clusters → taxonomies → content | +| 27 | Connected enhancements: multi-keyword scoring, cluster-aware analysis, auto-linker | + +### Phase 10: Polish + Package (Days 28-30) + +| Day | Task | +|---|---| +| 28 | Cross-module testing: all modules enabled/disabled combinations | +| 28 | Performance: ensure zero frontend impact when features aren't used | +| 29 | WordPress.org compliance: readme.txt, screenshots, FAQ | +| 29 | Internationalization audit: all strings translatable | +| 30 | Build script: generate release zip | +| 30 | Documentation: hooks, filters, developer guide | + +--- + +## Part 10: Performance Rules + +The plugin must be invisible in terms of frontend performance when features aren't actively outputting content. + +| Rule | Implementation | +|---|---| +| Zero CSS on frontend unless share buttons are enabled | Conditional enqueue only | +| Zero JS on frontend unless share buttons or dynamic features are used | Conditional enqueue | +| All `` output in a single hook at priority 1 | No scattered wp_head hooks | +| Schema output as single JSON-LD block | Not multiple schema blocks | +| Admin assets only on IGNY8 admin pages | Screen check before enqueue | +| Meta box assets only on post editor screens | Screen check before enqueue | +| Site audit runs via WP Cron, never on page load | Background processing | +| Link crawl is background process, never blocks requests | WP Cron scheduled | +| All option reads use object cache when available | wp_cache_get/set | +| Connected mode API calls are async, never block page load | WP Cron + queue | + +--- + +## Part 11: WordPress.org Submission Requirements + +For free distribution on WordPress.org repo: + +- GPL v2+ license +- No phone-home without user consent +- No premium upsell in admin notices (only on dedicated settings page) +- All assets (CSS, JS, images) included — no external CDN +- No minified-only JS/CSS — source files must be readable +- Proper text domain and i18n +- Sanitize all inputs, escape all outputs +- Use WordPress APIs (no direct SQL without $wpdb) +- No tracking without opt-in +- readme.txt with proper headers, FAQ, changelog, screenshots + +--- + +*End of IGNY8 Plugin Build Plan* diff --git a/v2/Igny8 V2 New Final Plans/IGNY8-Rich-Schema-SERP-Enhancement-Module.docx b/v2/Igny8 V2 New Final Plans/IGNY8-Rich-Schema-SERP-Enhancement-Module.docx new file mode 100644 index 00000000..445ade7c Binary files /dev/null and b/v2/Igny8 V2 New Final Plans/IGNY8-Rich-Schema-SERP-Enhancement-Module.docx differ diff --git a/v2/Igny8 V2 New Final Plans/Linker Internal & External/IGNY8-Linker-Module-Visualization.html b/v2/Igny8 V2 New Final Plans/Linker Internal & External/IGNY8-Linker-Module-Visualization.html new file mode 100644 index 00000000..7833f056 --- /dev/null +++ b/v2/Igny8 V2 New Final Plans/Linker Internal & External/IGNY8-Linker-Module-Visualization.html @@ -0,0 +1,578 @@ + + + + + +IGNY8 Linker Module — SAG Authority Flow + + + + + + +
+
+ +
+
IGNY8 Linker Module
+
SAG Authority Flow Visualization
+
+
+
+ + + +
+
+ +
+ + + + +
+
+ +
+
+ + + + diff --git a/v2/Igny8 V2 New Final Plans/Linker Internal & External/IGNY8_Linker_FatGrid_PR_Analysis.md.pdf b/v2/Igny8 V2 New Final Plans/Linker Internal & External/IGNY8_Linker_FatGrid_PR_Analysis.md.pdf new file mode 100644 index 00000000..7563cef6 Binary files /dev/null and b/v2/Igny8 V2 New Final Plans/Linker Internal & External/IGNY8_Linker_FatGrid_PR_Analysis.md.pdf differ diff --git a/v2/Igny8 V2 New Final Plans/SAG-Doc3-Interlinking-Specification-PLAN.md b/v2/Igny8 V2 New Final Plans/SAG-Doc3-Interlinking-Specification-PLAN.md new file mode 100644 index 00000000..1b16f717 --- /dev/null +++ b/v2/Igny8 V2 New Final Plans/SAG-Doc3-Interlinking-Specification-PLAN.md @@ -0,0 +1,541 @@ +# Document 3 — SAG Interlinking Specification (Linker Module) + +## Detailed Section Plan + +**Version:** 1.0 | March 2026 +**Status:** Plan — Ready for section-by-section build +**Dependency:** SAG-IGNY8-Implementation.md (Section 14 pipeline, Section 16 data models, blueprint JSON) +**Target Format:** Markdown (.md) for IGNY8 repo use with Claude Code +**Estimated Length:** ~800-1,000 lines + +--- + +## Current State Summary (inputs to this document) + +### What Exists in IGNY8 Today +- **Linker module:** Backend at `business/linking/`, API at `modules/linker/`, frontend at `pages/Linker/` and `api/linker.api.ts` — all INACTIVE behind `linker_enabled` feature flag +- **Existing Linker capability** (pre-SAG): Finds link candidates based on content similarity, injects links with varied anchor text, configurable link density limits +- **Blueprint JSON** already has `internal_linking_map` field (currently `{"rules_reference": "SAG-Interlinking-Specification.md"}` — pointing to THIS document), `linked_attribute_terms` per cluster, `cross_cluster_links` per cluster, and `link_coverage_score` on SAGCluster model +- **Content model** has `sag_cluster_id` field (planned) — links content back to its cluster for linking rules +- **Pipeline Stage 7** (SAG-enhanced): "Pre-computed internal links ready" at review queue — means links are generated BEFORE publish, not after + +### What SAG-IGNY8-Implementation.md Already Defines +- Page types: Blog Post, Cluster Hub Page, Product Page, Service Page, Category Page, Attribute Term Page, Brand Page, Comparison Page +- Cluster types: Product/Service Category, Condition/Problem, Feature, Brand, Informational, Comparison — each has different hub page style +- Blueprint stores `linked_attribute_terms` (which taxonomy terms a cluster connects to) and `cross_cluster_links` (which other clusters share attribute values) +- Execution priority: Phase 1 = category pages + top hubs, Phase 2 = remaining hubs + first blogs, Phase 3 = attribute term pages, Phase 4 = additional blogs + brand comparisons +- Health monitoring already tracks "internal link coverage" as one of the weekly health check items + +### What the Niche Definition Process (Doc 2) Defines +- Each cluster has 1 hub page + 3-8 supporting content pieces +- Clusters form at 2+ attribute value intersections — two clusters sharing an attribute value are cross-link candidates +- Max 50 clusters per sector, backlink campaigns target top 25-30 — the other 20-25 rank purely through internal authority flow + +### What Content Types Plan Defines +- Taxonomy landing pages include "key subtopics + internal links" and "internal links to related clusters" as default sections +- Cluster hub pages aggregate related terms + posts + products + +### What the Taxonomy Term Content Plan Defines +- Term pages need "internal links to related clusters" as a standard section +- Cluster Hub Manager handles "cluster landing pages and cross-links" + +--- + +## Section Plan + +### Section 1: Purpose & Scope + +**Content:** +- Why SAG interlinking is fundamentally different from generic internal linking tools +- Generic linkers scan content for keyword matches and insert links randomly — SAG linking follows deterministic rules derived from the dimensional structure +- Every link has a structural purpose: it flows authority from backlinked pages down through the hierarchy and connects dimensionally-related content +- This document is the rules engine specification — it tells the IGNY8 Linker module exactly what links to create, where, with what anchor text, and in what priority order +- Scope: WordPress implementation first, platform-agnostic rules that translate to any CMS +- Dependency: Requires an active SAG Blueprint with populated clusters, published content, and WordPress taxonomies created + +**Inputs from existing docs:** SAG-IGNY8-Implementation.md Section 14.1 (Post-Publish → "Linker creates SAG-compliant internal links") + +--- + +### Section 2: Page Types in the Link Graph + +**Content:** +Define every page type that participates in the link graph, its role, and its WordPress implementation. Each type has different linking behavior. + +| Page Type | SAG Role | WordPress Implementation | Link Behavior | +|-----------|----------|------------------------|---------------| +| Homepage | T1 — authority entry point | Front page | Links to sector landing pages and top cluster hubs | +| Sector Landing Page | Sector overview | Page (or custom page template) | Links to all cluster hubs within sector | +| Cluster Hub Page | T2/T3 — authority distribution node | Page with hub template | Links DOWN to supporting content, ACROSS to related cluster hubs, UP to sector landing | +| Supporting Blog Post | T4 — content depth | Post | Links UP to its cluster hub (mandatory), ACROSS to sibling blogs in same cluster, ACROSS to related cluster hubs | +| Attribute Term Page | Taxonomy node connecting clusters | Custom taxonomy term archive with rich content | Links to ALL cluster hubs that use this attribute value | +| Product Page | Commercial page | WooCommerce product | Links to its cluster hub, to relevant attribute term pages | +| Service Page | Commercial page | Page with service template | Links to its cluster hub, to relevant attribute term pages | +| Category Page | Top-level grouping | Category archive with rich content | Links to cluster hubs within this category | +| Brand Page | Brand overview | Post or page | Links to cluster hubs featuring this brand | +| Comparison Page | Decision-stage content | Post | Links to both compared cluster hubs | + +**Key rule:** Every page except homepage must link to at least ONE cluster hub. No orphan pages in a SAG site. + +**Inputs from existing docs:** SAG-IGNY8-Implementation.md Section 11.2 (content type table), Section 12.2 (platform mapping table), Content_Types_Writing_Plan.md Section 2 + +--- + +### Section 3: Link Relationship Types + +**Content:** +Define the 7 directional link types the system generates. Each has specific rules. + +**Type 1: Vertical Upward (Supporting → Hub)** +- Every supporting blog post MUST link to its cluster hub page +- This is mandatory, not optional — enforced at content generation time +- Anchor text uses cluster's primary keyword or hub page title variant +- Placement: First mention of cluster topic in content body, ideally within first 2 paragraphs +- Count: Exactly 1 link to own hub per supporting article + +**Type 2: Vertical Downward (Hub → Supporting)** +- Every cluster hub page links to ALL its published supporting content +- Placement: Hub pages have a structured "Related Articles" or "In This Guide" section +- Plus contextual in-body links where naturally relevant +- Anchor text: Article title or primary keyword of the supporting piece + +**Type 3: Horizontal Sibling (Supporting ↔ Supporting within same cluster)** +- Supporting articles within the same cluster link to each other where topically relevant +- Not mandatory for every pair — only where semantic overlap creates a natural link opportunity +- Maximum 2 sibling links per article to avoid link dilution +- Anchor text: Natural descriptive phrases, varied per link + +**Type 4: Cross-Cluster (Hub ↔ Hub sharing attribute value)** +- Two cluster hubs that share an attribute value are cross-link candidates +- Example: "Foot × Neuropathy" and "Foot × EMS" both have Target Area = Foot → cross-link +- Maximum 2 cross-cluster links per hub page to avoid diluting the hub's primary focus +- Selection: Highest-value cross-links chosen by shared keyword volume overlap +- Anchor text: The linked hub's primary keyword or a natural variant + +**Type 5: Taxonomy Contextual (Term Page → Cluster Hubs)** +- Each attribute term page links to EVERY cluster hub that uses that attribute value +- Example: "Neuropathy" term page links to "Foot × Neuropathy", "EMS × Neuropathy", "Heated × Neuropathy" +- This is the dimensional connecting layer — term pages are the linking nodes of the grid +- Anchor text: Hub page title or cluster primary keyword + +**Type 6: Breadcrumb Structural** +- Every page has a breadcrumb path: Home → Sector → [Attribute Term or Category] → Hub → Current Page +- These are navigational links, always present in page template +- Not counted toward content link density limits + +**Type 7: Related Content (Cross-Cluster, Semantic)** +- For supporting blogs, a "Related Reading" or "You May Also Like" section with 2-3 links to content in OTHER clusters +- Selected by: shared attribute values (not same cluster), complementary topics, user journey logic +- This is the weakest link type — lowest priority, most likely to be omitted if link density cap is reached + +**Inputs from existing docs:** Blueprint JSON `linked_attribute_terms` field (Type 5), `cross_cluster_links` field (Type 4), Taxonomy_Term_Content_Plan.md Section 7 item 5 ("internal links to related clusters") + +--- + +### Section 4: Authority Flow Model + +**Content:** +How external backlink authority distributes through the SAG structure via internal links. This is the mechanism behind the "compounding authority effect." + +**Flow path:** +1. External backlinks hit homepage (T1) and top 25-30 cluster hub pages (T2/T3) +2. Hub pages distribute authority DOWN to 3-8 supporting articles each +3. Supporting articles link BACK UP to hub (reinforcing) and ACROSS to siblings (spreading) +4. Attribute term pages act as horizontal connectors — they link to ALL hubs sharing that attribute value, creating cross-cluster authority flow +5. Clusters WITHOUT direct backlinks receive authority through: cross-cluster links from backlinked hubs, term page connections from shared attribute values, and sibling blog cross-references + +**Why this compounds:** +- Every new piece of content in a cluster strengthens the hub (more upward links) +- Every new cluster that shares an attribute value strengthens the term page (more hub links feeding into it) +- The term page then distributes that combined authority to ALL connected hubs +- Result: A site at DR 29 can dominate country-level rankings for thousands of queries because the internal structure amplifies whatever external authority exists + +**Maximum hop distance:** Any page should be reachable from a backlinked page within 3 link hops. If a page requires 4+ hops, it needs a direct cross-link from a higher-authority page. + +**Visualization:** Include a flow diagram showing Homepage → Sector → Hubs (backlinked) → Supporting Content → Term Pages → Other Hubs (not backlinked) with authority flow arrows + +**Inputs from existing docs:** Transcript discussion of T1-T5 tier system, SAG-IGNY8-Implementation.md Section 14.3 (health monitoring tracks link coverage), SAG compounding authority evidence from MassagerSmart (DR 29 dominating country rankings) + +--- + +### Section 5: Link Scoring & Priority Algorithm + +**Content:** +When the Linker has multiple potential links to create (especially for cross-cluster and related content links), it needs a scoring system to select the highest-value links. + +**Scoring factors:** + +| Factor | Weight | Logic | +|--------|--------|-------| +| Shared attribute values | 40% | More shared values = stronger topical relevance | +| Target page authority | 25% | Pages with backlinks or higher link_coverage_score get priority | +| Keyword overlap | 20% | Cluster keyword lists compared — higher overlap = more relevant link | +| Content recency | 10% | Newer content gets slight priority to accelerate indexing | +| Current link count gap | 5% | Pages below minimum inbound links get priority | + +**Priority ordering for link creation:** +1. Mandatory links first (Type 1: supporting → hub — always created) +2. Hub → supporting links (Type 2 — always created for published content) +3. Term page → hub links (Type 5 — always created) +4. Cross-cluster hub links (Type 4 — top 2 by score) +5. Sibling links (Type 3 — top 2 by score) +6. Related content links (Type 7 — fill remaining capacity) + +**Inputs from existing docs:** SAGCluster model has `link_coverage_score` field, blueprint health monitoring tracks internal link coverage + +--- + +### Section 6: Anchor Text Generation Rules + +**Content:** +Anchor text strategy per link type to avoid over-optimization while maximizing keyword relevance. + +| Link Type | Anchor Text Strategy | Examples | +|-----------|---------------------|----------| +| Supporting → Hub | Primary keyword of hub (60%), hub title variant (30%), natural phrase (10%) | "foot massagers for neuropathy", "our neuropathy foot massager guide", "learn more about neuropathy relief" | +| Hub → Supporting | Article title (70%), primary keyword (20%), descriptive (10%) | "Doctor-Recommended Foot Massagers for Neuropathy", "doctor-recommended neuropathy massagers" | +| Sibling → Sibling | Natural contextual phrase (60%), article keyword (30%), generic (10%) | "comparing EMS and TENS therapy", "EMS vs TENS for neuropathy" | +| Cross-Cluster Hub → Hub | Target hub primary keyword (50%), descriptive (40%), generic (10%) | "EMS foot massagers", "explore our EMS foot massager guide" | +| Term Page → Hub | Hub primary keyword (50%), hub title (40%), descriptive (10%) | "best foot massagers for neuropathy", "Foot Massagers for Neuropathy Guide" | +| Breadcrumb | Page title (100%) | Always the page title — no variation | +| Related Content | Natural phrase (80%), generic (20%) | "you might also find this helpful", "related: heated massagers for circulation" | + +**Hard rules:** +- No exact-match anchor text used more than 3 times across the entire site for the same target URL +- Anchor text must be grammatically natural in context — never force a keyword phrase that breaks sentence flow +- Never use "click here", "read more", or "this article" as anchor text +- Maximum anchor text length: 8 words +- Minimum anchor text length: 2 words + +--- + +### Section 7: Link Density Enforcement + +**Content:** +Maximum and minimum outbound/inbound link counts per page type to prevent over-linking or under-linking. + +| Page Type | Min Outbound | Max Outbound | Min Inbound | Notes | +|-----------|-------------|-------------|-------------|-------| +| Homepage | 5 | 15 | N/A (external) | Links to top hubs + sector pages | +| Cluster Hub | 5 | 20 | 3 | Must link to all supporting + 2 cross-cluster | +| Supporting Blog (<1000 words) | 2 | 5 | 1 | Must include hub link | +| Supporting Blog (1000-2000 words) | 3 | 8 | 1 | Must include hub link | +| Supporting Blog (2000+ words) | 4 | 12 | 1 | Must include hub link | +| Attribute Term Page | 3 | unlimited | 0 | Links to ALL connected hubs (no cap) | +| Product Page | 2 | 5 | 1 | Hub + relevant term pages | +| Service Page | 2 | 5 | 1 | Hub + relevant term pages | + +**Override logic:** +- If a hub has 10+ supporting articles, max outbound for hub increases to 25 (listing them all adds value) +- If content is a mega-guide (3000+ words), max outbound increases to 15 +- User can manually override density limits per page in IGNY8 UI + +**Density ratio:** Outbound links per 300 words of content, with a target of 1-2 links per 300 words for body content. Navigational sections (related articles, breadcrumbs) don't count toward this ratio. + +--- + +### Section 8: Cross-Cluster & Cross-Sector Linking Logic + +**Content:** +Detailed rules for when and how to create links between clusters. + +**Cross-cluster within same sector:** +- Two clusters are cross-link candidates when they share at least 1 attribute value +- Example: "Foot × Neuropathy" and "Foot × Plantar Fasciitis" share Target Area = Foot +- The Linker checks `attribute_intersection` JSON of both clusters for shared values +- Maximum 2 cross-cluster outbound links per hub page +- Selection: Score all candidates by the scoring algorithm (Section 5), pick top 2 + +**Cross-sector (multi-sector sites):** +- Same logic but across sectors — two clusters from different sectors sharing an attribute value +- These are rarer and higher-value because they connect separate topical areas +- Example: "Agile PM Tools" (PM sector) and "Sprint Planning CRM" (CRM sector) both have Use Case = Agile +- Cross-sector links get a 1.5x score multiplier because they're harder for competitors to replicate +- Maximum 1 cross-sector link per hub page (don't dilute primary sector authority) + +**Shared attribute value check (pseudocode):** +``` +for each cluster_a.hub_page: + candidates = [] + for each cluster_b in blueprint.clusters: + if cluster_b == cluster_a: skip + shared = intersection(cluster_a.attribute_values, cluster_b.attribute_values) + if len(shared) >= 1: + score = calculate_link_score(cluster_a, cluster_b, shared) + candidates.append((cluster_b, score)) + sort candidates by score desc + create_links(top 2 candidates) +``` + +**Inputs from existing docs:** Blueprint JSON `cross_cluster_links` field already stores these relationships per cluster + +--- + +### Section 9: Link Injection Method + +**Content:** +Where exactly in the content links get placed. + +**During content generation (New Content Mode):** +- AI content generation prompts include link injection instructions +- Links are placed BEFORE content enters the review queue (pipeline Stage 7 reference) +- Writer module receives link targets from the Linker as part of the task context + +**Link placement zones per page type:** + +**Blog Posts / Supporting Content:** +- Zone 1: In-body contextual (primary) — links woven into paragraph text where topically natural + - Hub link: Within first 2 paragraphs, at first natural mention of cluster topic + - Sibling links: In relevant body sections, natural context + - Cross-cluster links: In sections discussing related topics +- Zone 2: "Related Reading" section at end of article (2-3 links) +- Zone 3: Breadcrumb at top (structural, always present) + +**Cluster Hub Pages:** +- Zone 1: In-body contextual — links to supporting content within guide sections +- Zone 2: "Articles in This Guide" / "Complete Guide Contents" section — all supporting articles listed +- Zone 3: "Related Topics" section — cross-cluster hub links (max 2) +- Zone 4: Breadcrumb at top + +**Attribute Term Pages:** +- Zone 1: Intro paragraph — link to the primary cluster hub for this term +- Zone 2: "Explore by Topic" section — all connected cluster hubs listed with brief descriptions +- Zone 3: "Top [Term] Products/Services" — links to relevant products/services +- Zone 4: "Related Guides" — links to supporting blogs across clusters + +**Product/Service Pages:** +- Zone 1: In description — link to cluster hub this product belongs to +- Zone 2: "Specifications" or "Details" section — links to attribute term pages for the product's attribute values +- Zone 3: "Related Products" — sibling products in same cluster + +--- + +### Section 10: Existing Content Audit Mode + +**Content:** +How the Linker scans already-published content and identifies missing SAG links. + +**Trigger:** User clicks "Audit Links" in Linker module, or automatic weekly scan via blueprint health monitoring + +**Audit process:** +1. Load active blueprint — get all clusters, page types, expected link relationships +2. Crawl all published content (from IGNY8 content records, not live site) +3. For each page, extract all outbound links (parse HTML content) +4. Compare actual links vs expected links per the rules in Sections 3-8 +5. Generate gap report + +**Gap report output per page:** +- Missing mandatory links (e.g., blog post has no link to its hub) +- Missing cross-cluster links (hub has 0 of 2 recommended) +- Missing attribute term links +- Over-linked pages (exceeding density limits) +- Orphan pages (no inbound links from any SAG page) + +**Recommendation generation:** +- For each missing link: target URL, suggested anchor text (3 variants), suggested placement zone +- For over-linked pages: which links to remove (lowest-scoring by algorithm) +- Priority ordering: mandatory gaps first, then high-authority gaps, then nice-to-haves + +**User workflow:** Linker presents recommendations → user approves/rejects per link → approved links auto-injected into content → content republished to WordPress + +--- + +### Section 11: New Content Mode + +**Content:** +How links are automatically inserted during content generation, before the content enters the review queue. + +**Integration point:** Pipeline Stage 4 (Content Generation) → Linker adds link context to Writer task + +**Flow:** +1. Writer task created with `sag_cluster_id` and `blueprint_context` +2. Before content generation, Linker calculates required links for this content piece: + - What cluster is this? → Mandatory link to cluster hub + - What page type is this? → Apply density rules + - What sibling content exists in this cluster? → Sibling link candidates + - What cross-cluster opportunities exist? → Cross-cluster candidates +3. Link targets + anchor text suggestions passed to AI content generation prompt +4. AI generates content WITH links embedded +5. Post-generation link validation: verify all mandatory links present, density within limits +6. Content enters review queue with links pre-inserted + +**Prompt enhancement (added to Thinker prompts):** +``` +Link requirements for this content: +- MANDATORY: Link to [hub_url] with anchor text "[primary_keyword]" within first 2 paragraphs +- RECOMMENDED: Link to [sibling_url_1] with anchor "[suggested_anchor]" where contextually relevant +- RECOMMENDED: Link to [cross_cluster_url] with anchor "[suggested_anchor]" if topic comes up naturally +- Total outbound links: [min]-[max] based on content length +- Do NOT use "click here" or "read more" as anchor text +``` + +--- + +### Section 12: Link Health Monitoring + +**Content:** +Ongoing monitoring that feeds into the SAG Health Score. + +**Checks (run weekly or on-demand):** +- Broken links: Published URLs that return 404 or redirect chains +- Orphan pages: Pages with 0 inbound SAG links (every page should have at least 1) +- Authority flow gaps: Clusters where hub has backlinks but supporting content has <2 inbound links +- Over-linked pages: Pages exceeding density maximums +- Missing mandatory links: Any supporting blog without a hub link +- Stale cross-links: Cross-cluster links pointing to hubs whose clusters have been restructured +- Anchor text over-optimization: Same exact anchor pointing to same URL more than 3 times site-wide + +**Health score contribution:** +The link coverage score (0-100) on SAGCluster model is calculated as: +- Hub page published and has all mandatory links? (25 points) +- All supporting content links back to hub? (25 points) +- At least 1 cross-cluster link on hub? (15 points) +- All attribute term pages link to this hub? (15 points) +- No broken links within cluster? (10 points) +- Density within limits for all cluster pages? (10 points) + +**Alert thresholds:** +- Cluster link score < 50: Flag as "needs attention" in dashboard +- Orphan page detected: Immediate alert +- Broken link detected: Add to fix queue +- 3+ same exact anchor text: Over-optimization warning + +--- + +### Section 13: Reporting & Visualization + +**Content:** +What the Linker module shows in the IGNY8 UI. + +**Cluster-Level Link Coverage Report:** +- Table showing all clusters with: cluster name, hub status (published/draft/missing), supporting content count, link coverage score, missing links count +- Color coding: green (score 80+), yellow (50-79), red (<50) +- Click into cluster → see all pages, all links, all gaps + +**Site-Wide Link Map:** +- Visual showing clusters as nodes, with lines connecting cross-linked hubs +- Attribute term pages as connecting nodes between clusters +- Thickness of lines = number of links between nodes +- Helps users see which parts of the grid are well-connected vs isolated + +**Link Audit Dashboard:** +- Total links site-wide +- Missing mandatory links count +- Orphan pages count +- Over-linked pages count +- Top 10 most-linked pages (should be hubs) +- Top 10 least-linked pages (should be investigated) +- Average links per page by type + +**Gap Analysis Export:** +- Downloadable report of all missing links with recommendations +- Format matching existing IGNY8 export patterns + +--- + +### Section 14: Data Models + +**Content:** +New models and fields needed for the Linker module. + +**SAGLink (new model)** +``` +- id (UUID) +- blueprint_id (FK → SAGBlueprint) +- source_content_id (FK → Content) +- target_content_id (FK → Content, nullable — for external/term page targets) +- target_url (String — for term pages or external) +- link_type (Enum: hub_upward, hub_downward, sibling, cross_cluster, taxonomy_contextual, breadcrumb, related_content) +- anchor_text (String) +- placement_zone (Enum: in_body, related_section, breadcrumb, specification, guide_contents) +- status (Enum: planned, injected, published, broken, removed) +- score (Float — from scoring algorithm) +- created_at, injected_at +``` + +**SAGLinkAudit (new model)** +``` +- id (UUID) +- blueprint_id (FK → SAGBlueprint) +- audit_date (DateTime) +- total_links (Integer) +- missing_mandatory (Integer) +- orphan_pages (Integer) +- broken_links (Integer) +- over_linked_pages (Integer) +- cluster_scores (JSON — {cluster_id: score} map) +- recommendations (JSON — array of link recommendations) +``` + +**Modified existing models:** +- SAGCluster: `link_coverage_score` already defined — this doc defines how it's calculated (Section 12) +- Content: Add `outbound_link_count` (Integer), `inbound_link_count` (Integer) — cached counters + +--- + +### Section 15: Integration with IGNY8 Pipeline + +**Content:** +How the Linker module fits into the existing IGNY8 workflow and automation. + +**Manual mode:** +- User publishes content → clicks "Generate Links" in Linker → reviews recommendations → approves → links injected +- User runs "Audit Links" → sees gap report → approves fixes → links updated + +**Automation mode (pipeline extension):** +- After Stage 7 (images generated), new Stage 8: Link Generation + - Load blueprint, get cluster context for this content + - Generate required links per rules + - Inject into content HTML + - Content enters review queue with links already present +- After publish → async link audit checks all pages in cluster for completeness + +**WordPress plugin integration:** +- When content publishes to WordPress, links are already in the HTML +- Plugin does NOT need to do link processing — IGNY8 app handles all link logic +- Plugin reports back published URL → IGNY8 updates SAGLink records with final published URLs + +--- + +### Section 16: MassagerSmart Reference Example + +**Content:** +Walk through the complete interlinking architecture for MassagerSmart.com as the reference implementation. + +**Example cluster: "Foot Massagers for Neuropathy"** +- Hub page: "Best Foot Massagers for Neuropathy & Nerve Pain Relief" + - Links DOWN to: "Doctor-Recommended Foot Massagers for Neuropathy", "EMS vs TENS for Neuropathy", "Does a Foot Massager Actually Help Neuropathy?" + - Links ACROSS to: "EMS Foot Massagers" hub (shared value: Foot), "Heated Foot Massagers" hub (shared value: Foot) + - Links UP to: Sector landing page +- Supporting blog: "Doctor-Recommended Foot Massagers for Neuropathy" + - Links UP to: Hub page (mandatory) + - Links to SIBLING: "EMS vs TENS for Neuropathy" (shared cluster) + - Links to RELATED: "Shiatsu Foot Massagers" hub (different cluster, related topic) +- Attribute Term Page: "Neuropathy" + - Links to: "Foot Massagers for Neuropathy" hub, "EMS Massagers for Neuropathy" hub, "Heated Massagers for Neuropathy" hub — all hubs where Relief Focus = Neuropathy + +Show the complete link map for 3-4 clusters demonstrating all 7 link types in practice. + +--- + +### Section 17: Cross-References + +**Content:** +- SAG Master Document — Pure methodology reference +- SAG Implementation for IGNY8 — Three-layer architecture, blueprint JSON, data models, pipeline integration (primary dependency) +- SAG Niche Definition Process — Cluster formation rules that determine link structure (Document 2) +- SAG Backlink Campaign Specification — External links that feed the internal authority flow (Document 4) + +--- + +## Build Plan + +This document will be built as Markdown (.md) for the IGNY8 repo, matching the format of SAG-IGNY8-Implementation.md. Estimated 800-1,000 lines across 17 sections. Can be built section by section in one session, or split into 2 sessions if needed. + +Sections 1-4 establish the conceptual framework (page types, link types, authority flow). +Sections 5-8 define the rules engine (scoring, anchors, density, cross-cluster). +Sections 9-11 define the two operating modes (audit existing, generate for new). +Sections 12-13 define monitoring and reporting. +Sections 14-15 define data models and pipeline integration. +Section 16 is the worked example. +Section 17 is cross-references. diff --git a/v2/Igny8 V2 New Final Plans/SAG-IGNY8-Implementation.md b/v2/Igny8 V2 New Final Plans/SAG-IGNY8-Implementation.md new file mode 100644 index 00000000..bf47ab83 --- /dev/null +++ b/v2/Igny8 V2 New Final Plans/SAG-IGNY8-Implementation.md @@ -0,0 +1,1278 @@ +# SAG Implementation for IGNY8 — Foundational Architecture Document + +**Version:** 2.0 +**Status:** Definitive Implementation Reference +**Scope:** Three-layer SAG architecture, two entry scenarios, and complete integration with IGNY8 platform +**Dependency:** SAG-Master-Document.md (pure SAG methodology reference) +**Usage:** Development reference for IGNY8 app, plugin, and AI prompt engineering. Designed for use in development IDE with Claude Code. + +--- + +## Table of Contents + +1. [Executive Summary](#1-executive-summary) +2. [Terminology](#2-terminology) +3. [The Problem SAG Solves in IGNY8](#3-the-problem-sag-solves-in-igny8) +4. [Three-Layer SAG Architecture](#4-three-layer-sag-architecture) +5. [Layer 1: Attribute Framework](#5-layer-1-attribute-framework) +6. [Layer 2: Attribute Population](#6-layer-2-attribute-population) +7. [Layer 3: Cluster Formation & Keyword Generation](#7-layer-3-cluster-formation--keyword-generation) +8. [Case 1: Existing Site Intelligence](#8-case-1-existing-site-intelligence) +9. [Case 2: New Site from Scratch](#9-case-2-new-site-from-scratch) +10. [The SAG Blueprint](#10-the-sag-blueprint) +11. [Content Idea Generation from Clusters](#11-content-idea-generation-from-clusters) +12. [Content Type Mapping Across Platforms](#12-content-type-mapping-across-platforms) +13. [Taxonomy Creation Flow](#13-taxonomy-creation-flow) +14. [Integration with IGNY8 Pipeline](#14-integration-with-igny8-pipeline) +15. [AI Prompt Architecture](#15-ai-prompt-architecture) +16. [Data Models & Schema](#16-data-models--schema) +17. [Implementation Phases](#17-implementation-phases) + +--- + +## 1. Executive Summary + +IGNY8 currently operates as a keyword-driven content pipeline: users add keywords, AI clusters them by semantic similarity, content is generated and published. This produces functional content but does not produce SAG-quality site architecture. The clustering is flat, has no structural intelligence, and depends entirely on the quality of user keyword selection. + +This document defines how IGNY8 evolves into a **site architecture engine** that implements the Semantic Authority Grid methodology. The core innovation: site structure is generated from **attribute-based intelligence** — not from keywords. Keywords become an output of the structure, not an input. + +The system works through three layers: +- **Layer 1:** Define what attributes organize this sector (e.g., Target Area, Device Type, Relief Focus) +- **Layer 2:** Populate attribute values from real data (e.g., Foot, Shiatsu, Neuropathy) +- **Layer 3:** Form clusters from meaningful attribute intersections, auto-generate keywords from those intersections + +Two entry scenarios feed the same architecture: +- **Case 1 (Existing Site):** AI extracts attributes and values from real site data (products, categories, content) +- **Case 2 (New Site):** AI generates attribute framework from sector intelligence + user inputs + +Both produce a unified **SAG Blueprint** that drives content generation, taxonomy creation, template assignment, internal linking, and backlink planning — without requiring the user to research or add a single keyword. + +--- + +## 2. Terminology + +Every term used in this document has exactly one meaning. These align with IGNY8's existing vocabulary where possible and extend it where needed. + +### 2.1 SAG Architecture Terms + +| Term | Definition | Example | Becomes in WordPress | +|------|-----------|---------|---------------------| +| **Industry** | Top-level business category. Pre-defined in IGNY8. | Health & Wellness, Automotive, Technology | — | +| **Sector** | Specific niche within an industry. Pre-defined in IGNY8. A site can have 1-5 sectors. | Personal Massagers, Auto Repair, Cloud Services | — | +| **Attribute** | A classification axis or facet that organizes the sector. Each attribute represents one way to categorize content, products, or services. | Target Area, Device Type, Relief Focus, Therapy Method | Custom taxonomy | +| **Attribute Value** | A specific option within an attribute. Each value can become a taxonomy term with its own SEO landing page. | Foot, Shiatsu, Neuropathy, Heated, Renpho | Taxonomy term | +| **Cluster** | A meaningful intersection of 2+ attribute values, forming a self-contained topical ecosystem. Each cluster has a hub page and supporting content. | Foot × Neuropathy = "Foot Massagers for Neuropathy" | IGNY8 Cluster taxonomy term | +| **Keyword** | A search term that real users type into search engines. Keywords naturally emerge from attribute value combinations within clusters, or are manually added and mapped to clusters. | "foot massager for neuropathy", "best ems foot massager nerve pain" | Target keyword for content | + +### 2.2 IGNY8 Content Terms (Existing — Preserved) + +| Term | Definition | Example | Notes | +|------|-----------|---------|-------| +| **Sector** | Already exists in IGNY8 Ideas/Content system. Content is tagged with its sector. | Printing Services, Personal Massagers | No change needed | +| **Structure** | Content format/approach. Determines how the content is written. | Comparison, Guide Tutorial, How To, Question, Review, Top Listicle | Already exists in IGNY8 Ideas UI | +| **Type** | What kind of page/content this is. Determines the WordPress post type and page template. | Blog Post, Cluster Hub Page, Product Page, Attribute Term Page, Category Page, Service Page | Extends current Post/Page to include all SAG content types | +| **Cluster** | Already exists in IGNY8 Ideas/Content system. Content is tagged with its cluster. | "UK Sign Shops and Local Sign Making Services" | Enhanced: now generated from attribute intersections instead of keyword grouping | + +### 2.3 The Complete Hierarchy + +``` +Industry + └── Sector(s) + └── Attributes (classification axes for the sector) + └── Attribute Values (specific options per attribute) + └── Clusters (meaningful intersections of 2+ attribute values) + └── Keywords (emerge naturally from cluster's attribute combination) + └── Content Ideas (specific content pieces with Structure + Type) + └── Content (generated articles, pages, products) +``` + +### 2.4 What Changed from Current IGNY8 + +| Current IGNY8 | SAG-Enhanced IGNY8 | +|--------------|-------------------| +| Industry/Sector = keyword database filter only | Industry/Sector = carries attribute framework (NEW data layer) | +| Clusters formed from keyword grouping | Clusters formed from attribute value intersections | +| Keywords must be added first, structure follows | Structure comes first, keywords emerge from it | +| All clusters produce same content type | Clusters have types that determine content structure | +| No custom taxonomy generation | Attributes become WordPress custom taxonomies automatically | +| Sector has no structural intelligence | Sector carries complete attribute definitions | + +--- + +## 3. The Problem SAG Solves in IGNY8 + +### 3.1 Current State + +IGNY8's existing clustering takes user-provided keywords and groups them by semantic similarity using AI. This works for content writing — keywords get organized, ideas get generated, articles get written. But it fails at site architecture because: + +1. **Structure depends on keyword quality.** A user who selects incomplete keywords gets an incomplete site structure. The architecture is only as good as the keyword input. + +2. **No attribute awareness.** The system doesn't know that "Massager Type" and "Relief Focus" are fundamental organizing axes for a massager site. It just sees keywords as flat text. + +3. **No cluster types.** Every cluster produces the same kind of output. A product category cluster, a condition/problem cluster, and a brand comparison cluster all get treated identically. + +4. **No taxonomy derivation.** IGNY8 creates IGNY8 Sectors and IGNY8 Clusters as WordPress taxonomies, but it doesn't create the product attributes and custom taxonomies (Massager Type, Relief Focus, Therapy Method) that make a site dimensionally rich. Those were manually created on MassagerSmart. + +5. **No keyword-free operation.** Without keywords, IGNY8 can't do anything. The entire pipeline stalls at step 1. + +### 3.2 Target State + +After SAG implementation, IGNY8 will: + +- Generate a complete site architecture from sector selection alone — no keywords needed +- Auto-generate 300-500+ keyword variants from attribute value combinations +- Form clusters from attribute intersections with proper type classification +- Create WordPress custom taxonomies from attributes automatically +- Generate content ideas per cluster with correct Structure and Type +- Produce different content for different cluster types (hub pages, blog posts, product pages, term pages) +- Allow users to add more keywords that map into the pre-existing structure +- Work identically across WordPress, and in future Shopify and custom sites (same concepts, platform-specific terminology) + +--- + +## 4. Three-Layer SAG Architecture + +### 4.1 Overview + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ LAYER 1: ATTRIBUTE FRAMEWORK │ +│ │ +│ "What attributes organize this sector?" │ +│ │ +│ Input: Industry + Sector(s) │ +│ Output: Attribute definitions (axes without values) │ +│ Source: New attribute data layer (to be built) + AI generation │ +│ │ +│ Example output: │ +│ Attributes: [Target Area, Device Type, Relief Focus, │ +│ Therapy Method, Brand, Features] │ +└──────────────────────────────┬──────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────┐ +│ LAYER 2: ATTRIBUTE POPULATION │ +│ │ +│ "What specific values exist for each attribute?" │ +│ │ +│ Input: Attribute framework + real-world data │ +│ Output: Attributes with populated values │ +│ Source: Site data (Case 1) OR user inputs (Case 2) + AI │ +│ │ +│ Example output: │ +│ Target Area: [Foot, Neck, Face] │ +│ Device Type: [Shiatsu, EMS, Heated, Percussion] │ +│ Relief Focus: [Neuropathy, Plantar Fasciitis, Circulation] │ +└──────────────────────────────┬──────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────┐ +│ LAYER 3: CLUSTER FORMATION & KEYWORD GENERATION │ +│ │ +│ "What clusters form at attribute intersections? │ +│ What keywords naturally emerge from those clusters?" │ +│ │ +│ Input: Populated attributes │ +│ Output: Clusters + auto-generated keywords + content plan │ +│ Source: AI analysis of meaningful intersections │ +│ │ +│ Example output: │ +│ Cluster: Foot × Neuropathy │ +│ → Hub: "Best Foot Massagers for Neuropathy" │ +│ → Keywords: "foot massager for neuropathy", │ +│ "best foot massager neuropathy", │ +│ "ems foot massager nerve pain", ... │ +│ → Supporting content: 4-6 blog topics │ +└──────────────────────────────┬──────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────┐ +│ SAG BLUEPRINT │ +│ │ +│ Complete site architecture: Clusters (typed) + Taxonomies + │ +│ Keywords + Content plan + URL structure + Internal linking map │ +│ │ +│ → Feeds IGNY8 Pipeline: Ideas → Writer → Images → Publish → Link │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### 4.2 Key Principle: Attributes Before Everything + +**Current IGNY8 flow:** +User adds keywords → AI clusters keywords → Ideas → Content + +**SAG flow:** +Sector selected → Attributes defined → Values populated → Clusters form at intersections → Keywords auto-generated → Ideas created per cluster → Content generated per type → Published → Interlinked + +The user never needs to add a keyword. The system generates its own keyword base from the attribute structure. Users CAN add keywords to enhance coverage, but the system operates independently of manual keyword input. + +--- + +## 5. Layer 1: Attribute Framework + +### 5.1 What Layer 1 Provides + +Layer 1 answers: "For this sector, what are the natural classification axes?" + +This is sector-level knowledge. You don't need keywords or products to know that a massager e-commerce site will have attributes like Target Area, Device Type, Relief Focus, and Brand. You don't need keywords to know that a law firm will have attributes like Practice Area, Case Type, Client Type, and Location. + +### 5.2 Current State: No Attribute Data Exists + +**Critical clarification:** IGNY8's current industry/sector system is a flat classification used only to filter the keyword database. Selecting "Health & Wellness → Personal Massagers" currently provides zero structural intelligence — no attributes, no values, no cluster patterns. + +**Layer 1 requires building a completely new data layer** that attaches attribute definitions to each sector. This is a significant new effort, not an extension of existing sector data. + +### 5.3 Attribute Data Structure + +Each sector has an attribute framework definition: + +```json +{ + "sector": "Personal Massagers", + "industry": "Health & Wellness", + "site_type": "e-commerce", + "attributes": [ + { + "name": "Target Area", + "description": "Body area the device targets", + "level": "primary", + "suggested_values": ["Neck", "Back", "Foot", "Face", "Eye", "Scalp", "Shoulder", "Full Body"] + }, + { + "name": "Device Type", + "description": "Technology or mechanism of the massager", + "level": "primary", + "suggested_values": ["Shiatsu", "EMS", "Percussion", "Vibration", "Roller", "LED", "Microcurrent", "Heated"] + }, + { + "name": "Relief Focus", + "description": "Health condition or therapeutic goal", + "level": "secondary", + "suggested_values": ["Neuropathy", "Plantar Fasciitis", "Circulation", "Pain Relief", "Muscle Recovery", "Skin Tightening"] + }, + { + "name": "Therapy Method", + "description": "Therapeutic approach or technique", + "level": "secondary", + "suggested_values": ["Electrical Stimulation", "Deep Tissue", "Kneading", "TENS Therapy", "NMES Therapy", "Heat Therapy"] + }, + { + "name": "Brand", + "description": "Manufacturer or brand name", + "level": "tertiary", + "suggested_values": [] + }, + { + "name": "Features", + "description": "Product features and characteristics", + "level": "tertiary", + "suggested_values": ["Cordless", "Portable", "Waterproof", "Rechargeable"] + } + ] +} +``` + +### 5.4 Attribute Levels + +| Level | Purpose | WordPress Mapping | Content Impact | +|-------|---------|------------------|----------------| +| **Primary** | Main site navigation axes. Define the top-level structure. | Hierarchical category or main custom taxonomy | Category pages, primary URL segments | +| **Secondary** | Important classification that creates cluster depth. | Custom taxonomy (non-hierarchical) | Cluster formation axes, attribute term landing pages | +| **Tertiary** | Descriptive attributes for filtering and tagging. | Tags or flat custom taxonomy | Product filters, content tags, minor landing pages | + +### 5.5 Building the Attribute Data Layer + +**Phase 1: Manual Creation (High Quality)** +For the 12+ industries already in IGNY8 with their 60-120 sector combinations, attribute frameworks are manually crafted. This is the gold standard — each sector gets a reviewed, validated attribute definition. + +**Phase 2: AI-Assisted Generation** +For new industries/sectors not covered by manual creation, AI generates attribute frameworks using: +- Sector knowledge from training data +- Pattern matching from similar manually-created sector frameworks +- Competitive intelligence (analyzing top-ranking sites in the sector) + +**Phase 3: User-Contributed Refinement** +Users can add custom attributes during setup. Over time, commonly-added custom attributes get promoted to the sector's default framework. + +### 5.6 Multi-Sector Attribute Merging + +When a site has multiple sectors (e.g., "Auto Repair" + "Electric Vehicles"): + +1. **Identical attributes combine** — both have "Vehicle Type" → merge value lists +2. **Unique attributes add** — "Battery Technology" from EV sector adds as sector-specific attribute +3. **Cross-sector clusters can form** — intersections that span both sectors create unique content opportunities (e.g., "Electric Vehicle Brake Repair") + +--- + +## 6. Layer 2: Attribute Population + +### 6.1 What Layer 2 Provides + +Layer 1 gives the axes — "this sector has Target Area, Device Type, Relief Focus." Layer 2 fills in the actual values — "THIS site's Target Area values are Foot, Neck, and Face (not Back, Eye, or Scalp)." + +### 6.2 Population Sources by Scenario + +**Case 1 (Existing Site):** +The IGNY8 plugin sends product/content data from the WordPress site. AI analyzes product titles, descriptions, existing categories, and existing attributes to extract what values actually exist. + +A product titled "Nekteck Shiatsu Neck and Back Massager with Heat" tells the AI: +- Target Area values: Neck, Back +- Device Type values: Shiatsu +- Feature values: Heated +- Brand values: Nekteck + +Across 50 products, the AI builds the complete value set for each attribute. + +**Case 2 (New Site):** +Values come from user inputs during setup ("What body areas do your products target?", "What device types do you sell?"), supplemented by the sector framework's suggested values. The user confirms, prunes, or adds to suggestions. + +### 6.3 Right-Sizing to the Site + +The sector framework might suggest 8 Target Area values, but a specific site only sells foot and neck massagers. Layer 2 prunes to just Foot and Neck. This dramatically simplifies the resulting structure — fewer clusters, fewer taxonomy terms, fewer pages — all perfectly matched to the actual business. + +**Pruning rules:** +- Primary attribute with only 1 value → demote to secondary (the entire site is about that one thing, so it's not a differentiating axis) +- Secondary attribute with only 1 value → demote to tertiary +- Tertiary attribute with 0 values → exclude entirely +- User always has final override + +### 6.4 Completeness Assessment + +After population, each attribute gets a readiness score: + +| Score | Meaning | Action | +|-------|---------|--------| +| **Ready** | 3+ values populated | Proceed to cluster formation | +| **Thin** | 1-2 values only | AI suggests additions; user confirms | +| **Empty** | No values | Attribute excluded from blueprint OR user prompted | + +All primary attributes must be "Ready" before the SAG Blueprint can be generated. + +--- + +## 7. Layer 3: Cluster Formation & Keyword Generation + +### 7.1 How Clusters Form + +Clusters are **meaningful intersections of 2+ attribute values**. Not every mathematical combination becomes a cluster — only intersections that represent a real topical ecosystem with enough depth to support a hub page and supporting content. + +**Example: Given these populated attributes:** +- Target Area: [Foot, Neck, Face] +- Device Type: [Shiatsu, EMS, Heated] +- Relief Focus: [Neuropathy, Plantar Fasciitis, Circulation] + +**Potential 2-value intersections (Target Area × Relief Focus):** +- Foot × Neuropathy → ✅ Strong cluster: "Foot Massagers for Neuropathy" +- Foot × Plantar Fasciitis → ✅ Strong cluster: "Foot Massagers for Plantar Fasciitis" +- Foot × Circulation → ✅ Viable cluster: "Foot Massagers for Circulation" +- Neck × Neuropathy → ❌ Weak: not enough product/search reality +- Face × Circulation → ❌ Weak: too niche for standalone cluster + +**Potential 2-value intersections (Target Area × Device Type):** +- Foot × Shiatsu → ✅ Strong cluster: "Shiatsu Foot Massagers" +- Foot × EMS → ✅ Strong cluster: "EMS Foot Massagers" +- Neck × Heated → ✅ Strong cluster: "Heated Neck Massagers" +- Face × LED → ✅ Strong cluster: "LED Face Massagers" + +**Potential 3-value intersections:** +- Foot × EMS × Neuropathy → Could be a cluster if deep enough, or a supporting content piece within the "Foot × Neuropathy" cluster + +**The AI determines which intersections warrant standalone clusters** based on: +- Does this intersection represent a real product/service category? +- Can it support a hub page with 3-10 supporting content pieces? +- Is there enough differentiation from adjacent clusters? +- Would real users search for this specific intersection? + +### 7.2 Cluster Types + +Each cluster gets a type classification based on what its attribute intersection represents: + +| Cluster Type | What It Represents | Hub Page Becomes | Example | +|-------------|-------------------|-----------------|---------| +| **Product/Service Category** | Primary attribute intersection defining a product/service group | Category page or cluster hub landing page | "Shiatsu Foot Massagers" | +| **Condition/Problem** | Intersection involving a problem/need attribute | Cluster hub — solution-focused landing page | "Foot Massagers for Neuropathy" | +| **Feature** | Intersection highlighting a specific feature/technology | Feature landing page | "Heated Neck Massagers for Circulation" | +| **Brand** | Grouping by brand across products/services | Brand comparison page | "Top Foot Massager Brands Compared" | +| **Informational** | Educational/how-to content supporting a broader topic | Blog hub or guide page | "How to Massage Your Neck" | +| **Comparison** | Head-to-head or buying guide content | Comparison/roundup article | "EMS vs TENS: Which Therapy Works Better?" | + +### 7.3 Keyword Auto-Generation + +This is the breakthrough: **keywords emerge from attribute value combinations without manual research.** + +**Process:** +For each cluster, take its attribute values and generate natural keyword variants: + +**Cluster: Foot × Neuropathy (Condition/Problem type)** + +Attribute values in this cluster: Target Area=Foot, Relief Focus=Neuropathy + +**Auto-generated keyword variants:** +``` +Direct combinations: + "foot massager for neuropathy" + "foot massager neuropathy" + "neuropathy foot massager" + +With modifiers (best, top, review): + "best foot massager for neuropathy" + "best foot massager neuropathy" + "top foot massager for neuropathy" + "foot massager for neuropathy reviews" + +With additional attribute values from the cluster's products: + "ems foot massager for neuropathy" + "shiatsu foot massager neuropathy" + "heated foot massager nerve pain" + +Question variants: + "do foot massagers help neuropathy" + "is foot massager good for neuropathy" + "what foot massager is best for neuropathy" + +Long-tail with condition context: + "foot massager for diabetic neuropathy" + "foot massager for peripheral neuropathy" + "doctor recommended foot massager for neuropathy" + "foot massager for neuropathy pain relief" +``` + +**From just 2 attribute values (Foot + Neuropathy), 15-25 keyword variants emerge.** Across all clusters for a site with 3 target areas × 3 device types × 3 conditions, you get 300-500+ keyword variants without anyone researching or manually adding a single keyword. + +### 7.4 Keyword Variant Generation Templates + +The system uses templates to generate keywords from attribute values: + +``` +Templates for Condition/Problem clusters: + "[target] massager for [condition]" + "best [target] massager for [condition]" + "[device_type] [target] massager for [condition]" + "does [target] massager help [condition]" + "[condition] [target] massager reviews" + "doctor recommended [target] massager for [condition]" + +Templates for Product Type clusters: + "[device_type] [target] massager" + "best [device_type] [target] massager" + "[device_type] [target] massager reviews" + "[device_type] vs [device_type_2] [target] massager" + +Templates for Brand clusters: + "[brand] [target] massager" + "[brand] [target] massager reviews" + "[brand] vs [brand_2] [target] massager" + "best [brand] massager" +``` + +These templates are sector-specific. A services business would use templates like: +``` + "[service_type] in [location]" + "best [service_type] near me" + "[service_type] for [industry]" + "how much does [service_type] cost" +``` + +### 7.5 Manual Keyword Addition (Supplementary) + +Users can still add keywords from: +- IGNY8's pre-researched keyword library +- Manual entry +- CSV import +- Keyword research API (future) + +These keywords get **mapped to existing clusters** based on which cluster's attribute intersection they match. If a keyword doesn't match any cluster, it's flagged as either: +- A gap in the attribute framework (suggest new attribute value) +- A potential new cluster (suggest new intersection) +- An outlier (exclude from structure) + +--- + +## 8. Case 1: Existing Site Intelligence + +### 8.1 Scenario + +An existing WordPress/WooCommerce site connects to IGNY8. The site has products, categories, some pages and blog posts — but no SAG structure, weak/flat taxonomies, and no cluster organization. + +### 8.2 Data Collection + +The IGNY8 plugin collects and sends to the app: + +| Data Type | What's Collected | Purpose | +|-----------|-----------------|---------| +| **Products** | Title, description, price, existing categories, existing tags, any custom attribute values, images | AI extracts attribute values from product data | +| **Categories** | Name, slug, hierarchy, description, product count | Understand existing site structure (usually flat/weak) | +| **Custom Taxonomies** | All registered taxonomies + their terms | Detect if any attributes already exist (partially) | +| **Pages** | Title, URL, content summary | Identify existing hubs, service pages, landing pages | +| **Posts** | Title, URL, content summary, categories, tags | Identify existing blog content to map to clusters | +| **WooCommerce Attributes** | All product attributes + values + assignments | Direct attribute data (if site has any) | +| **Menu Structure** | Navigation items with hierarchy | Understand how site currently organizes content | + +### 8.3 AI Attribute Extraction + +The critical Case 1 intelligence step. AI receives messy, unstructured site data and infers what attributes SHOULD exist. + +**Example: AI analyzes 50 product titles:** +``` +"Nekteck Shiatsu Neck and Back Massager with Heat" +"Cloud Massage Shiatsu Foot Massager Machine" +"RENPHO Foot Massager with Heat, Shiatsu Deep Kneading" +"EMS Foot Massager Pad for Neuropathy Pain Relief" +"Portable Neck Massager for Pain Relief" +"Heated Back Massager with Vibration" +... +``` + +**AI extraction output:** +``` +Discovered Attributes: + Target Area: Neck (found 12x), Back (found 8x), Foot (found 25x), Shoulder (found 5x) + Device Type: Shiatsu (18x), EMS (7x), Percussion (3x), Vibration (4x) + Relief Focus: Neuropathy (5x), Pain Relief (12x), Circulation (3x) + Brand: Nekteck (5), RENPHO (8), Cloud Massage (3), Homedics (4), ... + Features: Heated (15x), Cordless (7x), Portable (4x) + +Confidence: High — clear recurring patterns across products +``` + +The AI compares these discovered attributes against the sector template (if available for this sector) to validate its findings and suggest any attributes the product data missed. + +### 8.4 Gap Analysis + +After attribute extraction and cluster formation, the system reports: + +``` +YOUR SITE CURRENTLY HAS: + 50 products in 3 flat categories + 12 tags (unorganized) + 0 custom product attributes + 8 random blog posts + 5 static pages + +SAG BLUEPRINT RECOMMENDS: + 6 attributes → become 6 WordPress custom taxonomies + 18 attribute values → become 18 taxonomy terms with landing pages + 12 cluster hubs → new authority pages to create + 36+ supporting blog posts → organized by cluster + Internal linking across all 100+ pages + +GAP: 12 cluster hubs, 28+ blog posts, 18 term pages, + 50 products need attribute enrichment, + 250+ internal links to create +``` + +### 8.5 Product Auto-Tagging + +For Case 1, existing products lack dimensional attributes. The system auto-tags: + +1. AI reads each product's title and description +2. Identifies which attribute values the product belongs to +3. Generates bulk taxonomy term assignments +4. User reviews before saving + +**Example:** +"RENPHO Foot Massager with Heat, Shiatsu Deep Kneading" → +- Target Area: Foot +- Device Type: Shiatsu +- Features: Heated +- Brand: RENPHO +- Therapy Method: Deep Tissue, Kneading + +--- + +## 9. Case 2: New Site from Scratch + +### 9.1 Scenario + +A user creates a new site in IGNY8 with no existing content. They go through the Setup Wizard and IGNY8 generates the complete SAG architecture before any content exists. + +### 9.2 Updated Setup Wizard + +``` +Step 1: Welcome + → Standard welcome screen (no changes) + +Step 2: Add Site + → Site Name, URL, Industry, Sectors (up to 5) + → (Existing step — no changes needed) + +Step 3: Site Structure (NEW STEP) + → 3a: AI generates attribute framework from sector + → 3b: User reviews attributes, toggles on/off, edits values + → 3c: User provides business specifics: + - What products/services? (per site type) + - What conditions/problems do they solve? + - What brands? (if e-commerce) + - What locations? (if services) + → 3d: AI populates attributes from user input + → 3e: Blueprint preview — clusters, keywords, content plan + → 3f: User confirms → Blueprint generated + +Step 4: Connect WordPress + → Standard connection + → ENHANCED: Plugin auto-creates taxonomies from blueprint + +Step 5: Keywords (now optional) + → Keywords from library can supplement auto-generated keywords + → Gap analysis shows which clusters need more coverage + → User can skip entirely — auto-generated keywords are sufficient + +Step 6: Complete + → Blueprint summary, content plan, "Start generating" CTA +``` + +### 9.3 Quick Mode vs Detailed Mode + +**Quick Mode:** "Let IGNY8 build your site structure automatically" +- Uses sector template defaults +- Skips attribute review +- Generates blueprint from defaults +- User can refine later in Site Settings + +**Detailed Mode:** "Customize your site structure" +- Full attribute review and business input flow +- More accurate, tailored blueprint +- Recommended for specific niches + +### 9.4 Step 3 UI Flow + +**Screen: Attribute Review** +``` +Based on your sector (Personal Massagers), we've identified +these organizing attributes for your site: + +PRIMARY ATTRIBUTES: + ✅ Target Area + Values: [Neck] [Foot] [Face] [Back] [+ Add] + ✅ Device Type + Values: [Shiatsu] [EMS] [Heated] [Percussion] [+ Add] + +SECONDARY ATTRIBUTES: + ✅ Relief Focus + Values: [Neuropathy] [Plantar Fasciitis] [Circulation] [+ Add] + ✅ Therapy Method + Values: [Deep Tissue] [TENS] [NMES] [Heat Therapy] [+ Add] + +TERTIARY ATTRIBUTES: + ☑ Brand — [Add your brands] + ☑ Features — [Cordless] [Portable] [Waterproof] + +[+ Add Custom Attribute] +[Continue →] +``` + +**Screen: Blueprint Preview** +``` +Your Site Architecture + +12 Clusters identified across 3 categories: + +📁 Foot Massagers + ├── Foot Massagers for Neuropathy (Condition cluster, Hub page) + ├── Foot Massagers for Plantar Fasciitis (Condition cluster, Hub page) + ├── Shiatsu Foot Massagers (Product Type cluster, Hub page) + ├── EMS Foot Massagers (Product Type cluster, Hub page) + └── Foot Massager Brands Compared (Brand cluster, Blog post) + +📁 Neck Massagers + ├── Heated Neck Massagers (Feature cluster, Hub page) + ├── Shiatsu Neck Massagers (Product Type cluster, Hub page) + └── Neck Massager Brands Compared (Brand cluster, Blog post) + +📁 Face Massagers + ├── LED Face Massagers (Product Type cluster, Hub page) + ├── Microcurrent Face Massagers (Product Type cluster, Hub page) + └── Face Massager Brands Compared (Brand cluster, Blog post) + +📊 420 keywords auto-generated +📝 48 content pieces planned (12 hubs + 36 supporting) +🏷️ 6 custom taxonomies to create +🔗 Internal linking map ready + +[✅ Approve & Build] [↩ Adjust Attributes] +``` + +--- + +## 10. The SAG Blueprint + +### 10.1 What the Blueprint Contains + +Both Case 1 and Case 2 produce the same output: the SAG Blueprint. This is the master architectural document for the site. + +```json +{ + "blueprint_id": "uuid", + "site_id": "site_uuid", + "version": 1, + "status": "active", + + "attributes": [ + { + "name": "Target Area", + "slug": "target-area", + "level": "primary", + "values": [ + {"name": "Foot", "slug": "foot"}, + {"name": "Neck", "slug": "neck"}, + {"name": "Face", "slug": "face"} + ] + }, + { + "name": "Device Type", + "slug": "device-type", + "level": "primary", + "values": [ + {"name": "Shiatsu", "slug": "shiatsu"}, + {"name": "EMS", "slug": "ems"}, + {"name": "Heated", "slug": "heated"} + ] + }, + { + "name": "Relief Focus", + "slug": "relief-focus", + "level": "secondary", + "values": [ + {"name": "Neuropathy", "slug": "neuropathy"}, + {"name": "Plantar Fasciitis", "slug": "plantar-fasciitis"}, + {"name": "Circulation", "slug": "circulation"} + ] + } + ], + + "clusters": [ + { + "name": "Foot Massagers for Neuropathy", + "cluster_type": "condition_problem", + "attribute_intersection": { + "target_area": "Foot", + "relief_focus": "Neuropathy" + }, + "hub_page": { + "title": "Best Foot Massagers for Neuropathy & Nerve Pain Relief", + "type": "cluster_hub", + "structure": "guide_tutorial", + "url_slug": "/best-foot-massagers-for-neuropathy-nerve-pain-relief/" + }, + "auto_generated_keywords": [ + "foot massager for neuropathy", + "best foot massager for neuropathy", + "neuropathy foot massager", + "doctor recommended foot massager for neuropathy", + "ems foot massager for neuropathy", + "does foot massager help neuropathy" + ], + "supporting_content": [ + { + "title": "Doctor-Recommended Foot Massagers for Neuropathy", + "type": "blog_post", + "structure": "review", + "keywords": ["doctor recommended foot massager for neuropathy"] + }, + { + "title": "EMS vs TENS for Neuropathy: Which Therapy Works Better?", + "type": "blog_post", + "structure": "comparison", + "keywords": ["ems vs tens neuropathy", "ems foot massager neuropathy"] + } + ], + "linked_attribute_terms": ["neuropathy", "ems", "foot"], + "cross_cluster_links": ["ems-foot-massagers"] + } + ], + + "taxonomy_creation_plan": [ + { + "attribute": "Target Area", + "wp_taxonomy_slug": "target-area", + "register_for": ["product", "post", "page"], + "terms_to_create": ["Foot", "Neck", "Face"] + }, + { + "attribute": "Device Type", + "wp_taxonomy_slug": "device-type", + "register_for": ["product"], + "terms_to_create": ["Shiatsu", "EMS", "Heated"] + } + ], + + "internal_linking_map": { + "rules_reference": "SAG-Interlinking-Specification.md" + }, + + "execution_priority": [ + {"phase": 1, "items": ["category_pages", "top_cluster_hubs"]}, + {"phase": 2, "items": ["remaining_hubs", "first_blogs_per_cluster"]}, + {"phase": 3, "items": ["attribute_term_pages", "product_enrichment"]}, + {"phase": 4, "items": ["additional_blogs", "brand_comparisons"]} + ] +} +``` + +### 10.2 Blueprint Lifecycle + +| State | Description | +|-------|-------------| +| **Draft** | Generated, awaiting user confirmation | +| **Active** | Confirmed, driving all content operations | +| **Evolving** | New clusters added as products/content grows | +| **Archived** | Replaced by newer version | + +Blueprints are versioned, not overwritten. Site changes trigger new versions. + +--- + +## 11. Content Idea Generation from Clusters + +### 11.1 Mapping to IGNY8's Existing Content Ideas System + +IGNY8 already has a Content Ideas system with these fields (visible in the Ideas UI): +- **Content Idea Title** — the article/page title +- **Sector** — which sector this belongs to +- **Structure** — content format (Comparison, Guide Tutorial, How To, Question, Review, Top Listicle) +- **Type** — content type (Post, Page — extending to include all SAG types) +- **Primary Keywords** — target keywords for this content +- **Cluster** — which cluster this belongs to + +SAG enhances this system by: +1. Auto-generating ideas from the blueprint (instead of only from keyword clustering) +2. Setting the correct **Type** based on cluster type and content purpose +3. Setting the correct **Structure** based on the content's role in the cluster +4. Pre-assigning **Cluster** from the blueprint +5. Pre-populating **Primary Keywords** from auto-generated keywords + +### 11.2 Type Field — Extended Content Types + +The existing Type field (Post, Page) needs to expand to cover all SAG content types. These are platform-agnostic concepts that map differently per CMS: + +| SAG Content Type | Purpose | WordPress | Shopify (future) | Custom Site (future) | +|-----------------|---------|-----------|------------------|---------------------| +| **Blog Post** | Supporting cluster content — articles, guides, comparisons | `post` | Blog article | `/blog/[slug]` | +| **Cluster Hub Page** | Authority landing page for a cluster | `page` (with hub template) | Page | `/[slug]` | +| **Product Page** | Individual product (e-commerce) | `product` (WooCommerce) | Product | `/products/[slug]` | +| **Service Page** | Individual service offering | `page` (with service template) | Page | `/services/[slug]` | +| **Category Page** | Top-level product/content category | Category term (with rich content) | Collection | `/[category]` | +| **Attribute Term Page** | Landing page for an attribute value | Custom taxonomy term (with rich content) | Tag/Collection | `/[attribute]/[value]` | +| **Brand Page** | Brand overview or comparison | `post` or `page` | Page | `/brands/[slug]` | +| **Comparison Page** | Head-to-head or roundup | `post` | Blog article | `/blog/[slug]` | + +### 11.3 Structure Field — Content Format per Type + +The existing Structure field determines HOW the content is written. SAG assigns structures based on cluster type and content purpose: + +| Cluster Type | Hub Page Structure | Supporting Blog Structures | +|-------------|-------------------|---------------------------| +| Condition/Problem | Guide Tutorial | How To, Review, Comparison, Question | +| Product Type | Top Listicle or Guide Tutorial | Comparison, Review, How To | +| Feature | Guide Tutorial | Comparison, How To, Question | +| Brand | Comparison or Review | Review, Comparison | +| Informational | How To or Guide Tutorial | How To, Question, Guide Tutorial | +| Comparison | Comparison | Review, Question | + +### 11.4 Idea Generation Logic + +For each cluster in the blueprint, the system generates: + +**1 Hub Page Idea:** +``` +Title: "Best Foot Massagers for Neuropathy & Nerve Pain Relief" +Sector: Personal Massagers +Structure: Guide Tutorial +Type: Cluster Hub Page +Keywords: foot massager for neuropathy, best foot massager for neuropathy, neuropathy foot massager +Cluster: Foot Massagers for Neuropathy +``` + +**3-6 Supporting Content Ideas:** +``` +Title: "Doctor-Recommended Foot Massagers for Neuropathy" +Sector: Personal Massagers +Structure: Review +Type: Blog Post +Keywords: doctor recommended foot massager for neuropathy +Cluster: Foot Massagers for Neuropathy +``` + +``` +Title: "EMS vs TENS for Neuropathy: Which Therapy Works Better?" +Sector: Personal Massagers +Structure: Comparison +Type: Blog Post +Keywords: ems vs tens neuropathy +Cluster: Foot Massagers for Neuropathy +``` + +``` +Title: "Does a Foot Massager Actually Help Neuropathy?" +Sector: Personal Massagers +Structure: Question +Type: Blog Post +Keywords: does foot massager help neuropathy +Cluster: Foot Massagers for Neuropathy +``` + +**Attribute Term Page Ideas (from cluster's linked attributes):** +``` +Title: "Neuropathy Relief: Best Devices & Therapy Options" +Sector: Personal Massagers +Structure: Guide Tutorial +Type: Attribute Term Page +Keywords: neuropathy relief devices, neuropathy therapy +Cluster: (cross-cluster — serves multiple neuropathy-related clusters) +``` + +--- + +## 12. Content Type Mapping Across Platforms + +### 12.1 Platform-Agnostic Concept + +SAG defines content types by their role in the architecture, not by platform-specific terminology. The same cluster hub concept exists on WordPress, Shopify, and custom sites — only the implementation differs. + +### 12.2 Mapping Table + +| SAG Concept | WordPress | Shopify (future) | Custom React/HTML (future) | +|------------|-----------|------------------|---------------------------| +| **Blog Post** | Post (`post`) | Blog Article | Page component at `/blog/[slug]` | +| **Cluster Hub** | Page (`page`) with custom template | Page with custom template | Page component at `/[slug]` | +| **Product** | WooCommerce Product (`product`) | Product | Page component at `/products/[slug]` | +| **Service** | Page (`page`) with service template | Page | Page component at `/services/[slug]` | +| **Category** | Category term with description content | Collection | Route at `/[category]` | +| **Attribute Term** | Custom taxonomy term with description content | Metafield-based tag or collection | Route at `/[attribute]/[value]` | +| **Navigation** | WordPress Menus | Navigation menus | React Router / Nav component | +| **Taxonomy** | `register_taxonomy()` | Collections, Tags, Metafields | Database model + routes | +| **Attribute on Product** | Product attribute / custom taxonomy term | Product metafield or variant option | Product property in database | + +### 12.3 Implementation Priority + +1. **WordPress** — primary platform, implemented first +2. **Custom Site** — React/HTML site builder (parallel development possible) +3. **Shopify** — future phase, after WordPress and Custom are proven + +### 12.4 Abstraction Layer + +IGNY8 should store content types in platform-agnostic format (the SAG Content Type) and translate to platform-specific format only at the publishing step. This means: + +- Blueprint uses SAG types: `cluster_hub`, `blog_post`, `product_page`, `attribute_term_page` +- Writer generates content tagged with SAG type +- Publisher translates to WordPress: `cluster_hub` → create as `page` with hub template +- Future Shopify publisher: `cluster_hub` → create as Shopify `page` with equivalent template + +--- + +## 13. Taxonomy Creation Flow + +### 13.1 From Blueprint to WordPress + +When a blueprint is confirmed, IGNY8 creates the defined taxonomies on WordPress via the plugin. + +``` +IGNY8 App WordPress Plugin +────────── ──────────────── +1. Blueprint confirmed +2. Generate taxonomy payload ──────────> 3. Receive creation request + 4. Register custom taxonomies + 5. Create terms within each + 6. Assign to post types +7. Update blueprint: created <────────── 7. Report success + term IDs +``` + +### 13.2 Handling Existing Taxonomies (Case 1) + +For existing sites, some taxonomies may already exist: + +| Situation | Action | +|-----------|--------| +| **Exact match** — taxonomy exists with same slug | Skip creation, map existing terms | +| **Similar match** — taxonomy exists with similar name | Present to user: "Is 'Product Category' the same as 'Device Type'?" | +| **No match** | Create new taxonomy | +| **Existing terms** | Merge — add new terms, map existing terms to blueprint values | + +### 13.3 Product Attribute Enrichment + +For Case 1 products lacking attributes: +1. AI reads product title + description +2. Identifies attribute values per product +3. Generates bulk assignments +4. User reviews → saves + +--- + +## 14. Integration with IGNY8 Pipeline + +### 14.1 Current vs SAG-Enhanced Pipeline + +| Stage | Current | SAG-Enhanced | +|-------|---------|-------------| +| **Entry** | User adds keywords | Sector selection → attributes → clusters → keywords auto-generated | +| **Clustering** | AI groups keywords by similarity | Clusters pre-defined by attribute intersections; keywords map to them | +| **Ideas** | Generic ideas per cluster | Type-specific ideas (hub brief vs blog brief vs comparison brief) with correct Structure and Type fields | +| **Tasks** | All tasks same type | Tasks carry cluster type, content structure, and blueprint context | +| **Content** | Same prompts for everything | Type-specific prompts selected by Structure and Type | +| **Images** | Generic image generation | Image style matches content type (hub hero vs blog illustration vs product photo) | +| **Review** | Manual review | Review shows blueprint context — what cluster, what links to | +| **Publish** | Publish as post | Publish to correct post type, with correct taxonomies, correct template | +| **Post-Publish** | Nothing | Linker creates SAG-compliant internal links | + +### 14.2 SAG-Enhanced Automation Pipeline + +``` +Stage 0: Blueprint Check + → Verify active blueprint exists + → Load unfulfilled content needs + +Stage 1: Keyword Processing + → Map any new keywords to existing clusters + → Flag keywords that don't fit (potential new cluster) + +Stage 2: Idea Generation (blueprint-guided) + → Generate ideas per unfulfilled blueprint content needs + → Each idea has correct Sector, Structure, Type, Cluster + +Stage 3: Task Creation + → Tasks carry blueprint context for content generation + +Stage 4: Content Generation (type-specific) + → Select prompt by Structure + Type + → Include cluster context in prompt + +Stage 5: Image Generation + → Match image style to content type + +Stage 6: Taxonomy Assignment + → Auto-assign to correct custom taxonomies from blueprint + +Stage 7: Review Queue + → Blueprint context visible in review + → Pre-computed internal links ready +``` + +### 14.3 Blueprint Health Monitoring + +Background process that maintains blueprint integrity: + +**Weekly health check:** +- Content completeness per cluster (hub exists? blogs published?) +- Internal link coverage +- Unassigned products/pages +- Taxonomy terms without content +- Overall SAG Health Score (0-100) + +**Evolution triggers:** +- New products added to site +- New keywords don't fit existing clusters +- User adds new sector +- Manual user trigger + +--- + +## 15. AI Prompt Architecture + +### 15.1 Prompt Chain for Blueprint Generation + +| Step | Prompt | Input | Output | +|------|--------|-------|--------| +| 1 | **Attribute Discovery** | Industry, sector(s), sector template (if exists) | Validated attribute framework | +| 2a | **Attribute Extraction** (Case 1) | Attributes + raw site data | Populated attributes from real data | +| 2b | **Attribute Population** (Case 2) | Attributes + user business inputs | Populated attributes from user data | +| 3 | **Cluster Formation** | Populated attributes | Clusters with types and intersections | +| 4 | **Keyword Generation** | Clusters + attribute values | Auto-generated keywords per cluster | +| 5 | **Content Planning** | Clusters + keywords + existing content (Case 1) | Content ideas with Structure and Type | +| 6 | **Blueprint Assembly** | All above | Complete SAG Blueprint JSON | + +### 15.2 Content Generation Prompts (Enhanced) + +Existing Thinker module prompts get SAG context variables: + +| Variable | Description | +|----------|-------------| +| `{cluster_name}` | Cluster this content belongs to | +| `{cluster_type}` | Type classification | +| `{cluster_hub_title}` | Hub page title (for internal link reference) | +| `{cluster_hub_url}` | Hub page URL | +| `{attribute_terms}` | Attribute values this content should reference | +| `{cluster_products}` | Products in this cluster | +| `{related_blogs}` | Other blog posts in this cluster | +| `{content_type}` | SAG content type (hub, blog, product, term page) | +| `{content_structure}` | Structure (comparison, how to, review, etc.) | + +--- + +## 16. Data Models & Schema + +### 16.1 New Models + +**SAGBlueprint** +``` +- id (UUID) +- site_id (FK → Site) +- account_id (FK → Account) +- version (Integer) +- status (Enum: draft, active, evolving, archived) +- attributes (JSON) — full attribute framework with populated values +- clusters (JSON) — cluster definitions +- taxonomy_plan (JSON) — taxonomies to create +- execution_priority (JSON) +- sag_health_score (Float, 0-100) +- created_at, confirmed_at, created_by +``` + +**SAGAttribute** +``` +- id (UUID) +- blueprint_id (FK → SAGBlueprint) +- name (String) +- slug (String) +- level (Enum: primary, secondary, tertiary) +- values (JSON array of {name, slug} objects) +- wp_taxonomy_slug (String, nullable) — set after taxonomy created on WordPress +- created_at +``` + +**SAGCluster** +``` +- id (UUID) +- blueprint_id (FK → SAGBlueprint) +- site_id (FK → Site) +- name (String) +- cluster_type (Enum: product_category, condition_problem, feature, brand, informational, comparison) +- attribute_intersection (JSON) — which attribute values form this cluster +- auto_generated_keywords (JSON array) +- status (Enum: planned, partial, complete) +- content_count (Integer, computed) +- link_coverage_score (Float, 0-100) +- created_at +``` + +### 16.2 Modified Existing Models + +All additions are nullable for backward compatibility: + +**Cluster model:** Add `sag_cluster_id` (FK → SAGCluster), `cluster_type` + +**Tasks model:** Add `sag_cluster_id`, `blueprint_context` (JSON) + +**Content model:** Add `sag_cluster_id` + +**ContentIdea model:** Add `sag_cluster_id`, `idea_source` (Enum: keyword_clustering, sag_blueprint, gap_analysis) + +**Site model:** Add `sag_blueprint_id` (FK → SAGBlueprint, nullable) — active blueprint for site + +### 16.3 Sector Attribute Framework Storage + +New model or configuration store for sector-level attribute templates: + +**SectorAttributeTemplate** +``` +- id (UUID) +- industry (String) +- sector (String) +- site_type (Enum: e_commerce, services, saas, content, local_business, brand) +- attribute_framework (JSON) — template attributes with suggested values +- keyword_templates (JSON) — keyword generation templates per cluster type +- created_at, updated_at +- source (Enum: manual, ai_generated, user_contributed) +``` + +This is the NEW data layer that does not currently exist and must be built. + +--- + +## 17. Implementation Phases + +### Phase 1: Data Foundation (Weeks 1-3) + +**Build the new data layer:** +- Create SAGBlueprint, SAGAttribute, SAGCluster models +- Create SectorAttributeTemplate model +- Blueprint CRUD API endpoints +- Add nullable SAG fields to existing Cluster, Tasks, Content, ContentIdea models +- Basic blueprint viewer in Site Settings (read-only) + +### Phase 2: Sector Attribute Templates (Weeks 4-6) + +**Build attribute intelligence:** +- Manually create attribute templates for top 5-8 sectors with highest user base +- AI-assisted template generation for remaining sectors +- Template loading, merging (multi-sector), and validation logic +- API: given industry + sectors → return attribute framework + +### Phase 3: Cluster Formation & Keyword Generation (Weeks 7-9) + +**Core SAG intelligence:** +- AI prompt for forming clusters from attribute intersections +- Cluster type classification logic +- Keyword auto-generation engine (templates per sector type) +- Keyword variant generation producing 300-500+ keywords per site +- Blueprint assembly from attributes → clusters → keywords + +### Phase 4: Case 2 — Setup Wizard (Weeks 10-12) + +**New site flow:** +- Add Site Structure step to wizard (Step 3) +- Attribute review UI +- Business details input forms (per site type) +- Blueprint preview UI +- Quick mode vs detailed mode +- Blueprint confirmation and storage + +### Phase 5: Blueprint-Aware Content Pipeline (Weeks 13-15) + +**Enhance existing pipeline:** +- Idea generation from blueprint (correct Sector, Structure, Type, Cluster) +- Task creation with blueprint context +- Type-specific prompt selection in Writer +- Auto taxonomy assignment on content creation +- Blueprint execution priority drives automation queue + +### Phase 6: Taxonomy Creation (Weeks 16-17) + +**WordPress integration:** +- Taxonomy creation payload generator +- Plugin endpoint to create taxonomies +- Existing taxonomy detection and mapping (Case 1) +- Taxonomy sync status tracking + +### Phase 7: Case 1 — Existing Site Analysis (Weeks 18-21) + +**Existing site intelligence:** +- Plugin site analysis endpoints (products, categories, taxonomies, content) +- AI attribute extraction from unstructured site data +- Gap analysis engine +- User confirmation UI for discovered attributes and proposed structure +- Product auto-tagging + +### Phase 8: Health Monitoring & Polish (Weeks 22-24) + +**Ongoing maintenance:** +- SAG Health Score calculation +- Weekly health check automation +- Blueprint evolution triggers +- Dashboard health widget +- End-to-end testing both cases +- Documentation + +--- + +## Summary + +The SAG implementation transforms IGNY8 from a keyword-dependent content tool into a structure-first site architecture engine. The key shifts: + +1. **Attributes replace keywords as the structural foundation.** Keywords emerge from attribute intersections; they don't define structure. + +2. **Clusters are attribute intersections, not keyword groups.** A cluster exists because Target Area=Foot and Relief Focus=Neuropathy intersect meaningfully — not because someone added "foot massager neuropathy" to their keyword list. + +3. **The system operates without manual keyword input.** 300-500+ keywords auto-generate from attribute value combinations. Users can add more, but the base is self-sufficient. + +4. **Content types match cluster types.** Hub pages, blog posts, product pages, attribute term pages, category pages — each gets the right Structure and Type based on its role in the SAG architecture. + +5. **Platform-agnostic concepts, platform-specific publishing.** The same SAG architecture works across WordPress, Shopify, and custom sites — only the publishing layer changes. + +6. **Sector attribute templates are a completely new data layer.** Current IGNY8 sectors carry zero structural intelligence. Building this layer is the foundational work that everything else depends on. + +--- + +*Cross-references:* +- *SAG-Master-Document.md — Pure SAG methodology and clustering rules* +- *SAG-Interlinking-Specification.md — Linker module specification (Document 3)* +- *SAG-Backlink-Campaign-Specification.md — External backlink campaigns (Document 4)* diff --git a/v2/Igny8 V2 New Final Plans/SAG-Master-Document.md b/v2/Igny8 V2 New Final Plans/SAG-Master-Document.md new file mode 100644 index 00000000..29c8af44 --- /dev/null +++ b/v2/Igny8 V2 New Final Plans/SAG-Master-Document.md @@ -0,0 +1,1048 @@ +# Semantic Authority Grid (SAG) — Master Strategy Document + +**Version:** 2.0 +**Status:** Definitive Reference +**Scope:** Complete SAG methodology — strategy, clustering, architecture, content types, interlinking, and long-term authority building +**Usage:** Strategic reference for SEO site architecture, content planning, and development implementation + +--- + +## Table of Contents + +1. [What is SAG](#1-what-is-sag) +2. [Core Principles](#2-core-principles) +3. [The Dimensional Framework](#3-the-dimensional-framework) +4. [Cluster Formation Methodology](#4-cluster-formation-methodology) +5. [Cluster Types & Content Mapping](#5-cluster-types--content-mapping) +6. [Taxonomy Derivation](#6-taxonomy-derivation) +7. [Site Architecture from Clusters](#7-site-architecture-from-clusters) +8. [Content Structures per Type](#8-content-structures-per-type) +9. [Internal Linking Architecture](#9-internal-linking-architecture) +10. [URL Structure Strategy](#10-url-structure-strategy) +11. [SEO Schema & Metadata](#11-seo-schema--metadata) +12. [Authority Compounding Model](#12-authority-compounding-model) +13. [SAG Application Workflow](#13-sag-application-workflow) +14. [Niche Adaptation Framework](#14-niche-adaptation-framework) +15. [Validation & Quality Criteria](#15-validation--quality-criteria) +16. [Anti-Patterns](#16-anti-patterns) +17. [Real-World Reference: MassagerSmart](#17-real-world-reference-massagersmart) +18. [Appendix: Clustering Prompt Specification](#18-appendix-clustering-prompt-specification) + +--- + +## 1. What is SAG + +The Semantic Authority Grid is a structured SEO and content architecture framework that organizes keywords, content, and commercial pages into interconnected clusters. Each cluster functions as a self-contained mini-ecosystem with its own hub page, supporting blogs, taxonomy term pages, and commercial content (products or services) — all bound together by systematic internal linking. + +SAG is not a clustering algorithm. It is a site architecture philosophy where **keywords dictate structure**, not the other way around. The output of SAG is not a list of keyword groups — it is a complete site blueprint that defines every page type, every taxonomy, every internal link relationship, and every content template needed to build a topically authoritative website. + +### What SAG Produces + +Given a set of keywords (or a product/service catalog), SAG outputs: + +- **Dimensional axes** — the natural facets that organize the niche (e.g., device type, body area, condition, technique, brand) +- **Clusters** — groups of keywords at meaningful dimensional intersections, each forming a self-contained topical ecosystem +- **Cluster types** — classification of each cluster's purpose (hub, blog, category, product, comparison, informational) +- **Taxonomy structure** — categories, tags, and custom taxonomies derived from dimensional axes +- **Page templates** — content structure specifications per cluster type +- **URL hierarchy** — logical URL paths reflecting the dimensional structure +- **Internal linking map** — directional authority flow between all pages +- **Content plan** — what to write, in what order, targeting which keywords + +### Why SAG Matters + +Search engines reward **depth + structure**, not isolated keyword pages. SAG prevents keyword fragmentation, thin content, random tagging, and chaotic navigation. Instead, it delivers depth, clarity, and authority signals — the foundation of long-term rankings. + +Sites built on SAG architecture achieve: +- Higher ranking effectiveness per unit of domain authority (DR/DA) +- Dramatically more pages ranking without direct backlinks (25:1 ratio demonstrated) +- Faster crawling and indexation of new content (sub-10-minute crawl times demonstrated) +- Lower DR threshold for passive ranking of new content +- Compounding authority that increases over years, not just months + +--- + +## 2. Core Principles + +### 2.1 Keywords First, Structure Follows + +Site categories, tags, taxonomies, and page hierarchy must be built AFTER keywords are analyzed and grouped into clusters. Never force keywords into a pre-existing site structure. The dimensional reality of the keyword set determines the architecture. + +### 2.2 Clusters are Mini-Ecosystems + +Each cluster is a self-contained topical authority unit. A complete cluster contains: +- 1 hub/anchor page (the authority center) +- 3-10+ supporting content pieces (blogs, guides, comparisons) +- Taxonomy term pages (derived from cluster dimensions) +- Commercial pages (products or services) where applicable +- Internal links connecting all elements + +A cluster should feel like a complete resource on its topic. A user entering any page within the cluster should be able to naturally navigate to every other page through logical internal links. + +### 2.3 Multi-Dimensional Analysis + +Keywords are not grouped by single-word matching or simple semantic similarity. They are analyzed across multiple dimensions simultaneously. A keyword like "best heated shiatsu foot massager for neuropathy" sits at the intersection of: Product Type (foot massager) + Feature (heated) + Technique (shiatsu) + Condition (neuropathy). The cluster it belongs to is determined by which dimensional combination creates the strongest ecosystem. + +### 2.4 Internal Linking as Authority Architecture + +Internal links are not decorative. They are the mechanism that distributes authority from backlinked pages to un-linked pages. SAG defines directional linking rules: +- Blogs → their cluster hub +- Hubs → attribute term pages + products within the cluster +- Attribute term pages → hub + related products +- Products → hub + comparison/review blogs +- Cross-cluster links only between related hubs + +This structured flow ensures every backlink built to any page in the system benefits every other page through predictable authority distribution. + +### 2.5 Scalability Without Chaos + +New keywords slot into existing clusters or form new ones without breaking the structure. New products inherit the dimensional framework automatically. The architecture grows organically because the dimensional axes are stable — only the values within them expand. + +### 2.6 Exclusion Over Forced Inclusion + +It is better to leave keywords unclustered than to force weak groupings. Only cluster keywords with strong multi-dimensional bonds. Outliers that don't fit any ecosystem are excluded from the structure entirely. Quality of clusters always trumps quantity. + +--- + +## 3. The Dimensional Framework + +### 3.1 What are Dimensions? + +Dimensions are the natural facets or axes along which keywords in a niche can be classified. Every niche has its own dimensional structure, but dimensions generally fall into universal categories that manifest differently per industry. + +### 3.2 Universal Dimension Categories + +| # | Dimension Category | Description | Examples | +|---|-------------------|-------------|----------| +| 1 | **Topic/Subject** | The core thing being discussed | Foot massager, vitamin C serum, auto repair | +| 2 | **Problem/Need** | The pain point or desire driving the search | Neuropathy relief, skin brightening, brake failure | +| 3 | **Solution/Method** | How something is done or achieved | Shiatsu technique, LED therapy, OBD diagnosis | +| 4 | **Feature/Attribute** | Specific characteristics | Heated, waterproof, organic, portable, cordless | +| 5 | **Persona/Audience** | Who needs this | Beginners, professionals, pregnant women, diabetics | +| 6 | **Use-Case/Application** | Where/when/why it's used | Travel, home office, summer, pregnancy | +| 7 | **Product Type/Format** | Category or form factor | EMS pad, roller, pillow, serum, cream | +| 8 | **Brand/Manufacturer** | Specific brands | Renpho, TheraFace, Nekteck, Mario Badescu | +| 9 | **Comparison/Alternative** | Explicit or implied comparisons | Shiatsu vs percussion, vitamin C vs retinol | +| 10 | **Context/Modifier** | Geographic, temporal, or situational qualifiers | UK, near me, 2024, under $50 | + +### 3.3 Niche-Specific Dimension Manifestation + +The same universal categories manifest differently per industry: + +**E-Commerce (Massagers):** +- Topic → Body area (neck, foot, face, back) +- Product Type → Device type (shiatsu, EMS, percussion, roller) +- Solution → Therapy technique (electrical stimulation, deep tissue, vibration) +- Problem → Health condition (neuropathy, plantar fasciitis, circulation) +- Feature → Device features (heated, cordless, portable) +- Brand → Manufacturer (Renpho, Nekteck, TheraFace) + +**SaaS Company:** +- Topic → Feature category (analytics, automation, reporting) +- Persona → Company size (startup, SMB, enterprise) +- Use-Case → Industry vertical (fintech, healthcare, e-commerce) +- Product Type → Integration type (API, plugin, native) +- Problem → Business challenge (scaling, compliance, efficiency) +- Comparison → Competitor alternatives (vs Competitor A, vs Competitor B) + +**Services Business (Law Firm):** +- Topic → Practice area (personal injury, family law, corporate) +- Persona → Client type (individual, business, nonprofit) +- Use-Case → Case type (car accident, divorce, contract dispute) +- Context → Location (city, county, state) +- Problem → Legal need (lawsuit, defense, compliance) +- Solution → Service delivery (consultation, representation, mediation) + +**Content/Media Site:** +- Topic → Subject area (technology, health, finance) +- Persona → Reader level (beginner, intermediate, expert) +- Use-Case → Content purpose (tutorial, news, opinion, review) +- Context → Timeliness (evergreen, trending, seasonal) +- Format → Content type (guide, listicle, comparison, case study) + +### 3.4 Discovering Dimensions + +Dimensions are discovered, not assumed. The process: + +1. **Collect all keywords** — gather the complete keyword universe for the niche +2. **Identify recurring modifiers** — find words/phrases that appear across multiple keywords as qualifying descriptors +3. **Group modifiers into axes** — modifiers that represent the same type of qualification form a dimension +4. **Validate dimensional independence** — each dimension should represent a genuinely different facet (not a synonym of another dimension) +5. **Enumerate dimension values** — list all unique values within each dimension + +**Example Discovery Process:** + +Keywords: "heated foot massager," "shiatsu foot massager," "foot massager for neuropathy," "best foot massager 2024," "heated shiatsu back massager," "neck massager for pain," "EMS foot massager mat" + +Recurring modifiers: +- Body area: foot, back, neck → **Dimension: Massage Area** +- Technique: heated, shiatsu, EMS → **Dimension: Device Type/Technique** +- Condition: neuropathy, pain → **Dimension: Relief Focus** +- Intent: best, 2024 → **Dimension: Search Context** (may or may not form a structural dimension) +- Format: mat, massager → **Dimension: Product Format** + +### 3.5 Dimensional Intersection = Cluster Potential + +Clusters form at meaningful intersections of 2+ dimensions. The more dimensions that intersect, the stronger the cluster: + +- **2-dimensional intersection:** Foot (area) × Shiatsu (type) → "Shiatsu Foot Massagers" — viable cluster +- **3-dimensional intersection:** Foot (area) × EMS (type) × Neuropathy (condition) → "EMS Foot Massagers for Neuropathy" — strong cluster +- **4-dimensional intersection:** Foot (area) × Heated (feature) × Shiatsu (type) × Circulation (condition) → Very specific, may be too narrow for a standalone cluster but excellent as supporting content within a broader cluster + +The optimal cluster sits at a 2-3 dimensional intersection that is: +- Broad enough to support 5-20 keywords +- Specific enough to have a clear hub page topic +- Deep enough to support 3-10+ supporting content pieces + +--- + +## 4. Cluster Formation Methodology + +### 4.1 Step 1: Identify Natural Semantic Overlaps + +Keywords cluster together when they share 2+ dimensional intersections. Shared words alone don't make a cluster. "Back massager" and "back support pillow" share the word "back" but represent completely different product ecosystems. + +**Dimensional intersection test:** +- "best foot massagers for plantar fasciitis" → Product Type (foot massager) + Condition (plantar fasciitis) + Intent (best/commercial) +- "plantar fasciitis foot massager reviews" → Product Type (foot massager) + Condition (plantar fasciitis) + Format (reviews) +- "do foot massagers help plantar fasciitis" → Product Type (foot massager) + Condition (plantar fasciitis) + Intent (informational) + +These share 2 strong dimensions (product type + condition) and form a natural cluster. + +### 4.2 Step 2: Map User Journey Patterns + +Each cluster should support natural user exploration. Valid journey patterns: + +**Problem → Information → Solution → Product:** +"what causes plantar fasciitis" → "best treatments for plantar fasciitis" → "foot massagers for plantar fasciitis" → specific product pages + +**General → Specific → Variant:** +"foot massagers" → "shiatsu foot massagers" → "heated shiatsu foot massagers with remote" + +**Question → Explanation → Options → Decision:** +"do vitamin C serums work" → "how vitamin C brightens skin" → "best vitamin C serums" → "vitamin C vs retinol" + +**Feature Discovery → Feature Comparison → Feature + Use-Case:** +"heated massagers" → "heated vs unheated massagers" → "heated massagers for arthritis" + +**Cluster journey test:** Can a user naturally move from any keyword in the cluster to any other keyword through a logical research or buying journey? + +### 4.3 Step 3: Identify Cluster Anchors (Hub Potential) + +Every cluster needs one clear root keyword that serves as the hub page anchor. + +**Hub characteristics:** +- Broad enough to encompass all cluster keywords +- Specific enough to be commercially or informationally valuable +- Natural landing point for the user journey +- Can support 3-10+ supporting content pieces + +**Good hubs:** +- ✅ "Foot Massagers for Plantar Fasciitis" — supports safety, features, comparisons, use-cases +- ✅ "Vitamin C Serums for Skin Brightening" — supports skin types, vs alternatives, application guides +- ✅ "Best Heated Neck Massagers" — supports brands, features, conditions, buying guide + +**Bad hubs:** +- ❌ "Massagers" — too broad, no natural ecosystem boundary +- ❌ "Renpho foot massager cord length" — too narrow, can't support an ecosystem +- ❌ "Products" — meaningless, not topical + +### 4.4 Step 4: Extract Attribute Dimensions + +For each cluster, identify taxonomy-worthy dimensions — recurring modifiers that could become product filters, content tags, URL parameters, or faceted navigation. + +**Extraction method:** Look for modifiers that repeat across cluster keywords: +- Material: cotton, linen, silk, organic +- Feature: heated, waterproof, portable, wireless +- Size: king, queen, twin, compact +- Type: shiatsu, percussion, vibration, EMS +- Audience: men, women, seniors, athletes +- Context: travel, home, office, car + +These become the custom taxonomies in the site architecture. + +### 4.5 Step 5: Resolve Keyword Conflicts + +Before finalizing: +1. Identify keywords that could fit multiple clusters +2. Assign to the cluster with the MOST dimensional intersections +3. If tied, assign to the MORE SPECIFIC cluster (narrower topic) +4. If still tied, assign to the cluster representing the PRIMARY user intent +5. Last resort: create a new cluster if the keyword represents a unique ecosystem +6. Each keyword appears in exactly one cluster — no duplication + +### 4.6 Formation Rules + +| Rule | Requirement | +|------|-------------| +| **Semantic Coherence** | Keywords must share meaningful semantic relationships, not just word overlap | +| **Dimensional Intersection** | Minimum 2 shared dimensions required; 3+ = strong cluster member | +| **User Journey Viability** | Natural navigation paths must exist within the cluster | +| **Ecosystem Completeness** | Must support 1 hub + 3-10 supporting articles | +| **Minimum Size** | 5 keywords minimum (below this, it's not an ecosystem) | +| **Maximum Size** | 20 keywords maximum (above this, consider splitting) | +| **Optimal Size** | 7-15 keywords (hub + supporting + variants) | +| **No Duplication** | Each keyword in exactly one cluster | +| **Quality Over Quantity** | 5 strong clusters > 15 weak clusters | + +--- + +## 5. Cluster Types & Content Mapping + +Not all clusters are the same. Each cluster has a **type** that determines what kind of content it produces, what page template it uses, and how it fits into the site architecture. + +### 5.1 Cluster Type Classification + +| Cluster Type | Purpose | Hub Page Type | Content Focus | Example | +|-------------|---------|---------------|---------------|---------| +| **Product Cluster** | Group commercial products by dimensional intersection | Product category page | Feature comparison, buying guidance, product listings | "Shiatsu Foot Massagers" | +| **Condition/Problem Cluster** | Address specific problems or use-cases | Cluster hub / landing page | Problem education, solution overview, product recommendations | "Foot Massagers for Neuropathy" | +| **Feature Cluster** | Organize by specific product/service features | Feature landing page | Feature explanation, comparison with alternatives, best-of lists | "Heated Neck Massagers" | +| **Brand Cluster** | Group by manufacturer/brand | Brand comparison page | Brand review, model comparison, brand vs brand | "Top Neck Massager Brands Compared" | +| **Informational Cluster** | Pure educational content | Blog/guide hub | How-to, tips, techniques, safety information | "How to Massage Your Neck" | +| **Comparison Cluster** | Head-to-head evaluations | Comparison/roundup page | A vs B, buying guide, machine comparison | "Neck Massage Machine Buying Guide" | +| **Attribute Cluster** | Organize by taxonomy dimension value | Attribute term landing page | Attribute-specific content with related products/services | "EMS Therapy Devices" | + +### 5.2 How to Determine Cluster Type + +Analyze the dominant intent and dimensional composition: + +1. **If the cluster is anchored by a product category keyword** → Product Cluster +2. **If the cluster is anchored by a problem/condition keyword** → Condition/Problem Cluster +3. **If the cluster is anchored by a specific feature** → Feature Cluster +4. **If the cluster groups multiple brands** → Brand Cluster +5. **If the cluster is purely informational** → Informational Cluster +6. **If the cluster centers on comparisons** → Comparison Cluster +7. **If the cluster represents a single dimension value** → Attribute Cluster + +### 5.3 Cluster Type → Content Type Mapping + +| Cluster Type | Primary Content Type | WordPress Post Type | Content Structure | +|-------------|---------------------|--------------------|--------------------| +| Product Cluster | Product category page | `product_cat` term or custom page | `category_archive` | +| Condition/Problem Cluster | Cluster hub page | `page` or custom post type | `cluster_hub` | +| Feature Cluster | Feature landing page | `page` | `landing_page` | +| Brand Cluster | Brand comparison post | `post` | Blog article | +| Informational Cluster | Blog post | `post` | Blog article | +| Comparison Cluster | Comparison/roundup post | `post` | Blog article | +| Attribute Cluster | Attribute term page | Taxonomy term (e.g., `pa_type`) | `attribute_archive` | + +--- + +## 6. Taxonomy Derivation + +### 6.1 Dimensions Become Taxonomies + +The dimensional axes discovered during keyword analysis translate directly into site taxonomies. This is not metaphorical — each dimension literally becomes a WordPress taxonomy (or equivalent in other CMS platforms). + +**Massager Niche Example:** + +| Dimension | WordPress Taxonomy | Term Examples | +|-----------|-------------------|---------------| +| Body Area | `massage_area` | Neck, Foot, Face, Back, Eye, Scalp | +| Device Type | `massager_type` | Shiatsu, EMS, Percussion, Vibration, Roller | +| Technique | `massage_technique` | Deep Tissue, Electrical Stimulation, Kneading | +| Condition | `relief_focus` | Neuropathy, Plantar Fasciitis, Circulation, Pain Relief | +| Feature | `product_feature` (tag) | Heated, Cordless, Portable, Waterproof | +| Brand | `brand` | Renpho, Nekteck, TheraFace, Homedics | + +### 6.2 Taxonomy Hierarchy + +Not all taxonomies are equal. They form a natural hierarchy: + +**Primary Taxonomies (Categories):** The major organizational axes that define site navigation. Usually 2-3 per site. +- Example: Massage Area (Neck, Foot, Face) + Device Type (Shiatsu, EMS, Heated) + +**Secondary Taxonomies (Custom Taxonomies):** Important classification axes that provide filtering and additional landing pages. +- Example: Relief Focus (Neuropathy, Circulation), Technique (Deep Tissue, Kneading) + +**Tertiary Taxonomies (Tags):** Descriptive attributes that don't warrant their own archive pages but aid in cross-referencing. +- Example: Features (Cordless, Portable), Price Range (Under $50, $50-100) + +### 6.3 Every Taxonomy Term is a Potential SEO Landing Page + +In SAG, taxonomy terms are not just organizational labels. Each term can (and should, for primary/secondary taxonomies) have its own rich content — an SEO-optimized landing page that: +- Defines and explains the term +- Lists related products/services +- Links to relevant blog content +- Includes FAQs +- Targets term-specific keywords +- Uses appropriate schema markup + +A "Shiatsu" taxonomy term page is not just a list of shiatsu products. It's a comprehensive landing page about shiatsu massage technology, with product recommendations, technique explanations, comparison content, and internal links to the shiatsu-related cluster hub and supporting blog posts. + +--- + +## 7. Site Architecture from Clusters + +### 7.1 Architecture Hierarchy + +SAG produces a clear site hierarchy: + +``` +Homepage +├── [Primary Category 1] ← Taxonomy dimension 1 +│ ├── [Cluster Hub A] ← Condition/Problem cluster +│ │ ├── Blog Post 1 ← Supporting content +│ │ ├── Blog Post 2 ← Supporting content +│ │ ├── Product 1 ← Commercial page +│ │ └── Product 2 ← Commercial page +│ ├── [Cluster Hub B] ← Feature cluster +│ │ ├── Blog Post 3 +│ │ └── Product 3 +│ └── [Attribute Term Page] ← Taxonomy term landing page +├── [Primary Category 2] +│ ├── [Cluster Hub C] +│ │ ├── Blog Post 4 +│ │ └── Product 4 +│ └── [Attribute Term Page] +├── Blog Archive +│ └── All blog posts (also accessible through cluster hubs) +└── Brand Pages + ├── Brand A Comparison + └── Brand B Comparison +``` + +### 7.2 MassagerSmart Architecture Example + +``` +massagersmart.com +├── /foot-massager/ ← Product Category (Primary Taxonomy: Massage Area) +│ ├── /best-foot-massagers-for-neuropathy-.../ ← Cluster Hub (Condition Cluster) +│ │ ├── /blog/ankle-heel-foot-massagers-.../ ← Supporting Blog +│ │ ├── /blog/foot-message-vs-massage-.../ ← Supporting Blog +│ │ └── /shop/foot-massager/portable-ems-foot-massager-.../ ← Product +│ ├── /best-foot-massagers-for-plantar-fasciitis-.../ ← Cluster Hub +│ ├── /best-shiatsu-foot-massagers-.../ ← Cluster Hub (Product Type Cluster) +│ ├── /top-heated-electric-ems-foot-massagers-.../ ← Cluster Hub (Feature Cluster) +│ └── /top-foot-massager-brands-compared-.../ ← Brand Cluster +├── /neck-massager/ +│ ├── /portable-cordless-handheld-neck-massagers-.../ ← Cluster Hub +│ ├── /heated-electric-neck-massagers-.../ ← Cluster Hub +│ ├── /shiatsu-neck-massagers-.../ ← Cluster Hub +│ ├── /neck-shoulder-massagers-.../ ← Cluster Hub +│ └── /top-neck-massager-brands-compared-.../ ← Brand Cluster +├── /face-massager/ +│ ├── [Electric/LED/Microcurrent cluster hubs] +│ ├── [Manual tools cluster hub] +│ ├── [Skin healing cluster hub] +│ └── [Brand cluster hub] +├── Taxonomy Term Pages (each with rich SEO content) +│ ├── /massager-type/shiatsu/ ← Attribute term: Shiatsu +│ ├── /massager-type/ems/ ← Attribute term: EMS +│ ├── /relief-focus/neuropathy/ ← Attribute term: Neuropathy +│ ├── /massage-technique/electrical-stimulation/ ← Attribute term +│ └── ... +└── /blog/ + ├── /blog/how-to-massage-your-neck/ ← Info cluster blog + ├── /blog/neck-shoulder-massage-techniques-.../ ← Info cluster blog + └── /blog/neck-massage-machine-buying-guide/ ← Comparison cluster blog +``` + +### 7.3 Architecture Rules + +1. **Every page belongs to at least one cluster** — no orphan pages +2. **Every cluster has exactly one hub page** — the authority anchor +3. **Every product/service is assigned to a primary cluster** — and optionally tagged with secondary clusters +4. **Every taxonomy term with 3+ associated products/pages gets its own landing page** — below that threshold, it exists only as a tag +5. **Blog posts always support a specific cluster** — random blog posts without cluster assignment violate SAG +6. **Cross-cluster relationships are defined explicitly** — not every hub links to every other hub; only dimensionally related hubs cross-link + +--- + +## 8. Content Structures per Type + +### 8.1 Cluster Hub Page + +The authority anchor for the cluster. Comprehensive, long-form content that positions the site as the definitive resource on the cluster's topic. + +**Structure:** +1. Introduction + topic definition (what it is, why it matters) +2. Key considerations / buyer's guide / selection criteria +3. Top recommendations (product/service listings with brief reviews) +4. Comparison table (if applicable) +5. Detailed breakdowns by sub-category or feature +6. Use-case specific guidance +7. FAQs (targeting long-tail question keywords) +8. Related resources (internal links to supporting blogs and attribute pages) + +**Word count:** 2,000-5,000+ words +**Schema:** `CollectionPage` or `WebPage`, `FAQPage` if FAQs present, `ItemList` for product listings + +### 8.2 Blog / Supporting Content + +Depth pieces that expand semantic coverage for the cluster. Each targets specific supporting keywords. + +**Structures by sub-type:** + +**How-To Guide:** +1. Introduction + what you'll learn +2. Step-by-step process +3. Tips and common mistakes +4. When to seek professional help +5. Related product recommendations + +**Comparison Post:** +1. Introduction + comparison criteria +2. Side-by-side analysis +3. Comparison table +4. Verdict / recommendation +5. FAQs + +**Informational Article:** +1. Topic introduction +2. Key concepts explained +3. Benefits / risks / considerations +4. Expert insights or data +5. Actionable takeaways +6. Related resources + +**Word count:** 1,000-2,500 words +**Schema:** `Article`, `BlogPosting`, `HowTo` where applicable + +### 8.3 Product Page + +Individual product or service offering with conversion-focused content. + +**Structure:** +1. Product name + tagline +2. Hero image + gallery +3. Key specifications table +4. Feature/benefit sections (organized by dimensional attributes) +5. Use-case scenarios +6. Comparison with alternatives (links to comparison blog) +7. Customer reviews / testimonials +8. FAQs specific to product +9. Related products (same cluster) + +**Additional Information Section (taxonomy-driven):** +- Device Type & Target Area (Massager Category, Massage Area, Massager Type) +- Therapy Details (Massage Technique, Relief Focus, Therapy Method) +- Each attribute value links to its taxonomy term page + +**Word count:** 800-2,000 words +**Schema:** `Product`, `Review`, `AggregateRating`, `FAQPage` + +### 8.4 Taxonomy Term Landing Page + +SEO-optimized landing page for each taxonomy term value. + +**Structure:** +1. Introduction + term definition +2. Key subtopics (H2/H3 outline covering the term's scope) +3. Top related products/services (filtered by this term) +4. Related blog posts +5. Comparison with alternative terms (e.g., "Shiatsu vs Percussion") +6. FAQs +7. Internal links to related cluster hubs + +**Word count:** 1,000-2,000 words +**Schema:** `CollectionPage` or `WebPage`, `FAQPage` + +### 8.5 Product/Service Category Page + +Top-level category page organizing products/services by primary taxonomy. + +**Structure:** +1. Category introduction + overview +2. Sub-category navigation (links to cluster hubs within this category) +3. Best-of / featured items +4. Buying guide summary +5. All products/services grid with filters +6. FAQs +7. Related categories + +**Word count:** 1,500-3,000 words +**Schema:** `CollectionPage`, `ItemList`, `BreadcrumbList` + +### 8.6 Brand Page + +Comparison and review content for a specific brand or across multiple brands. + +**Structure:** +1. Brand overview / introduction +2. Product lineup analysis +3. Feature comparison table (brand's products or brand vs competitors) +4. Pros and cons +5. Best use-cases for this brand +6. Customer sentiment summary +7. Alternatives to consider + +**Word count:** 1,500-3,000 words +**Schema:** `Article`, `Brand` (where applicable) + +### 8.7 Service Page + +For service-based businesses rather than product-based. + +**Structure:** +1. Service overview + value proposition +2. Process steps (how the service works) +3. Outcomes / deliverables +4. Who it's for (persona targeting) +5. Pricing / packages (if applicable) +6. Case studies / results +7. FAQs +8. Local SEO sections (if location-based) +9. Contact / CTA + +**Word count:** 1,000-2,500 words +**Schema:** `Service`, `LocalBusiness` (if applicable), `FAQPage` + +--- + +## 9. Internal Linking Architecture + +### 9.1 The Authority Flow Model + +Internal links in SAG are not random or decorative. They form a deliberate authority distribution system. The goal: every backlink built to any page in the site benefits every other page through predictable internal link equity flow. + +### 9.2 Linking Rules by Page Type + +| Source Page | Links TO | Purpose | +|------------|----------|---------| +| **Blog Post** | Its cluster hub (mandatory) | Funnels authority to hub | +| **Blog Post** | Related blogs in same cluster (1-3) | Cross-pollination within ecosystem | +| **Blog Post** | Relevant products (1-2) | User journey: info → commercial | +| **Cluster Hub** | All blogs in its cluster | Distributes hub authority to supporting content | +| **Cluster Hub** | Attribute term pages (relevant to cluster) | Connects to taxonomy layer | +| **Cluster Hub** | Products/services in cluster | Hub → commercial funnel | +| **Cluster Hub** | Related cluster hubs (1-2 max) | Cross-cluster authority for shared dimensions | +| **Product Page** | Its primary cluster hub (mandatory) | Funnels product authority to hub | +| **Product Page** | Comparison/review blog (if exists) | User journey: product → evaluation | +| **Product Page** | Related products (same cluster) | Cross-selling within ecosystem | +| **Attribute Term Page** | Its associated cluster hub(s) | Taxonomy → hub authority flow | +| **Attribute Term Page** | Products with this attribute | Term → commercial pages | +| **Attribute Term Page** | Relevant blogs | Term → informational depth | +| **Category Page** | All cluster hubs in category | Top-level → hub distribution | +| **Category Page** | Featured products | Category → conversion | +| **Homepage** | Category pages / top cluster hubs | Root authority distribution | + +### 9.3 Cross-Cluster Linking Rules + +Cross-cluster links connect related ecosystems but must be controlled to avoid authority dilution: + +1. **Only link between hubs that share at least 1 dimension** — "Shiatsu Foot Massagers" hub can link to "Shiatsu Neck Massagers" hub (shared: technique dimension) +2. **Maximum 2 cross-cluster links per hub** — more dilutes the ecosystem's authority concentration +3. **Blogs should NOT cross-link to other clusters' hubs** — they link only to their own hub +4. **Category pages link to all their child cluster hubs** — this is hierarchical, not cross-cluster + +### 9.4 Link Density Guidelines + +| Page Type | Outbound Internal Links | Inbound Internal Links | +|-----------|------------------------|------------------------| +| Homepage | 5-15 | Maximum (all backlinked) | +| Category Page | 8-20 | From homepage + child hubs | +| Cluster Hub | 10-25 | From all cluster members + category | +| Blog Post | 3-8 | From hub + related blogs | +| Product Page | 3-8 | From hub + attribute terms | +| Attribute Term Page | 5-15 | From products + hub + blogs | + +### 9.5 Anchor Text Strategy (Internal) + +- Use descriptive, keyword-rich anchor text for internal links +- Vary anchor text naturally — don't use the exact same anchor for every link to a page +- Hub links should use the hub's primary keyword as anchor +- Product links should use product name or primary keyword +- Blog links should use the blog title or a natural description of the content + +--- + +## 10. URL Structure Strategy + +### 10.1 URL Hierarchy Reflects Site Architecture + +URLs should mirror the dimensional and cluster structure: + +``` +/ ← Homepage +/[category]/ ← Primary category (dimension 1) +/[category]/[cluster-hub-slug]/ ← Cluster hub page +/shop/[category]/[product-slug]/ ← Product page +/blog/[blog-post-slug]/ ← Blog post +/[taxonomy-name]/[term-slug]/ ← Taxonomy term page +``` + +### 10.2 URL Examples (MassagerSmart) + +``` +/foot-massager/ ← Category +/best-foot-massagers-for-neuropathy.../ ← Cluster hub +/shop/foot-massager/portable-ems-foot.../ ← Product +/blog/ankle-heel-foot-massagers.../ ← Blog +/massager-type/shiatsu/ ← Attribute term +/relief-focus/neuropathy/ ← Attribute term +``` + +### 10.3 URL Rules + +1. **Keep URLs descriptive and keyword-rich** — they should read naturally +2. **Use hyphens, not underscores** — standard SEO practice +3. **Reflect the hierarchy** — a product URL should indicate its category +4. **Blog posts can be flat** (/blog/slug/) — they don't need category in URL since they link to hubs via internal links +5. **Taxonomy terms use their taxonomy name as prefix** — /massager-type/shiatsu/ not just /shiatsu/ +6. **Avoid URL depth beyond 3 levels** — deeper URLs get less crawl priority + +--- + +## 11. SEO Schema & Metadata + +### 11.1 Schema by Page Type + +| Page Type | Primary Schema | Additional Schema | +|-----------|---------------|-------------------| +| Homepage | `WebSite`, `Organization` | `SiteNavigationElement` | +| Category Page | `CollectionPage` | `BreadcrumbList`, `ItemList` | +| Cluster Hub | `WebPage` or `CollectionPage` | `FAQPage`, `ItemList`, `BreadcrumbList` | +| Blog Post | `BlogPosting` or `Article` | `FAQPage`, `HowTo`, `BreadcrumbList` | +| Product Page | `Product` | `Review`, `AggregateRating`, `FAQPage`, `BreadcrumbList` | +| Service Page | `Service` | `LocalBusiness`, `FAQPage`, `BreadcrumbList` | +| Attribute Term Page | `CollectionPage` | `FAQPage`, `BreadcrumbList` | +| Brand Page | `Article` | `BreadcrumbList` | + +### 11.2 Meta Title & Description Patterns + +**Cluster Hub:** "[Primary Keyword]: [Value Proposition] | [Brand]" +- Example: "Best Foot Massagers for Neuropathy: Doctor-Recommended Picks | MassagerSmart" + +**Blog Post:** "[Topic]: [Angle or Promise] | [Brand]" +- Example: "How to Massage Your Neck (And When You Shouldn't) | MassagerSmart" + +**Product Page:** "[Product Name] — [Key Benefit] | [Brand]" +- Example: "Portable EMS Foot Massager — Neuropathy & Nerve Relief | MassagerSmart" + +**Taxonomy Term Page:** "[Term]: [Category Context] & [Value Proposition] | [Brand]" +- Example: "Shiatsu: Massage Devices & Deep Tissue Relief | MassagerSmart" + +--- + +## 12. Authority Compounding Model + +### 12.1 How SAG Compounds Authority Over Time + +SAG creates a compounding authority effect that increases over time, not linearly but exponentially. This is the key strategic advantage. + +**Phase 1: Foundation (Months 0-6)** +- Site structure is built according to SAG blueprint +- Cluster hubs and initial supporting content published +- Taxonomies created with basic content +- Internal linking architecture implemented +- External backlink campaign begins targeting T1-T2 pages +- **SAG impact:** 30-40% efficiency gain in backlink effectiveness vs flat site + +**Phase 2: Early Authority (Months 6-12)** +- DR/DA reaches tipping point range (DR 25-35 depending on market) +- First un-linked pages begin ranking for low-KD keywords +- Google crawl frequency increases as site structure proves reliable +- New content published into existing cluster structure ranks faster +- **SAG impact:** Un-linked pages ranking 2-4 DR points earlier than expected + +**Phase 3: Authority Establishment (Months 12-24)** +- 50%+ of new content ranks without direct backlinks +- Crawl times for new content drop to hours/minutes +- Cross-cluster authority flow becomes measurable +- Taxonomy term pages begin ranking independently +- **SAG impact:** 50%+ improvement in pages ranking without backlinks vs flat site at same DR + +**Phase 4: Compounding Dominance (Year 2+)** +- Site can rank for competitive keywords with DR well below competitors +- New content published into SAG structure achieves page 1-3 within weeks +- Authority ratio reaches 25:1+ (un-linked pages ranking per backlinked page) +- Site becomes the topical authority for its niche in search engines +- **SAG impact:** Site operates in a fundamentally different competitive league + +### 12.2 Why This Compounds + +1. **Every new page strengthens every existing page.** When a new blog post is added to a cluster, it creates new internal links to the hub and other cluster content. This increases the hub's internal link count, which increases its ranking power, which increases the authority it passes back to all other cluster pages. It's a positive feedback loop. + +2. **Google learns the site's authority pattern.** Over time, Google's crawler learns that this site consistently produces relevant, well-structured content in its niche. This builds a trust signal that goes beyond raw DR — it's topical trust. New pages inherit this trust immediately upon publication. + +3. **Taxonomy term pages accumulate authority passively.** As more products and blog posts link to taxonomy terms, those term pages gain ranking power without any direct SEO effort. A "Neuropathy Relief" term page gets stronger every time a new neuropathy-related blog post or product is published. + +4. **Cross-cluster links compound.** As individual clusters strengthen, the controlled cross-cluster links become more valuable, strengthening adjacent clusters. This creates a network effect where the whole site becomes stronger than the sum of its parts. + +### 12.3 Real-World Evidence + +An SAG-structured site in a competitive niche, after 8 years of consistent implementation: +- DR 29 (modest by competitive standards) +- Dominates country-level rankings for primary category keyword +- 1000+ pages on page 1 top 5 positions without any direct backlinks +- Only 30-40 pages have external backlinks +- New blog posts crawled within 10 minutes of publication +- New content ranks for target keywords within days + +This represents a 25:1+ ratio of un-linked pages ranking per backlinked page — a ratio that flat-structure sites at DR 50+ cannot achieve. + +--- + +## 13. SAG Application Workflow + +### 13.1 Complete Process (9 Steps) + +**Step 1: Collect Keywords** +Gather all relevant search queries from Ahrefs, SEMrush, Google Search Console, competitor analysis, and internal product/service data. Build a comprehensive keyword pool across all intents. + +**Step 2: Discover Dimensions** +Analyze the keyword set to identify the natural dimensional axes. What are the recurring facets that differentiate keywords from each other? Group modifiers into dimensions. Validate dimensional independence. + +**Step 3: Form Clusters** +Group keywords at meaningful 2-3 dimensional intersections. Each cluster must pass the ecosystem test: hub potential, user journey viability, minimum 5 keywords, semantic coherence. + +**Step 4: Classify Cluster Types** +Determine each cluster's type (product, condition, feature, brand, informational, comparison, attribute). This determines the content type, page template, and position in the site hierarchy. + +**Step 5: Derive Taxonomies** +Convert dimensional axes into site taxonomies. Define primary (categories), secondary (custom taxonomies), and tertiary (tags) taxonomy levels. Enumerate all term values. + +**Step 6: Map Site Architecture** +Build the complete page hierarchy: homepage → categories → cluster hubs → supporting content → products/services. Assign every page to its cluster. Define URL structure. + +**Step 7: Define Internal Linking Map** +Specify all internal link relationships following SAG linking rules. Hub → blogs, blogs → hub, hub → products, products → hub, hub ↔ attribute terms, controlled cross-cluster links. + +**Step 8: Generate Content Plan** +For each cluster, define: hub page content brief, supporting blog topics, taxonomy term page content needs, product/service page requirements. Prioritize by cluster importance and commercial value. + +**Step 9: Execute & Scale** +Publish hub pages first (highest priority). Add supporting blogs for depth. Create taxonomy term pages. Add products/services. Implement internal links. As new keywords emerge, slot them into existing clusters or form new ones. Launch external backlink campaign targeting hub pages and homepage. + +### 13.2 Execution Priority Order + +1. **Homepage** — foundation of authority +2. **Category pages** — primary navigation structure +3. **Cluster hub pages** — authority anchors (prioritize by commercial value) +4. **Supporting blog posts** — 2-3 per cluster initially +5. **Taxonomy term pages** — for primary/secondary taxonomy terms +6. **Product/service pages** — commercial conversion pages +7. **Additional blog posts** — expand depth per cluster +8. **Brand comparison pages** — if brand cluster exists +9. **Cross-cluster content** — content that bridges related clusters + +--- + +## 14. Niche Adaptation Framework + +### 14.1 E-Commerce Site + +**Typical Dimensions:** Product type, feature, condition/use-case, brand, price range, audience +**Primary Cluster Types:** Product clusters, condition clusters, feature clusters, brand clusters +**Key Architecture:** Categories → cluster hubs → product pages + supporting blogs +**Special Consideration:** Product attribute taxonomies are critical — they become filter/faceted navigation AND SEO landing pages + +### 14.2 SaaS / Technology Company + +**Typical Dimensions:** Feature category, use case, industry vertical, company size, integration type +**Primary Cluster Types:** Feature clusters, use-case clusters, comparison clusters, informational clusters +**Key Architecture:** Solution pages → feature hubs → case studies + blog posts +**Special Consideration:** Comparison clusters (vs competitors) are often the highest-value commercial content + +### 14.3 Services Business + +**Typical Dimensions:** Service type, industry served, location, methodology, outcome +**Primary Cluster Types:** Service clusters, industry clusters, informational clusters +**Key Architecture:** Service pages → industry-specific hubs → case studies + educational content +**Special Consideration:** Location dimension creates geo-specific cluster variants (same service, different cities) + +### 14.4 Content / Media Site + +**Typical Dimensions:** Subject area, reader level, content format, timeliness +**Primary Cluster Types:** Topic clusters, informational clusters, comparison clusters +**Key Architecture:** Topic categories → pillar content hubs → supporting articles +**Special Consideration:** Evergreen vs trending content balance — SAG structure should prioritize evergreen clusters with trending content as supporting pieces + +### 14.5 Local Business + +**Typical Dimensions:** Service type, location, audience, urgency +**Primary Cluster Types:** Service clusters, location clusters, problem clusters +**Key Architecture:** Service pages → location-specific variants → local educational content +**Special Consideration:** Location × service dimensional intersections create highly targeted local landing pages + +--- + +## 15. Validation & Quality Criteria + +### 15.1 Cluster Validation Checklist + +Before finalizing any cluster, verify: + +- [ ] **Hub Potential:** Cluster has 1 clear anchor keyword suitable for a hub page +- [ ] **Dimensional Overlap:** Keywords share 2+ semantic dimensions +- [ ] **User Journey:** Natural navigation paths exist within the cluster +- [ ] **Attribute Dimensions:** Recurring modifiers can become filters/taxonomies +- [ ] **Ecosystem Completeness:** Supports 1 hub + 3-10 supporting content pieces +- [ ] **Semantic Coherence:** Keywords genuinely belong together (not just word overlap) +- [ ] **No Duplication:** Each keyword appears in exactly one cluster +- [ ] **Minimum Size:** Cluster has 5+ keywords +- [ ] **Maximum Size:** Cluster has ≤20 keywords (split if larger) +- [ ] **Hub Naming:** Cluster name is natural, SEO-relevant, and specific + +### 15.2 Site Architecture Validation + +- [ ] **No orphan pages:** Every page belongs to at least one cluster +- [ ] **Complete cluster ecosystems:** Every cluster has hub + supporting content + commercial pages +- [ ] **Taxonomy coverage:** All primary/secondary dimensions have taxonomy term pages +- [ ] **Internal linking implemented:** All SAG linking rules are active +- [ ] **URL structure reflects hierarchy:** URLs follow the defined pattern +- [ ] **Schema markup applied:** Every page type has appropriate structured data +- [ ] **Cross-cluster links are controlled:** Maximum 2 per hub, dimension-justified + +### 15.3 Content Quality Criteria + +- [ ] **Hub pages are comprehensive** (2,000+ words, multiple sections, FAQs) +- [ ] **Blog posts provide genuine depth** (1,000+ words, unique angle) +- [ ] **Product pages include dimensional attributes** (taxonomy-driven specification sections) +- [ ] **Taxonomy term pages have rich content** (not just product lists) +- [ ] **All content targets specific keywords from the cluster** +- [ ] **Internal links use descriptive, varied anchor text** + +--- + +## 16. Anti-Patterns + +### 16.1 Clustering Anti-Patterns + +| Anti-Pattern | Why It's Wrong | Correct Approach | +|-------------|---------------|-----------------| +| **Single-word grouping** ("all 'heated' keywords together") | Feature alone isn't an ecosystem | Cluster by dimensional intersection (heated + product type + use-case) | +| **Forced categorization** ("must fit everything") | Creates weak clusters | Exclude keywords that don't fit strong ecosystems | +| **Shallow connections** (shared word, no semantic bond) | "Back massager" ≠ "back support pillow" | Verify 2+ dimensional intersections | +| **Traditional intent labels as clusters** ("informational cluster") | Intent is a property, not a dimension | Cluster by topic ecosystem, classify intent within | +| **Category-first thinking** ("put all foot stuff together") | Categories are outputs, not inputs | Let keyword dimensions determine categories | +| **Word-matching only** ("all 'massage' keywords") | Ignores semantic reality | Analyze dimensional intersections | +| **Duplicate keyword assignment** (keyword in 2 clusters) | Breaks SAG structure | Assign each keyword to exactly one cluster | + +### 16.2 Architecture Anti-Patterns + +| Anti-Pattern | Why It's Wrong | Correct Approach | +|-------------|---------------|-----------------| +| **Random blog posts** (not assigned to clusters) | Orphan content wastes authority | Every blog supports a specific cluster | +| **Flat taxonomy** (one level of categories, no custom taxonomies) | Misses dimensional depth | Derive multi-level taxonomies from dimensions | +| **Unlimited cross-cluster linking** | Dilutes authority concentration | Maximum 2 cross-cluster links per hub | +| **Empty taxonomy term pages** (just product lists) | Wastes SEO opportunity | Rich content on every term page | +| **No internal linking plan** | Authority distribution is random | Implement SAG linking rules systematically | +| **Products not assigned to clusters** | Products float outside ecosystems | Every product belongs to a primary cluster | + +--- + +## 17. Real-World Reference: MassagerSmart + +### 17.1 Dimensional Axes + +| Dimension | Taxonomy | Values | +|-----------|----------|--------| +| Body Area | `massage_area` | Neck, Foot, Face, Back, Eye, Scalp | +| Device Type | `massager_type` | Shiatsu, EMS Pad/Mat, Percussion, Vibration, Roller, LED, Microcurrent | +| Technique | `massage_technique` | Electrical Stimulation, Deep Tissue, Kneading, Vibration | +| Condition | `relief_focus` | Neuropathy Relief, Plantar Fasciitis, Circulation, Pain Relief, Skin Tightening, Lymphatic Drainage | +| Therapy | `therapy_method` | NMES Therapy, TENS Therapy, Shiatsu, Heat Therapy | +| Brand | `brand` | Renpho, Nekteck, TheraFace, Homedics, Naipo, SKG, Hugterra | + +### 17.2 Cluster Map (Foot Massagers) + +| Cluster Name | Type | Hub Page | Supporting Content | +|-------------|------|----------|-------------------| +| Neuropathy & Nerve Pain Massagers | Condition Cluster | /best-foot-massagers-for-neuropathy-.../ | Doctor recommendations, EMS for neuropathy blog, nerve pain relief guide | +| Plantar Fasciitis Foot Massagers | Condition Cluster | /best-foot-massagers-for-plantar-fasciitis-.../ | Exercise + massage blog, night splint comparison | +| Heated, Electric & EMS Massagers | Feature Cluster | /top-heated-electric-ems-foot-massagers-.../ | EMS vs TENS blog, heated massager safety guide | +| Shiatsu Foot Massagers | Product Type Cluster | /best-shiatsu-foot-massagers-.../ | Deep kneading technique blog, shiatsu at home guide | +| Leg & Calf Foot Massagers | Product Type Cluster | /best-leg-calf-foot-massagers-.../ | Calf pain relief blog, leg circulation guide | +| Foot Massager Brands Compared | Brand Cluster | /top-foot-massager-brands-compared-.../ | Individual brand reviews | +| General Product Category | Intent Cluster | /foot-massager/ (category page) | Best of year roundup, buying guide | + +### 17.3 Blog Clusters (Foot Massagers) + +| Blog Cluster | Type | URL Pattern | Purpose | +|-------------|------|-------------|---------| +| Heel & Ankle Relief | Use-Case Cluster | /blog/ankle-heel-foot-massagers-.../ | Supports neuropathy and general foot clusters | +| Foot Message vs Massage | Intent Cluster | /blog/foot-message-vs-massage-.../ | Captures misspelling/confusion traffic | +| Spa & Water Massagers | Function Cluster | /blog/best-foot-spa-massagers-.../ | Captures spa-related search intent | +| Foot Machine Types | Comparison Cluster | /blog/foot-massager-vs-massage-machine-.../ | Comparison/buying decision content | + +### 17.4 Product Page Example: Dimensional Attributes + +**Product:** Portable EMS Foot Massager for Neuropathy & Nerve Relief + +**Specification Section (taxonomy-driven):** + +| Attribute | Value (linked to term page) | +|-----------|---------------------------| +| Massager Category | EMS Foot Massagers | +| Massage Area | Feet | +| Massager Type | EMS Pad / Mat | +| Massage Technique | Electrical Stimulation | +| Relief Focus | Foot Circulation, Neuropathy Relief | +| Therapy Method | Foot Circulation, Neuropathy Relief, NMES Therapy, TENS Therapy | + +Each value in the specification section is a link to its taxonomy term page, creating bidirectional authority flow between product pages and term pages. + +--- + +## 18. Appendix: Clustering Prompt Specification + +This section provides the AI prompt specification for automated keyword clustering following SAG methodology. This is used by AI systems (including IGNY8) to perform SAG-compliant clustering. + +### 18.1 AI Clustering Prompt Role + +The AI acts as a semantic strategist building topic ecosystems using SAG methodology. It analyzes keywords and groups them into mini-ecosystems where each cluster represents a complete, self-contained topic authority area. + +### 18.2 Input Format + +```json +{ + "keywords": ["keyword 1", "keyword 2", "keyword 3", "..."] +} +``` + +Keywords may include volume and difficulty metrics, but clustering decisions should be based on semantic analysis, not volume/difficulty data. + +### 18.3 Output Format + +```json +{ + "clusters": [ + { + "name": "Natural, SEO-relevant cluster name representing the root topic", + "description": "2-3 sentences explaining: (1) what semantic dimensions bind these keywords, (2) what user journey or problem space this cluster addresses", + "keywords": ["keyword 1", "keyword 2", "keyword 3"] + } + ] +} +``` + +### 18.4 Clustering Algorithm + +1. **Identify dimensional axes** in the keyword set +2. **Find 2+ dimensional intersections** between keywords +3. **Group keywords at meaningful intersections** forming ecosystems +4. **Identify hub anchor keyword** for each cluster +5. **Extract taxonomy-worthy attributes** from each cluster +6. **Resolve conflicts** (keywords fitting multiple clusters → assign to strongest fit) +7. **Validate** each cluster against formation rules +8. **Exclude** keywords that don't fit any strong ecosystem + +### 18.5 Naming Guidelines + +**Good names:** Descriptive, SEO-relevant, represent the root topic +- "Heated Shiatsu Back Massagers for Pain Relief" +- "Organic Cotton Bedding for Summer" +- "Vitamin C Serums for Skin Brightening" + +**Bad names:** Too broad, meaningless, just a feature, or meta-descriptive +- "Massagers" / "Products" / "Heated" / "Queries about safety" + +### 18.6 Description Template + +"This cluster covers [TOPIC] focused on [PROBLEM/USE-CASE] for [AUDIENCE]. Keywords share dimensions of [DIMENSION 1] and [DIMENSION 2], forming a natural ecosystem for users researching [USER JOURNEY]." + +### 18.7 Quality Rules + +- Minimum 5 keywords per cluster +- Maximum 20 keywords per cluster (optimal: 7-15) +- No keyword duplication across clusters +- Each cluster must have clear hub potential +- Exclude keywords that don't fit strong ecosystems +- 5 strong clusters > 15 weak clusters + +--- + +*This document is the definitive reference for the Semantic Authority Grid methodology. All SAG-related implementation, content planning, and site architecture decisions should reference this document as the source of truth.* diff --git a/v2/Igny8 V2 New Final Plans/SAG-Niche-Definition-Process.pdf b/v2/Igny8 V2 New Final Plans/SAG-Niche-Definition-Process.pdf new file mode 100644 index 00000000..0615366a Binary files /dev/null and b/v2/Igny8 V2 New Final Plans/SAG-Niche-Definition-Process.pdf differ diff --git a/v2/Igny8 V2 New Final Plans/Theme-Build-Plan.md b/v2/Igny8 V2 New Final Plans/Theme-Build-Plan.md new file mode 100644 index 00000000..bbdf6f2c --- /dev/null +++ b/v2/Igny8 V2 New Final Plans/Theme-Build-Plan.md @@ -0,0 +1,1054 @@ +# [THEME NAME] — Complete Build Plan + +**By:** Alorig Systems +**For:** AI Agent (Claude Code / Opus 4.6 in VSCode) +**Version:** 1.0 +**Date:** March 2026 +**Status:** Reference Document for Development + +--- + +## Executive Summary + +A premium WordPress theme that provides the **physical infrastructure** for SAG-optimized sites. It registers all the custom post types, custom taxonomies, meta fields, and template systems needed to display a fully structured semantic site — whether that structure is built manually or pushed from IGNY8. + +The theme handles presentation, structure, and site infrastructure (performance, forms, security). The IGNY8 plugin handles intelligence, content, SEO, social, and analytics. + +**Two deliverables:** +1. **Theme** — CPTs, taxonomies, templates, block patterns, landing page builder, design system, WooCommerce templates +2. **Companion Plugin (Toolkit)** — Performance/caching, forms, security, SMTP, WooCommerce enhancements + +**Distribution:** Free version on WordPress.org (limited patterns + features). Premium version sold on Alorig site (full pattern library, all toolkit modules, priority support). + +--- + +## Part 1: What This Theme Does (and Doesn't Do) + +### 1.1 Theme Owns (Presentation + Structure) + +| Responsibility | Details | +|---|---| +| **Custom Post Types** | Services, Portfolio/Case Studies, Landing Pages, Team Members, Testimonials, FAQs, Documentation | +| **Custom Taxonomies** | Service categories, service attributes (area, type, property type), portfolio categories, documentation categories — all SAG-compatible | +| **SAG Structural Templates** | Term landing pages, cluster hub pages, attribute archive pages — all designed to display rich content, not just post lists | +| **Landing Page Builder** | Section-based CPT with pre-designed section templates + presets | +| **Block Patterns** | 50+ patterns organized by type (heroes, features, social proof, CTAs, etc.) | +| **FSE Templates** | Complete template sets for 5 site types (blog, SaaS, eCommerce, corporate, portfolio) | +| **WooCommerce Templates** | Custom shop, product, cart, checkout templates that respect SAG structure | +| **Design System** | theme.json tokens, custom utility CSS, typography, spacing scale | +| **Interlinking Display** | Renders related content sections, cluster navigation, term relationships — reading data from IGNY8 plugin or manual configuration | +| **WordPress Cleanup** | Remove bloat, conditional asset loading, zero jQuery on frontend | + +### 1.2 IGNY8 Plugin Owns (Intelligence + Marketing) + +The theme does NOT include any of these — they live in the IGNY8 plugin: + +- SEO meta tags, title tags, canonical, robots +- Schema / JSON-LD structured data +- XML sitemaps +- Redirects + 404 monitoring +- OG tags + social meta +- Share buttons + social posting +- Analytics (GA, GTM, pixels) +- Google Search Console integration +- Content analysis + scoring +- Internal link calculation + suggestions +- Site intelligence / audit +- Content sync from IGNY8 platform +- SAG blueprint sync + taxonomy creation logic + +### 1.3 Toolkit Plugin Owns (Site Infrastructure) + +- Page caching + HTML optimization +- CSS/JS minification + combination +- Image optimization + WebP conversion +- Critical CSS generation +- Contact forms + submission handling +- Security hardening + firewall +- SMTP mail handling +- WooCommerce enhancements (quick view, wishlist, ajax cart, filters) + +### 1.4 How They Work Together + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ THEME │ +│ Registers CPTs + Taxonomies + Templates + Design System │ +│ Displays everything: pages, terms, clusters, products, │ +│ services, landing pages, interlinking sections │ +│ │ +│ Reads from: │ +│ ├── IGNY8 Plugin (SEO data, related links, cluster nav, │ +│ │ term content, breadcrumbs, share buttons) │ +│ ├── Toolkit Plugin (cached pages, form shortcodes) │ +│ └── WordPress core (menus, widgets, customizer) │ +│ │ +│ Works WITHOUT either plugin (graceful degradation) │ +└─────────────────────────────────────────────────────────────────┘ + +┌──────────────────────────┐ ┌──────────────────────────────────┐ +│ IGNY8 PLUGIN │ │ TOOLKIT PLUGIN │ +│ SEO, Schema, Social, │ │ Performance, Forms, │ +│ Analytics, GSC, Linking, │ │ Security, SMTP, │ +│ Content Sync, SAG │ │ WooCommerce Enhancements │ +│ Intelligence │ │ │ +│ │ │ │ +│ Works with ANY theme │ │ Works with ANY theme │ +│ Enhanced with companion │ │ Enhanced with companion │ +└──────────────────────────┘ └──────────────────────────────────┘ +``` + +**Graceful degradation:** Theme checks `function_exists('igny8')` before reading plugin data. If IGNY8 plugin is not installed, interlinking sections don't render, breadcrumbs fall back to theme's own simple breadcrumbs, term pages show WordPress default content. Everything still works — just without the intelligence layer. + +--- + +## Part 2: SAG Structural Support + +This is the core differentiator. The theme physically implements the structures that SAG requires in WordPress. + +### 2.1 Custom Post Types + +| CPT | Slug | Purpose | SAG Role | +|---|---|---|---| +| **Services** | `service` | Individual service pages | Maps to SAG service clusters. Each service belongs to service categories + service attributes. | +| **Landing Pages** | `landing_page` | Section-based marketing pages | Cluster hub pages, campaign pages, any freeform landing page | +| **Portfolio** | `portfolio` | Case studies, projects | Supports attribute-based filtering (industry, service type, etc.) | +| **Team Members** | `team_member` | Staff/team profiles | Used in team sections and about pages | +| **Testimonials** | `testimonial` | Client testimonials | Used in social proof sections across site | +| **FAQs** | `faq` | Frequently asked questions | Maps to clusters/terms, generates FAQPage schema (via IGNY8 plugin) | +| **Documentation** | `documentation` | Knowledge base / docs | SaaS sites: organized by doc categories | + +**CPT Registration Details:** + +``` +service + - Public: true + - Has archive: true (services listing page) + - Supports: title, editor, thumbnail, excerpt, revisions, page-attributes + - Menu icon: dashicons-admin-tools + - Rewrite: /services/%service_category%/%postname%/ + - Taxonomies: service_category, service_area, service_attribute, cluster + +landing_page + - Public: true + - Has archive: false + - Supports: title, thumbnail, excerpt, revisions + - Does NOT support: editor (replaced by section meta box) + - Menu icon: dashicons-layout + - Rewrite: /l/%postname%/ (short URLs for campaigns) or /%postname%/ (flexible) + +portfolio + - Public: true + - Has archive: true + - Supports: title, editor, thumbnail, excerpt, revisions + - Menu icon: dashicons-portfolio + - Rewrite: /portfolio/%portfolio_category%/%postname%/ + - Taxonomies: portfolio_category, portfolio_tag, service_category (shared) + +team_member + - Public: true + - Has archive: true (team page) + - Supports: title, editor, thumbnail + - Menu icon: dashicons-groups + - Rewrite: /team/%postname%/ + +testimonial + - Public: false (displayed via blocks/shortcodes, not individual pages) + - Supports: title, editor, thumbnail + - Menu icon: dashicons-format-quote + +faq + - Public: true + - Has archive: true (FAQ page) + - Supports: title, editor + - Menu icon: dashicons-editor-help + - Taxonomies: faq_category, cluster + - Rewrite: /faq/%faq_category%/%postname%/ + +documentation + - Public: true + - Has archive: true + - Supports: title, editor, thumbnail, page-attributes (for ordering) + - Hierarchical: true (parent/child docs) + - Menu icon: dashicons-book + - Rewrite: /docs/%doc_category%/%postname%/ + - Taxonomies: doc_category +``` + +### 2.2 Custom Taxonomies + +These taxonomies directly map to SAG dimensional axes. When IGNY8 plugin is connected, it populates these taxonomies with SAG attribute values. When used standalone, users create terms manually. + +| Taxonomy | Slug | For CPTs | Hierarchical | SAG Mapping | +|---|---|---|---|---| +| **Service Category** | `service_category` | service, portfolio | Yes | Primary attribute (e.g., "Service Type": Emergency, Drain Cleaning, etc.) | +| **Service Area** | `service_area` | service | Yes | Tertiary attribute (geographic: user-populated per location) | +| **Service Attribute** | `service_attribute` | service | No | Secondary attributes (e.g., "Property Type": Residential, Commercial; "Urgency": Emergency, Same-Day) | +| **Portfolio Category** | `portfolio_category` | portfolio | Yes | Groups projects by type | +| **Portfolio Tag** | `portfolio_tag` | portfolio | No | Descriptive tags for filtering | +| **FAQ Category** | `faq_category` | faq | Yes | Groups FAQs by topic (maps to clusters) | +| **Doc Category** | `doc_category` | documentation | Yes | Documentation sections | +| **Content Cluster** | `cluster` | post, service, faq, page | No | SAG cluster assignment. Each post/service/FAQ maps to a cluster. This is the key taxonomy that ties content to the SAG grid. | +| **Topic Tag** | `topic_tag` | post, service, faq, documentation | No | Granular topical tags beyond clusters | + +**WooCommerce Taxonomies (when Woo is active):** + +The theme does NOT register WooCommerce's built-in taxonomies (product_cat, product_tag, pa_*). Instead it: +- Respects and templates all WooCommerce taxonomies natively +- Provides rich term archive templates for product_cat, product_tag +- Provides attribute archive templates for all pa_* taxonomies +- Registers the `cluster` taxonomy for the `product` post type too — so products can be cluster-mapped + +### 2.3 Meta Fields Per CPT + +**Service Meta Fields:** + +``` +_theme_service_price_range -- Text: e.g., "$150 - $500" +_theme_service_duration -- Text: e.g., "2-4 hours" +_theme_service_process_steps -- JSON array: [{step_number, title, description, icon}] +_theme_service_outcomes -- JSON array: [{title, description}] +_theme_service_faqs -- JSON array: [{question, answer}] (also rendered as FAQPage schema via IGNY8) +_theme_service_cta_text -- Text: custom CTA button text +_theme_service_cta_url -- URL: custom CTA destination +_theme_service_areas_served -- JSON array: geographic areas (populates service_area terms) +_theme_service_gallery -- JSON array: attachment IDs +_theme_service_related_services -- JSON array: post IDs (manual override; IGNY8 auto-calculates if connected) +``` + +**Portfolio Meta Fields:** + +``` +_theme_portfolio_client -- Text: client name +_theme_portfolio_date -- Date: project completion date +_theme_portfolio_url -- URL: live project link +_theme_portfolio_results -- JSON array: [{metric, value, description}] e.g., "50% increase in traffic" +_theme_portfolio_technologies -- Text: comma-separated tech/tools used +_theme_portfolio_testimonial_id -- Int: linked testimonial post ID +_theme_portfolio_gallery -- JSON array: attachment IDs +_theme_portfolio_before_after -- JSON: {before_image, after_image} +``` + +**Team Member Meta Fields:** + +``` +_theme_team_position -- Text: job title +_theme_team_email -- Email +_theme_team_phone -- Text +_theme_team_social -- JSON: {linkedin, twitter, facebook, website} +_theme_team_order -- Int: display order +_theme_team_department -- Text: department/group +``` + +**Testimonial Meta Fields:** + +``` +_theme_testimonial_author_name -- Text: person's name +_theme_testimonial_author_title -- Text: job title +_theme_testimonial_company -- Text: company name +_theme_testimonial_rating -- Int: 1-5 stars +_theme_testimonial_image -- Attachment ID: author photo +_theme_testimonial_featured -- Boolean: show in featured sections +_theme_testimonial_service_id -- Int: linked service post ID +_theme_testimonial_product_id -- Int: linked product ID (WooCommerce) +``` + +**FAQ Meta Fields:** + +``` +(FAQs use title = question, editor = answer. Additional meta:) +_theme_faq_order -- Int: display order within category +_theme_faq_schema_enabled -- Boolean: include in FAQPage schema +``` + +**Documentation Meta Fields:** + +``` +_theme_doc_sidebar_enabled -- Boolean: show doc sidebar navigation +_theme_doc_toc_enabled -- Boolean: show table of contents +_theme_doc_last_reviewed -- Date: content last reviewed date +_theme_doc_related_docs -- JSON array: related doc post IDs +``` + +### 2.4 Term Landing Page Templates + +Every taxonomy term archive in this theme renders as a **rich landing page**, not a simple post list. This is the SAG architecture in action. + +**Template hierarchy for term archives:** + +``` +taxonomy-service_category-{slug}.html → Specific service category +taxonomy-service_category.html → All service categories +taxonomy-service_area.html → Service area archives +taxonomy-service_attribute.html → Service attribute archives +taxonomy-cluster.html → Cluster hub pages +taxonomy-faq_category.html → FAQ category pages +taxonomy-product_cat.html → WooCommerce product categories +taxonomy-product_tag.html → WooCommerce product tags +taxonomy-pa_{attribute}.html → WooCommerce product attributes +archive-service.html → Services listing +archive-portfolio.html → Portfolio listing +archive-faq.html → FAQ listing +archive-documentation.html → Docs listing +``` + +**Term Landing Page Structure (universal):** + +Every term archive template follows this section order: + +``` +1. TERM HERO + - Term name as H1 + - Term description (rich content from _igny8_term_content if IGNY8 active, + otherwise standard WordPress term description) + - Breadcrumbs + - Post count + +2. KEY SUBTOPICS (if child terms exist) + - Grid of child term cards + - Each card: term name, description excerpt, post count, link + - This creates the dimensional navigation (e.g., "Emergency Plumbing" term + page shows child terms like "Burst Pipe Emergency", "Frozen Pipe Emergency") + +3. CONTENT GRID + - Posts/services/products belonging to this term + - Configurable layout: grid (2/3/4 col), list + - Filterable by secondary taxonomy if applicable + - Pagination + +4. RELATED TERMS (sibling terms in same taxonomy) + - "Related [Taxonomy Label]" section + - If IGNY8 active: reads _igny8_term_related_terms for intelligent suggestions + - If standalone: shows sibling terms (same parent) + +5. CLUSTER CROSS-LINKS (if IGNY8 active) + - "Related Topics" section + - Links to other clusters that share dimensional axes + - E.g., "Dog x Joint Health" cluster page links to "Dog x Senior Care" and "Cat x Joint Health" + +6. FAQ SECTION (if term has FAQs) + - If IGNY8 active: reads _igny8_term_faq + - If standalone: shows FAQ posts in matching faq_category + - Accordion display + +7. CTA / CONVERSION + - Configurable per term or global default + - "Get a free quote", "Browse products", "Contact us" etc. +``` + +**Cluster Hub Page Template (taxonomy-cluster.html):** + +Cluster pages are special — they're the hub of a SAG cluster. The template: + +``` +1. CLUSTER HERO + - Cluster name as H1 + - Cluster description (rich content) + - Breadcrumbs showing dimensional path + - Total content count in cluster + +2. HUB CONTENT + - The main cluster hub article content + - This is the comprehensive "pillar" page for the cluster + - Content from _igny8_term_content or editor + +3. SUPPORTING CONTENT + - All posts/services/products mapped to this cluster + - Organized by content type: posts first, then services, then products + - Each with excerpt, featured image, link + +4. ATTRIBUTE NAVIGATION + - "Browse by [Attribute]" sections + - Shows which attribute values this cluster intersects + - E.g., for "Dog Anxiety Relief Products" cluster: + "Pet Type: Dog" | "Pet Need: Anxiety Relief" | "Product Category: Health" + +5. RELATED CLUSTERS + - Other clusters sharing one or more attribute values + - Intelligent cross-linking that builds the SAG web + +6. FAQ + - Cluster-specific FAQs + +7. CTA +``` + +### 2.5 Interlinking Display Components + +The theme provides template parts that render interlinking sections. These read data from IGNY8 plugin when available, or from manual post meta when not. + +**Component: Related Content Block** + +``` +Location: After post/service/product content +Data source: _igny8_related_links post meta (array of {post_id, anchor_text, priority}) +Fallback: WordPress related posts by shared categories/tags +Display: 3-4 cards with featured image, title, excerpt +Template part: parts/related-content.html +``` + +**Component: Cluster Navigation** + +``` +Location: Sidebar or after content +Data source: IGNY8 plugin API → igny8()->linking->get_cluster_navigation($post_id) +Fallback: Posts in same cluster taxonomy term +Display: "More in [Cluster Name]" with linked list +Template part: parts/cluster-navigation.html +``` + +**Component: Attribute Browse** + +``` +Location: Term archive pages, sidebar +Data source: Custom taxonomy terms for current context +Display: Pills/tags showing browsable attribute values +Template part: parts/attribute-browse.html +E.g., on a service page: "Service Type: Emergency" | "Property: Residential" | "Area: Downtown" +``` + +**Component: Breadcrumb Trail** + +``` +Location: Below header on all pages +Data source: IGNY8 plugin breadcrumbs (if active), else theme's own breadcrumbs +Display: Home > [Taxonomy] > [Parent Term] > [Child Term] > [Post Title] +Template part: parts/breadcrumbs.html +SAG aware: Breadcrumbs follow dimensional path, not just hierarchy +``` + +**Component: Term Quick Links** + +``` +Location: Single post/service sidebar or footer +Data source: All terms assigned to current post across all taxonomies +Display: Grouped by taxonomy label: "Service Type: Emergency | Drain Cleaning" + "Property Type: Residential" + "Cluster: Emergency Drain Services" +Template part: parts/term-quick-links.html +``` + +**Component: Child Term Grid** + +``` +Location: Term archive pages (when term has children) +Data source: get_term_children() + term meta +Display: Card grid with term image, name, description, post count +Template part: parts/child-term-grid.html +``` + +--- + +## Part 3: Landing Page System + +### 3.1 Architecture + +Identical to previous plan — section-based CPT with repeater meta box. No changes needed here since landing pages are theme-owned. + +**CPT:** `landing_page` +**Meta key:** `_theme_landing_sections` (serialized array of section objects) + +### 3.2 Section Types (15 total) + +| # | Section Type | Key Fields | +|---|---|---| +| 1 | **hero** | headline, subheadline, cta_text, cta_url, cta2_text, cta2_url, background_type (color/image/gradient/video), background_value, text_alignment, overlay_opacity | +| 2 | **features-grid** | section_title, section_subtitle, columns (2/3/4), items[] (icon, title, description, link) | +| 3 | **how-it-works** | section_title, section_subtitle, steps[] (number, title, description, icon) | +| 4 | **social-proof** | section_title, layout (grid/slider/single), testimonials[] (quote, name, title, image, company, rating) | +| 5 | **pricing** | section_title, section_subtitle, billing_toggle, plans[] (name, monthly_price, annual_price, description, features[], cta_text, cta_url, is_featured, badge) | +| 6 | **faq** | section_title, section_subtitle, items[] (question, answer), schema_enabled | +| 7 | **cta-band** | headline, subheadline, cta_text, cta_url, background_color, text_color | +| 8 | **content-block** | section_title, content (wp_editor), image, image_position (left/right/top), background | +| 9 | **stats-counter** | section_title, stats[] (number, suffix, label), background, animate | +| 10 | **team** | section_title, section_subtitle, members[] (name, title, bio, image, social_links) OR pull from team_member CPT | +| 11 | **portfolio-grid** | section_title, columns, items[] (title, category, image, link, description) OR pull from portfolio CPT | +| 12 | **contact-form** | section_title, section_subtitle, form_shortcode, show_map, address, phone, email | +| 13 | **video-embed** | section_title, video_url, poster_image, autoplay, full_width | +| 14 | **logo-bar** | section_title, logos[] (image, alt, link), style (grid/scroll) | +| 15 | **comparison-table** | section_title, columns[] (heading), rows[] (label, values[]), highlight_column | + +### 3.3 Landing Page Presets + +| Preset | Sections in Order | +|---|---| +| **SaaS Product** | hero → logo-bar → features-grid → how-it-works → social-proof → pricing → faq → cta-band | +| **Service Business** | hero → features-grid → content-block → stats-counter → social-proof → team → contact-form → cta-band | +| **Product Launch** | hero → content-block → features-grid → video-embed → social-proof → pricing → faq → cta-band | +| **Lead Generation** | hero → features-grid → social-proof → cta-band | +| **Portfolio / Agency** | hero → portfolio-grid → how-it-works → social-proof → stats-counter → contact-form | +| **Event / Webinar** | hero → content-block → features-grid → social-proof → faq → cta-band | +| **Cluster Hub** | hero → content-block → features-grid → faq → cta-band | +| **Term Landing** | hero → content-block → features-grid → social-proof → faq → cta-band | + +The last two presets are specifically for when IGNY8 generates hub/term content — the content gets pasted into the section fields for immediate designed output. + +--- + +## Part 4: Theme File Structure + +``` +theme-name/ +├── style.css +├── theme.json +├── functions.php +├── screenshot.png +│ +├── assets/ +│ ├── css/ +│ │ ├── base.css # Reset, typography, utilities (~25KB) +│ │ ├── blocks.css # Block pattern styles +│ │ ├── components.css # Shared components (cards, buttons, badges, etc.) +│ │ ├── landing-sections.css # Landing page section styles +│ │ ├── term-pages.css # Term archive / landing page styles +│ │ ├── woocommerce.css # WooCommerce overrides (conditional) +│ │ └── admin.css # Admin-only styles +│ ├── js/ +│ │ ├── app.js # Core frontend (~8KB) +│ │ ├── navigation.js # Mobile menu, dropdowns +│ │ ├── scroll-effects.js # Sticky header, smooth scroll, back-to-top +│ │ ├── counter-animation.js # Stats counter animation (conditional) +│ │ ├── accordion.js # FAQ accordion (conditional) +│ │ ├── landing-page-admin.js # Section builder admin UI +│ │ └── meta-box-admin.js # CPT meta box admin UI +│ ├── images/ +│ │ └── placeholder.svg +│ └── fonts/ +│ ├── inter-400.woff2 +│ ├── inter-500.woff2 +│ ├── inter-600.woff2 +│ └── inter-700.woff2 +│ +├── inc/ +│ ├── setup.php # Theme supports, menus, sidebars, image sizes +│ ├── cleanup.php # Remove WP bloat +│ ├── enqueue.php # Conditional asset loading +│ ├── template-tags.php # Template helper functions +│ ├── breadcrumbs.php # Fallback breadcrumbs (when IGNY8 not active) +│ ├── walkers.php # Custom menu walkers +│ ├── customizer.php # Theme customizer settings +│ ├── theme-bridge.php # IGNY8 plugin detection + data reading +│ │ +│ ├── cpt/ # Custom Post Types +│ │ ├── register.php # All CPT registrations +│ │ ├── service.php # Service CPT specifics + meta boxes +│ │ ├── landing-page.php # Landing page CPT specifics +│ │ ├── portfolio.php # Portfolio CPT + meta boxes +│ │ ├── team-member.php # Team member CPT + meta boxes +│ │ ├── testimonial.php # Testimonial CPT + meta boxes +│ │ ├── faq.php # FAQ CPT + meta boxes +│ │ └── documentation.php # Documentation CPT + meta boxes +│ │ +│ ├── taxonomies/ # Custom Taxonomies +│ │ ├── register.php # All taxonomy registrations +│ │ ├── service-category.php # Service category specifics +│ │ ├── service-area.php # Service area specifics +│ │ ├── service-attribute.php # Service attribute specifics +│ │ ├── cluster.php # Content cluster taxonomy +│ │ ├── portfolio-category.php # Portfolio category +│ │ ├── faq-category.php # FAQ category +│ │ └── doc-category.php # Documentation category +│ │ +│ ├── meta-fields/ # Meta box definitions +│ │ ├── class-meta-box-base.php # Base meta box class +│ │ ├── service-meta.php # Service meta fields +│ │ ├── portfolio-meta.php # Portfolio meta fields +│ │ ├── team-meta.php # Team member meta fields +│ │ ├── testimonial-meta.php # Testimonial meta fields +│ │ ├── faq-meta.php # FAQ meta fields +│ │ └── doc-meta.php # Documentation meta fields +│ │ +│ ├── landing-pages/ # Landing page system +│ │ ├── register-cpt.php # (delegated from cpt/landing-page.php) +│ │ ├── meta-boxes.php # Section repeater meta box +│ │ ├── presets.php # Pre-built page layouts +│ │ ├── render.php # Frontend section renderer +│ │ └── sections/ # Individual section templates +│ │ ├── hero.php +│ │ ├── features-grid.php +│ │ ├── how-it-works.php +│ │ ├── social-proof.php +│ │ ├── pricing.php +│ │ ├── faq.php +│ │ ├── cta-band.php +│ │ ├── content-block.php +│ │ ├── stats-counter.php +│ │ ├── team.php +│ │ ├── portfolio-grid.php +│ │ ├── contact-form.php +│ │ ├── video-embed.php +│ │ ├── logo-bar.php +│ │ └── comparison-table.php +│ │ +│ ├── interlinking/ # Interlinking display components +│ │ ├── related-content.php # Related content block (reads IGNY8 data) +│ │ ├── cluster-navigation.php # "More in this cluster" block +│ │ ├── attribute-browse.php # Attribute pills/tag navigation +│ │ ├── term-quick-links.php # Term assignments display +│ │ └── child-term-grid.php # Child term card grid +│ │ +│ ├── blocks/ # Custom Gutenberg blocks +│ │ ├── register.php +│ │ ├── pricing-table/ +│ │ ├── feature-grid/ +│ │ ├── testimonial-slider/ +│ │ ├── stats-counter/ +│ │ ├── team-grid/ +│ │ ├── faq-accordion/ +│ │ ├── cta-banner/ +│ │ ├── logo-carousel/ +│ │ ├── comparison-table/ +│ │ ├── icon-box/ +│ │ ├── service-grid/ # Pulls from service CPT +│ │ ├── portfolio-showcase/ # Pulls from portfolio CPT +│ │ └── doc-sidebar/ # Documentation navigation +│ │ +│ └── patterns/ # Block patterns +│ ├── register.php +│ ├── heroes/ +│ │ ├── hero-centered.php +│ │ ├── hero-split.php +│ │ ├── hero-video-bg.php +│ │ └── hero-slider.php +│ ├── content/ +│ │ ├── features-3col.php +│ │ ├── features-alternating.php +│ │ ├── how-it-works.php +│ │ └── benefits-icons.php +│ ├── social-proof/ +│ │ ├── testimonials-grid.php +│ │ ├── testimonials-slider.php +│ │ ├── logo-bar.php +│ │ └── stats-row.php +│ ├── conversion/ +│ │ ├── cta-simple.php +│ │ ├── cta-with-form.php +│ │ ├── pricing-section.php +│ │ └── newsletter-signup.php +│ ├── services/ # Service-specific patterns +│ │ ├── service-cards.php +│ │ ├── service-list.php +│ │ └── service-with-sidebar.php +│ ├── portfolio/ +│ │ ├── portfolio-grid.php +│ │ ├── portfolio-masonry.php +│ │ └── case-study-layout.php +│ └── footers/ +│ ├── footer-4col.php +│ ├── footer-centered.php +│ └── footer-minimal.php +│ +├── templates/ # FSE templates +│ ├── index.html +│ ├── home.html +│ ├── single.html # Single post +│ ├── single-service.html # Single service +│ ├── single-portfolio.html # Single portfolio item +│ ├── single-landing_page.html # Landing page (section renderer) +│ ├── single-documentation.html # Single doc (with sidebar nav) +│ ├── page.html +│ ├── archive.html # Default archive +│ ├── archive-service.html # Services listing +│ ├── archive-portfolio.html # Portfolio listing +│ ├── archive-faq.html # FAQ listing +│ ├── archive-documentation.html # Docs home +│ ├── taxonomy-service_category.html # Service category term page +│ ├── taxonomy-service_area.html # Service area term page +│ ├── taxonomy-service_attribute.html # Service attribute term page +│ ├── taxonomy-cluster.html # Cluster hub page +│ ├── taxonomy-faq_category.html # FAQ category page +│ ├── taxonomy-product_cat.html # WooCommerce product category (rich landing) +│ ├── taxonomy-product_tag.html # WooCommerce product tag +│ ├── search.html +│ ├── 404.html +│ │ +│ ├── starter-blog/ +│ │ ├── front-page.html +│ │ ├── single.html +│ │ └── archive.html +│ ├── starter-saas/ +│ │ ├── front-page.html +│ │ ├── page-features.html +│ │ ├── page-pricing.html +│ │ └── page-docs.html +│ ├── starter-corporate/ +│ │ ├── front-page.html +│ │ ├── page-about.html +│ │ ├── page-services.html +│ │ └── page-contact.html +│ ├── starter-ecommerce/ +│ │ ├── front-page.html +│ │ ├── archive-product.html +│ │ └── single-product.html +│ └── starter-portfolio/ +│ ├── front-page.html +│ ├── archive-portfolio.html +│ └── single-portfolio.html +│ +├── parts/ # FSE template parts +│ ├── header.html +│ ├── header-transparent.html +│ ├── header-minimal.html +│ ├── footer.html +│ ├── footer-minimal.html +│ ├── sidebar.html +│ ├── sidebar-docs.html # Documentation sidebar navigation +│ ├── post-meta.html +│ ├── author-box.html +│ ├── related-content.html # Related content (reads IGNY8 data) +│ ├── cluster-navigation.html # Cluster siblings +│ ├── attribute-browse.html # Attribute term pills +│ ├── term-quick-links.html # Assigned terms display +│ ├── child-term-grid.html # Child term cards +│ ├── breadcrumbs.html # Breadcrumbs (IGNY8 or fallback) +│ ├── term-hero.html # Term archive hero section +│ ├── term-content.html # Term rich content section +│ ├── term-faq.html # Term FAQ section +│ ├── comments.html +│ └── pagination.html +│ +└── woocommerce/ # WooCommerce template overrides + ├── archive-product.php # Shop page (SAG-structured) + ├── single-product.php # Product page (enhanced) + ├── taxonomy-product_cat.php # Product category (rich landing) + ├── content-product.php # Product card in archives + ├── cart/ + ├── checkout/ + └── myaccount/ +``` + +--- + +## Part 5: Toolkit Plugin (Companion) + +### 5.1 Scope + +Only site infrastructure — no SEO, no social, no analytics (those are in IGNY8 plugin). + +| Module | Purpose | Replaces | +|---|---|---| +| **Performance** | Page cache, asset optimization, image optimization, critical CSS, HTML minification, preload/prefetch | WP Rocket, LiteSpeed Cache, Smush | +| **Forms** | Form builder, submissions, notifications, anti-spam | Contact Form 7, Gravity Forms | +| **Security** | Login protection, firewall, hardening, security headers, audit log | Wordfence, Sucuri | +| **SMTP** | Mail delivery override, email log, test email | WP Mail SMTP | +| **WooCommerce** | Quick view, wishlist, AJAX cart, product filters, enhanced gallery | 5-6 separate Woo plugins | + +### 5.2 Plugin File Structure + +``` +theme-name-toolkit/ +├── theme-name-toolkit.php +├── readme.txt +│ +├── includes/ +│ ├── class-toolkit.php # Main class +│ ├── class-module-manager.php # Module toggle system +│ │ +│ ├── modules/ +│ │ ├── performance/ +│ │ │ ├── class-performance-module.php +│ │ │ ├── class-page-cache.php +│ │ │ ├── class-asset-optimizer.php +│ │ │ ├── class-image-optimizer.php +│ │ │ ├── class-critical-css.php +│ │ │ ├── class-html-minifier.php +│ │ │ ├── class-browser-cache.php +│ │ │ ├── class-preload.php +│ │ │ └── class-database-optimizer.php +│ │ │ +│ │ ├── forms/ +│ │ │ ├── class-forms-module.php +│ │ │ ├── class-form-builder.php +│ │ │ ├── class-form-renderer.php +│ │ │ ├── class-form-processor.php +│ │ │ ├── class-form-notifications.php +│ │ │ ├── class-form-entries.php +│ │ │ └── class-form-antispam.php +│ │ │ +│ │ ├── security/ +│ │ │ ├── class-security-module.php +│ │ │ ├── class-login-protection.php +│ │ │ ├── class-firewall.php +│ │ │ ├── class-hardening.php +│ │ │ ├── class-headers.php +│ │ │ └── class-audit-log.php +│ │ │ +│ │ ├── smtp/ +│ │ │ ├── class-smtp-module.php +│ │ │ ├── class-smtp-mailer.php +│ │ │ ├── class-email-log.php +│ │ │ └── class-email-test.php +│ │ │ +│ │ └── woocommerce/ +│ │ ├── class-woo-module.php +│ │ ├── class-quick-view.php +│ │ ├── class-wishlist.php +│ │ ├── class-ajax-cart.php +│ │ ├── class-product-filters.php +│ │ └── class-product-gallery.php +│ │ +│ └── admin/ +│ ├── class-dashboard.php +│ └── views/ +│ └── dashboard.php +│ +└── languages/ +``` + +--- + +## Part 6: Design System (theme.json) + +Same as previous plan — complete design token system with colors, typography, spacing, shadows, border radius, transitions. No changes needed. + +Key additions specific to SAG: + +```jsonc +{ + "custom": { + // Term page specific tokens + "termPage": { + "heroPadding": "4rem", + "sectionGap": "3rem", + "childTermCardMinWidth": "250px" + }, + // Interlinking component tokens + "interlink": { + "relatedBg": "var(--wp--preset--color--surface)", + "clusterNavBorder": "var(--wp--preset--color--primary-light)", + "attributePillBg": "var(--wp--preset--color--primary-light)", + "attributePillText": "var(--wp--preset--color--primary-dark)" + } + } +} +``` + +--- + +## Part 7: Setup Wizard + +Theme activation launches a wizard (works independently of plugin wizards): + +### Step 1: Site Type +- Blog, SaaS, eCommerce, Corporate/Services, Portfolio +- Determines: which CPTs are active, which starter templates import, which patterns are highlighted + +### Step 2: Brand Identity +- Logo upload +- Primary color (generates full palette) +- Font selection (heading + body from curated list) +- Live preview panel + +### Step 3: CPT Configuration +Based on site type, shows which CPTs will be enabled: +- Services site → Services, FAQ, Testimonials, Team enabled +- SaaS site → Documentation, FAQ, Team enabled +- eCommerce → WooCommerce detected, FAQ, Testimonials enabled +- Blog → FAQ enabled, others optional +- User can toggle any CPT on/off + +### Step 4: Demo Content Import +- Import starter content for selected site type +- Or start blank +- Creates: homepage, core pages, sample CPT entries, sample taxonomy terms + +### Step 5: Plugin Recommendations +- "For full SEO and content intelligence, install IGNY8 plugin" +- "For performance and security, install [Theme] Toolkit" +- Download/install buttons (or WordPress.org search links) + +--- + +## Part 8: Build Execution Plan + +### Phase 1: Foundation (Days 1-3) + +| Day | Task | +|---|---| +| 1 | Theme skeleton: style.css, functions.php, theme.json (full tokens), cleanup.php, enqueue.php | +| 1 | FSE base: index.html, single.html, page.html, archive.html, 404.html, search.html | +| 2 | Template parts: header.html (3 variants), footer.html (3 variants), sidebar.html, breadcrumbs.html | +| 2 | CSS design system: base.css (reset, typography, utilities), components.css (cards, buttons, badges, forms) | +| 3 | Core JS: app.js, navigation.js, scroll-effects.js | +| 3 | Theme customizer: logo, colors, fonts, layout options | + +### Phase 2: CPTs + Taxonomies (Days 4-6) + +| Day | Task | +|---|---| +| 4 | Register all 7 CPTs with full configuration (supports, rewrite rules, menu icons) | +| 4 | Register all custom taxonomies with hierarchical/non-hierarchical settings | +| 5 | Meta boxes: service meta, portfolio meta, team meta, testimonial meta | +| 5 | Meta boxes: FAQ meta, documentation meta | +| 6 | Admin UI: meta box JS for repeater fields (process steps, outcomes, gallery, social links) | +| 6 | Theme bridge: IGNY8 plugin detection, graceful fallback functions | + +### Phase 3: Term Landing Page Templates (Days 7-9) + +| Day | Task | +|---|---| +| 7 | Term hero template part: H1, description, breadcrumbs, post count | +| 7 | Term content template part: rich content from IGNY8 or WP description | +| 8 | Child term grid template part | +| 8 | Term archive templates: taxonomy-service_category, taxonomy-service_area, taxonomy-service_attribute | +| 9 | Term archive templates: taxonomy-cluster (hub page), taxonomy-faq_category | +| 9 | WooCommerce term templates: taxonomy-product_cat, taxonomy-product_tag | +| 9 | Term page CSS: term-pages.css | + +### Phase 4: Interlinking Display (Days 10-11) + +| Day | Task | +|---|---| +| 10 | Related content component: read IGNY8 data or fallback to category matching | +| 10 | Cluster navigation component: sidebar/footer cluster siblings | +| 11 | Attribute browse component: term pills navigation | +| 11 | Term quick links, child term grid finalization | +| 11 | Integration testing: all components with IGNY8 active and inactive | + +### Phase 5: Landing Page System (Days 12-14) + +| Day | Task | +|---|---| +| 12 | Landing page CPT + section repeater meta box | +| 12 | Admin JS: dynamic section fields, drag-to-reorder, add/remove/duplicate | +| 13 | Section templates (first 8): hero, features-grid, how-it-works, social-proof, pricing, faq, cta-band, content-block | +| 13 | Section CSS: landing-sections.css | +| 14 | Section templates (remaining 7): stats-counter, team, portfolio-grid, contact-form, video-embed, logo-bar, comparison-table | +| 14 | Presets: all 8 preset configurations, preset loader on page creation | +| 14 | Frontend renderer: section loop, responsive testing | + +### Phase 6: Single Templates (Days 15-16) + +| Day | Task | +|---|---| +| 15 | single-service.html: hero, content, process steps, outcomes, gallery, FAQs, related services, CTA | +| 15 | single-portfolio.html: hero, content, results, gallery, before/after, testimonial, related projects | +| 16 | single-documentation.html: sidebar nav, content, TOC, related docs, prev/next navigation | +| 16 | archive templates: archive-service, archive-portfolio, archive-faq, archive-documentation | + +### Phase 7: Custom Blocks + Patterns (Days 17-19) + +| Day | Task | +|---|---| +| 17 | Custom blocks: pricing-table, feature-grid, testimonial-slider, stats-counter, faq-accordion | +| 18 | Custom blocks: team-grid, cta-banner, logo-carousel, comparison-table, icon-box | +| 18 | Custom blocks: service-grid (CPT-powered), portfolio-showcase (CPT-powered), doc-sidebar | +| 19 | Block patterns: heroes (4), content (4), social proof (4), conversion (4), services (3), portfolio (3), footers (3) | + +### Phase 8: Site-Type Starters + WooCommerce (Days 20-22) + +| Day | Task | +|---|---| +| 20 | Starter templates: blog (homepage, single, archive) | +| 20 | Starter templates: SaaS (homepage, features, pricing, docs) | +| 21 | Starter templates: corporate (homepage, about, services, contact) | +| 21 | Starter templates: eCommerce (homepage, shop, product) | +| 22 | Starter templates: portfolio (homepage, portfolio, case study) | +| 22 | WooCommerce template overrides: shop, product, cart, checkout, account | + +### Phase 9: Toolkit Plugin (Days 23-27) + +| Day | Task | +|---|---| +| 23 | Plugin skeleton: main file, module manager, dashboard | +| 23 | Performance module: page cache, HTML minifier | +| 24 | Performance module: asset optimizer, image optimizer, WebP, lazy load | +| 24 | Performance module: critical CSS, preload, browser cache | +| 25 | Forms module: builder UI, field types, renderer, processor | +| 25 | Forms module: notifications, entries admin, anti-spam | +| 26 | Security module: login protection, firewall, hardening, headers, audit log | +| 26 | SMTP module: mailer, email log, test email | +| 27 | WooCommerce module: quick view, ajax cart, wishlist, product filters | + +### Phase 10: Setup Wizard + Polish (Days 28-30) + +| Day | Task | +|---|---| +| 28 | Setup wizard: 5-step flow (site type → brand → CPTs → demo → plugins) | +| 28 | Demo content: sample data for each site type | +| 29 | Cross-component testing: all CPTs, taxonomies, templates, interlinking | +| 29 | Performance audit: measure load times per site type | +| 30 | Responsive testing: all templates at all breakpoints | +| 30 | Accessibility: ARIA labels, keyboard nav, contrast | +| 30 | Package: readme.txt, screenshot, build script | + +--- + +## Part 9: Performance Targets + +Same targets as previous plan: + +| Metric | Target | +|---|---| +| First Contentful Paint | < 1.0s | +| Largest Contentful Paint | < 1.5s | +| Total Blocking Time | < 50ms | +| Cumulative Layout Shift | < 0.05 | +| Page Weight | < 200KB (uncached) | +| PageSpeed Score | 95+ mobile | +| Theme CSS total | < 35KB gzipped | +| Frontend JS total | < 15KB gzipped | + +--- + +## Part 10: Naming Conventions + +### PHP +- Theme prefix: `themename_` (replace with chosen name) +- Toolkit prefix: `themename_toolkit_` +- CPT slugs: `service`, `landing_page`, `portfolio`, `team_member`, `testimonial`, `faq`, `documentation` +- Taxonomy slugs: `service_category`, `service_area`, `service_attribute`, `cluster`, `portfolio_category`, `portfolio_tag`, `faq_category`, `doc_category`, `topic_tag` +- Meta key prefix: `_theme_` for theme meta, reads `_igny8_` for plugin data +- Text domain: `theme-name` + +### CSS +- BEM: `.tn-block__element--modifier` +- Term page classes: `.tn-term-hero`, `.tn-term-content`, `.tn-child-grid` +- Landing section classes: `.tn-section--hero`, `.tn-section--pricing` +- Interlinking classes: `.tn-related`, `.tn-cluster-nav`, `.tn-attribute-browse` + +### JavaScript +- ES6+, vanilla JS, no jQuery on frontend +- Each feature in own file, loaded conditionally + +--- + +## Part 11: Free vs Premium Split (WordPress.org) + +**Free Theme (WordPress.org):** +- All CPTs and taxonomies +- All term landing page templates +- Basic interlinking display components +- 3 landing page section types (hero, content-block, cta-band) +- 2 presets (generic, service) +- 10 block patterns (2 per category) +- 2 starter templates (blog, corporate) +- IGNY8 plugin bridge (full) +- Basic customizer options + +**Premium Theme:** +- All 15 landing page section types +- All 8 presets +- All 50+ block patterns +- All 5 starter templates +- WooCommerce templates +- Setup wizard with demo import +- Priority support +- Updates for 1 year + +**Free Toolkit Plugin (WordPress.org):** +- Performance: page cache + HTML minification +- Security: basic hardening + login protection +- Forms: basic form builder (5 field types) +- SMTP: basic mail override + +**Premium Toolkit:** +- Performance: full suite (critical CSS, image optimization, WebP, asset optimization) +- Security: full suite (firewall, audit log, 2FA) +- Forms: full suite (conditional logic, multi-step, file upload, entries management) +- SMTP: full suite (email log, templates) +- WooCommerce: all enhancements + +--- + +*End of Theme Build Plan* diff --git a/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/ARCHITECTURE.md b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/ARCHITECTURE.md new file mode 100644 index 00000000..6e35ad45 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/ARCHITECTURE.md @@ -0,0 +1,346 @@ +# System Architecture + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Backend Path:** `backend/igny8_core/` +**Frontend Path:** `frontend/src/` + +--- + +## Tech Stack + +| Layer | Technology | Version | Purpose | +|-------|------------|---------|---------| +| **Backend Framework** | Django | 5.1 | Web framework | +| **API Layer** | Django REST Framework | 3.15 | REST API | +| **Database** | PostgreSQL | 16 | Primary data store | +| **Cache/Queue** | Redis | 7 | Caching, Celery broker | +| **Task Queue** | Celery | 5.4 | Async task processing | +| **Frontend Framework** | React | 19 | UI framework | +| **Build Tool** | Vite | 5 | Frontend bundler | +| **Styling** | Tailwind CSS | 3 | Utility CSS | +| **State Management** | Zustand | 4 | React state | +| **Language** | TypeScript | 5 | Frontend typing | +| **Web Server** | Caddy | 2 | Reverse proxy, SSL | +| **Containerization** | Docker | - | Deployment | + +--- + +## High-Level Architecture + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ CLIENTS │ +│ React SPA (app.igny8.com) │ WordPress Plugin │ Admin │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ CADDY (Reverse Proxy) │ +│ SSL termination, routing, static files │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ DJANGO REST FRAMEWORK │ +│ │ +│ Middleware Stack: │ +│ SecurityMiddleware → WhiteNoise → CORS → Session → CSRF → │ +│ DjangoAuth → RequestIDMiddleware → AccountContextMiddleware → │ +│ ResourceTrackingMiddleware │ +│ │ +│ API: /api/v1/* → ViewSets → Services → Models │ +└─────────────────────────────────────────────────────────────────┘ + │ │ + ▼ ▼ +┌─────────────────────┐ ┌─────────────────────────────────────┐ +│ PostgreSQL │ │ Redis │ +│ Primary Database │ │ Sessions, Cache, Celery Broker │ +└─────────────────────┘ └─────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ CELERY WORKERS │ +│ AI Tasks, Automation, Publishing, Background Jobs │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ EXTERNAL SERVICES │ +│ OpenAI │ Anthropic │ Runware │ Bria │ WordPress Sites │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## Backend Structure + +``` +backend/igny8_core/ +├── settings.py # Django settings, all config +├── urls.py # Root URL routing +├── celery.py # Celery configuration +├── wsgi.py / asgi.py # WSGI/ASGI entry points +│ +├── auth/ # Authentication & tenancy +│ ├── models.py # User, Account, Site, Sector, Plan +│ ├── views.py # Login, register, password reset +│ ├── middleware.py # AccountContextMiddleware +│ └── urls.py # /api/v1/auth/* +│ +├── api/ # API infrastructure +│ ├── base.py # AccountModelViewSet, SiteSectorModelViewSet +│ ├── authentication.py # JWT, API key auth classes +│ └── pagination.py # Unified pagination +│ +├── ai/ # AI engine +│ ├── engine.py # AIEngine orchestrator +│ ├── functions/ # AutoCluster, GenerateIdeas, GenerateContent, etc. +│ ├── registry.py # Function registry +│ ├── model_registry.py # Model Registry service (v1.3.0) +│ └── progress.py # Progress tracking +│ +├── modules/ # Feature modules (API layer) +│ ├── planner/ # Keywords, Clusters, Ideas +│ ├── writer/ # Tasks, Content, Images +│ ├── billing/ # Credits, usage, transactions +│ ├── integration/ # WordPress integration +│ ├── system/ # Settings, prompts, AI config +│ ├── linker/ # Internal linking (inactive) +│ ├── optimizer/ # Content optimization (inactive) +│ └── publisher/ # Publishing pipeline +│ +├── business/ # Business logic (services) +│ ├── automation/ # 7-stage automation pipeline +│ ├── billing/ # Credit service, payment processing +│ ├── content/ # Content generation orchestration +│ ├── integration/ # Sync services +│ ├── linking/ # Link processing +│ ├── notifications/ # Notification system (v1.2.0) +│ ├── optimization/ # Content optimization +│ ├── planning/ # Clustering, idea generation +│ └── publishing/ # Publishing orchestration +│ +├── middleware/ # Custom middleware +│ ├── request_id.py # X-Request-ID header +│ └── resource_tracker.py # Resource tracking for admins +│ +└── tasks/ # Celery tasks + └── *.py # Background job definitions +``` + +--- + +## Frontend Structure + +``` +frontend/src/ +├── main.tsx # Entry point +├── App.tsx # Root component, routing +├── index.css # Global styles, Tailwind +│ +├── api/ # API clients +│ ├── linker.api.ts +│ ├── optimizer.api.ts +│ └── ... +│ +├── services/ +│ ├── api.ts # Main API service (2500+ lines) +│ └── notifications.api.ts # Notification API (v1.2.0) +│ +├── store/ # Zustand stores +│ ├── authStore.ts # Authentication state +│ ├── siteStore.ts # Active site +│ ├── sectorStore.ts # Active sector +│ ├── billingStore.ts # Billing state +│ ├── moduleStore.ts # Module enable/disable +│ ├── notificationStore.ts # Notifications (v1.2.0) +│ └── ... +│ +├── pages/ # Route pages +│ ├── Dashboard/ +│ ├── Planner/ +│ ├── Writer/ +│ ├── Automation/ +│ ├── Linker/ +│ ├── Optimizer/ +│ ├── Settings/ +│ ├── Billing/ +│ └── Auth/ +│ +├── components/ # Reusable components +│ ├── common/ +│ │ ├── ProgressModal.tsx # AI progress display +│ │ ├── SearchModal.tsx # Global search (v1.1.9) +│ │ └── ... +│ ├── dashboard/ # Dashboard widgets (v1.2.0) +│ │ ├── WorkflowPipelineWidget.tsx +│ │ ├── AIOperationsWidget.tsx +│ │ ├── RecentActivityWidget.tsx +│ │ ├── ContentVelocityWidget.tsx +│ │ ├── AutomationStatusWidget.tsx +│ │ ├── ThreeWidgetFooter.tsx +│ │ └── ... +│ └── header/ +│ └── NotificationDropdown.tsx +│ +├── context/ # React contexts (v1.1.9) +│ └── PageContext.tsx # Page-level state +│ +├── layout/ # Layout components +│ ├── AppLayout.tsx +│ ├── AppHeader.tsx +│ └── AppSidebar.tsx +│ +├── hooks/ # Custom hooks +│ └── useWorkflowStats.ts # Automation stats hook (v1.3.0) +├── context/ # React contexts +└── utils/ # Utility functions +``` + +--- + +## Key Design Patterns + +### 1. Multi-Tenant Data Isolation + +All data is scoped to Account, with optional Site and Sector filtering: + +``` +Account (Tenant) + └── Site (e.g., myblog.com) + └── Sector (e.g., Technology, Health) + └── Keywords/Clusters/Ideas/Content +``` + +**Implementation:** +- `AccountBaseModel` - Base class for account-scoped models +- `SiteSectorBaseModel` - Base class for site/sector-scoped models +- `AccountModelViewSet` - Auto-filters queryset by request.account +- `SiteSectorModelViewSet` - Auto-filters by account + site + sector + +### 2. Middleware-First Tenant Resolution + +```python +# Order in settings.py MIDDLEWARE +1. SecurityMiddleware +2. WhiteNoiseMiddleware +3. CorsMiddleware +4. SessionMiddleware +5. DjangoAuthenticationMiddleware +6. RequestIDMiddleware # Assigns X-Request-ID +7. AccountContextMiddleware # Sets request.account from session/JWT +8. ResourceTrackingMiddleware # Optional admin profiling +``` + +### 3. Unified API Responses + +All API responses follow this structure: + +```json +{ + "success": true, + "data": { ... }, + "message": "Optional message" +} +``` + +Error responses: +```json +{ + "success": false, + "error": "Error message", + "code": "ERROR_CODE" +} +``` + +### 4. Credit-Based Operations + +All AI operations check and deduct credits: +1. Pre-check: `CreditService.check_credits()` +2. Execute: AI function runs +3. Post-deduct: `CreditService.deduct_credits_for_operation()` + +--- + +## Environment Configuration + +Key environment variables (from `settings.py`): + +| Variable | Purpose | +|----------|---------| +| `DATABASE_URL` | PostgreSQL connection | +| `REDIS_URL` | Redis connection | +| `SECRET_KEY` | Django secret | +| `JWT_SECRET_KEY` | JWT signing key | +| `CORS_ALLOWED_ORIGINS` | Allowed frontend origins | +| `CELERY_BROKER_URL` | Celery broker (Redis) | + +AI keys are stored in `GlobalIntegrationSettings` (database), not env vars. + +--- + +## Deployment Architecture + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Docker Compose │ +│ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ Frontend │ │ Backend │ │ Worker │ │ +│ │ (Caddy) │ │ (Django) │ │ (Celery) │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +│ │ │ │ │ +│ └────────────────┼────────────────┘ │ +│ │ │ +│ ┌─────────────┐ ┌─────────────┐ │ +│ │ PostgreSQL │ │ Redis │ │ +│ └─────────────┘ └─────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## Model Registry (v1.3.0) + +The Model Registry provides centralized AI model configuration with database-stored pricing and settings: + +```python +# backend/igny8_core/ai/model_registry.py +from igny8_core.modules.system.models import AIModelConfig + +class ModelRegistry: + """Centralized AI model configuration service""" + + @classmethod + def get_model(cls, model_id: str) -> AIModelConfig: + """Get model config by ID""" + return AIModelConfig.objects.get(model_id=model_id) + + @classmethod + def get_active_models_by_type(cls, model_type: str) -> QuerySet: + """Get all active models for a type (text, image, etc.)""" + return AIModelConfig.objects.filter( + model_type=model_type, + is_active=True + ) +``` + +**Supported Providers:** +| Provider | Types | Integration | +|----------|-------|-------------| +| OpenAI | Text, Image | GPT-4o, GPT-4-turbo, DALL-E 3 | +| Anthropic | Text | Claude 3.5 Sonnet, Claude 3 Opus | +| Runware | Image | RunwareFLUX, SD 3.5 | +| Bria | Image | Bria 2.3 | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| ~~AIModelConfig Database~~ | ✅ v1.3.0 | ~~Move AI model pricing from constants to database~~ | +| ~~Multi-provider AI~~ | ✅ v1.3.0 | ~~Support for Anthropic, Bria~~ | +| Module Guard Extension | 🔜 Planned | Extend linker/optimizer disable to all pages (currently sidebar only) | +| Google AI Integration | 🔜 Planned | Support for Gemini models | diff --git a/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/AUTH-FLOWS.md b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/AUTH-FLOWS.md new file mode 100644 index 00000000..9ef7c5dc --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/AUTH-FLOWS.md @@ -0,0 +1,255 @@ +# Authentication & Authorization + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Backend Path:** `backend/igny8_core/auth/` +**Frontend Path:** `frontend/src/store/authStore.ts` + +--- + +## Quick Reference + +| What | File | Key Functions | +|------|------|---------------| +| User Model | `auth/models.py` | `User`, `Account`, `Plan` | +| Auth Views | `auth/views.py` | `LoginView`, `RegisterView`, `RefreshTokenView` | +| Middleware | `auth/middleware.py` | `AccountContextMiddleware` | +| JWT Auth | `api/authentication.py` | `JWTAuthentication`, `CookieJWTAuthentication` | +| API Key Auth | `api/authentication.py` | `APIKeyAuthentication` | +| Frontend Store | `store/authStore.ts` | `useAuthStore` | + +--- + +## Authentication Methods + +### 1. JWT Token Authentication (Primary) + +**Flow:** +1. User logs in via `/api/v1/auth/login/` +2. Backend returns `access_token` (15 min) + `refresh_token` (7 days) +3. Frontend stores tokens in localStorage and Zustand store +4. All API requests include `Authorization: Bearer ` +5. Token refresh via `/api/v1/auth/token/refresh/` + +**Token Payload:** +```json +{ + "user_id": 123, + "account_id": 456, + "email": "user@example.com", + "exp": 1735123456, + "iat": 1735122456 +} +``` + +### 2. Session Authentication (Admin/Fallback) + +- Used by Django Admin interface +- Cookie-based session with CSRF protection +- Redis-backed sessions (prevents user swapping bug) + +### 3. API Key Authentication (WordPress Bridge) + +**Flow:** +1. Account generates API key in settings +2. WordPress plugin uses `Authorization: ApiKey ` +3. Backend validates key, sets `request.account` and `request.site` + +**Use Cases:** +- WordPress content sync +- External integrations +- Headless CMS connections + +--- + +## API Endpoints + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| POST | `/api/v1/auth/register/` | `RegisterView` | Create new user + account | +| POST | `/api/v1/auth/login/` | `LoginView` | Authenticate, return tokens | +| POST | `/api/v1/auth/logout/` | `LogoutView` | Invalidate tokens | +| POST | `/api/v1/auth/token/refresh/` | `RefreshTokenView` | Refresh access token | +| POST | `/api/v1/auth/password/change/` | `ChangePasswordView` | Change password | +| POST | `/api/v1/auth/password/reset/` | `RequestPasswordResetView` | Request reset email | +| POST | `/api/v1/auth/password/reset/confirm/` | `ResetPasswordView` | Confirm reset with token | + +--- + +## User Roles + +| Role | Code | Permissions | +|------|------|-------------| +| **Developer** | `developer` | Full access across ALL accounts (superuser) | +| **Owner** | `owner` | Full access to own account (account creator) | +| **Admin** | `admin` | Full access to own account, billing, team management | +| **Editor** | `editor` | Content creation and editing only | +| **Viewer** | `viewer` | Read-only access to content | +| **System Bot** | `system_bot` | System automation (internal) | + +**Role Hierarchy:** +``` +developer > owner > admin > editor > viewer +``` + +--- + +## Middleware: AccountContextMiddleware + +**File:** `auth/middleware.py` + +**Purpose:** Injects `request.account` on every request + +**Flow:** +1. Check for JWT token → extract account_id +2. Check for session → get account from session +3. Check for API key → get account from key +4. Validate account exists and is active +5. Validate plan exists and is active +6. Set `request.account`, `request.user` + +**Error Responses:** +- No account: 403 with JSON error +- Inactive plan: 402 with JSON error + +--- + +## Frontend Auth Store + +**File:** `store/authStore.ts` + +**State:** +```typescript +{ + user: User | null; + token: string | null; + refreshToken: string | null; + isAuthenticated: boolean; +} +``` + +**Actions:** +- `login(email, password)` - Authenticate and store tokens +- `register(data)` - Create account and store tokens +- `logout()` - Clear tokens and reset stores +- `refreshToken()` - Refresh access token +- `checkAuth()` - Verify current auth state + +**Critical Implementation:** +```typescript +// Tokens are written synchronously to localStorage +// This prevents race conditions where API calls happen before persist +localStorage.setItem('auth-storage', JSON.stringify(authState)); +``` + +--- + +## Session Security (Redis-Backed) + +**Problem Solved:** User swapping / random logout issues + +**Implementation:** +```python +# settings.py +SESSION_ENGINE = 'django.contrib.sessions.backends.cache' +SESSION_CACHE_ALIAS = 'default' # Redis + +# auth/backends.py +class NoCacheModelBackend(ModelBackend): + """Authentication backend without user caching""" + pass +``` + +**Session Integrity:** +- Stores `account_id` and `user_id` in session +- Validates on every request +- Prevents cross-request contamination + +--- + +## API Key Management + +**Model:** `APIKey` in `auth/models.py` + +| Field | Type | Purpose | +|-------|------|---------| +| key | CharField | Hashed API key | +| account | ForeignKey | Owner account | +| site | ForeignKey | Optional: specific site | +| name | CharField | Key name/description | +| is_active | Boolean | Enable/disable | +| created_at | DateTime | Creation time | +| last_used_at | DateTime | Last usage time | + +**Generation:** +- 32-character random key +- Stored hashed (SHA-256) +- Shown once on creation + +--- + +## Permission Checking + +**In ViewSets:** +```python +class MyViewSet(AccountModelViewSet): + permission_classes = [IsAuthenticated] + + def get_queryset(self): + # Automatically filtered by request.account + return super().get_queryset() +``` + +**Role Checks:** +```python +if request.user.is_admin_or_developer: + # Admin/developer access + pass +elif request.user.role == 'editor': + # Editor access + pass +``` + +--- + +## Logout Flow + +**Backend:** +1. Blacklist refresh token (if using token blacklist) +2. Clear session + +**Frontend (Critical):** +```typescript +logout: () => { + // NEVER use localStorage.clear() - breaks Zustand persist + const authKeys = ['auth-storage', 'site-storage', 'sector-storage', 'billing-storage']; + authKeys.forEach(key => localStorage.removeItem(key)); + + // Reset dependent stores + useSiteStore.setState({ activeSite: null }); + useSectorStore.setState({ activeSector: null, sectors: [] }); + + set({ user: null, token: null, isAuthenticated: false }); +} +``` + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| 403 after login | Tokens not persisted before API call | Write to localStorage synchronously | +| User swapping | DB-backed sessions with user caching | Redis sessions + NoCacheModelBackend | +| Token refresh loop | Refresh token expired | Redirect to login | +| API key not working | Missing site scope | Check API key has correct site assigned | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| Token blacklist | 🔜 Planned | Proper refresh token invalidation | +| 2FA | 🔜 Planned | Two-factor authentication | +| SSO | 🔜 Planned | Google/GitHub OAuth | diff --git a/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/IGNY8-APP.md b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/IGNY8-APP.md new file mode 100644 index 00000000..43f12ac3 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/IGNY8-APP.md @@ -0,0 +1,383 @@ +# IGNY8 - AI-Powered SEO Content Platform + +**Version:** 1.8.4 +**Last Updated:** January 20, 2026 +**Status:** Production Ready + +--- + +## What is IGNY8? + +IGNY8 is an enterprise-grade AI content platform that transforms keyword research into published, SEO-optimized articles at scale. The platform automates the entire content lifecycle—from discovering keywords to publishing polished articles with AI-generated images—reducing what typically takes days of manual work into hours. + +**The Problem:** Creating SEO content at scale requires keyword research, content planning, writing, image creation, optimization, and publishing—a process that's labor-intensive and inconsistent. + +**The Solution:** IGNY8 provides an end-to-end automated pipeline where AI handles clustering, ideation, writing, and image generation while you maintain editorial control. + +--- + +## Platform Architecture + +| Aspect | Details | +|--------|---------| +| **Type** | Full-stack SaaS Platform | +| **Architecture** | Multi-tenant with complete data isolation | +| **Target Users** | Content marketers, SEO agencies, digital publishers | +| **Deployment** | Docker-based, cloud-hosted | +| **Pricing Model** | Credits + Monthly subscription plans | + +--- + +## Core Workflow + +IGNY8 follows a structured 8-stage content pipeline: + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ SETUP WORKFLOW │ +│ ───── ──────── │ +│ Sites → Keywords → Clusters → Ideas → Tasks → Content → Images → Published │ +│ ↑ ↑ ↑ │ +│ Configure AI Groups AI Writes │ +│ WordPress Related Full Articles │ +│ Keywords + SEO Meta │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +### Manual Mode +Walk through each stage with full control—review and edit at every step. + +### Automation Mode +Configure once, let IGNY8 process all 7 stages automatically on a schedule (daily, weekly, or monthly). Content lands in your review queue ready for approval. + +--- + +## Feature Deep-Dive + +### 1. Keyword Management (Planner) + +**Import Options:** +- Upload CSV with thousands of keywords +- Browse 50+ industries of pre-curated seed keywords +- Filter by country, difficulty, search volume + +**AI Clustering:** +- GPT-4 analyzes keyword intent and relationships +- Groups related keywords into topical clusters +- Enables one comprehensive article per cluster (instead of keyword stuffing) + +**Metrics Tracked:** +- Search volume (monthly) +- Keyword difficulty (0-100) +- CPC (cost-per-click) +- Intent classification (informational, commercial, transactional) + +--- + +### 2. Content Ideation (Planner) + +**AI-Generated Ideas:** +- Each cluster becomes a content brief +- Suggested titles, angles, and outlines +- Word count recommendations based on competition +- Priority scoring by SEO potential + +**Bulk Operations:** +- Generate ideas for multiple clusters at once +- Queue ideas directly to Writer module +- Batch status updates + +--- + +### 3. Content Generation (Writer) + +**AI Writing Engine:** +- Powered by GPT-4/GPT-4 Turbo +- Produces structured articles (H2s, H3s, lists, paragraphs) +- SEO-optimized meta titles and descriptions +- Configurable length: 500 to 5,000+ words + +**Content Types:** +- Blog posts and articles +- How-to guides +- Product comparisons +- Reviews and roundups + +**Customization:** +- Custom prompt additions (append to all AI prompts) +- Default tone selection (professional, casual, authoritative, etc.) +- Default article length preferences + +**Workflow States:** +- Queue → Draft → Review → Published +- Each stage has dedicated management views + +--- + +### 4. Image Generation (Writer) + +**Dual AI Providers:** +| Provider | Quality Tier | Best For | +|----------|--------------|----------| +| DALL-E 2 | Standard | Fast, economical | +| DALL-E 3 | Premium | High quality, detailed | +| Runware | Best | Alternative variety | + +**Image Types:** +- Featured images (hero/thumbnail) +- In-article images (embedded in content) +- Desktop and mobile sizes (responsive) + +**Smart Features:** +- AI extracts image prompts from article content +- Negative prompts for style control +- Multiple format support (WebP, JPG, PNG) +- Configurable max images per article + +--- + +### 5. Automation Pipeline + +**7-Stage Automated Workflow:** +``` +Stage 1: Process new keywords +Stage 2: AI cluster keywords +Stage 3: Generate content ideas +Stage 4: Create writer tasks +Stage 5: Generate article content +Stage 6: Extract image prompts +Stage 7: Generate images → Review queue +``` + +**Configuration:** +- Schedule: Daily, weekly, or monthly runs +- Run controls: Start, pause, resume +- Credit estimation before running +- Real-time progress tracking +- Activity log and run history + +--- + +### 6. WordPress Integration + +**Publishing:** +- One-click publish from Review tab +- Direct WordPress REST API integration +- Supports multiple WordPress sites per account + +**Synchronization:** +- Two-way content sync (import/export) +- Category and tag mapping +- Featured image upload +- Post type configuration (posts, pages, custom) + +**Setup:** +- Site URL and REST API authentication +- Content type mapping in Site Settings +- Auto-publish toggle (skip review step) +- Auto-sync toggle (keep WordPress updated) + +--- + +### 7. Team & Account Management + +**User Roles:** +| Role | Permissions | +|------|-------------| +| Admin | Full access, billing, team management | +| Manager | Content + billing view, no team management | +| Editor | AI content, clusters, tasks | +| Viewer | Read-only dashboards | + +**Team Features:** +- Invite team members by email +- Remove members +- Role display (editing roles coming soon) + +**Account Settings:** +- Organization name and billing address +- Tax ID / VAT number +- Billing email + +--- + +### 8. Usage & Billing + +**Credit System:** +| Operation | Typical Credits | +|-----------|-----------------| +| Keyword clustering (batch) | 10 | +| Content idea generation | 2 | +| Article (per 100 words) | 5 | +| Image (standard) | 3 | +| Image (premium/best) | 5 | + +**Usage Tracking:** +- Real-time credit balance +- Monthly usage vs. limits +- Transaction history +- Hard limits (sites, users, keywords, clusters) +- Monthly limits (ideas, words, images) + +**Subscription Plans:** +| Plan | Sites | Users | Credits/Month | Best For | +|------|-------|-------|---------------|----------| +| Free | 1 | 1 | 100 | Trial/Evaluation | +| Starter | 3 | 3 | 1,000 | Individual creators | +| Growth | 10 | 10 | 5,000 | Small teams | +| Scale | Unlimited | Unlimited | 25,000 | Agencies | + +--- + +## Module Status + +| Module | Status | Location | +|--------|--------|----------| +| **Dashboard** | ✅ Active | `/` | +| **Add Keywords** | ✅ Active | `/setup/add-keywords` | +| **Content Settings** | ✅ Active | `/account/content-settings` | +| **Sites** | ✅ Active | `/sites` | +| **Thinker** | ✅ Active (Admin) | `/thinker/prompts` | +| **Planner** | ✅ Active | `/planner/keywords` | +| **Writer** | ✅ Active | `/writer/tasks` | +| **Automation** | ✅ Active | `/automation` | +| **Account Settings** | ✅ Active | `/account/settings` | +| **Plans & Billing** | ✅ Active | `/account/plans` | +| **Usage** | ✅ Active | `/account/usage` | +| **AI Models** | ✅ Active (Admin) | `/settings/integration` | +| **Help** | ✅ Active | `/help` | +| **SiteBuilder** | ❌ Deprecated | Removed - was for site structure generation | +| **Linker** | ⏸️ Phase 2 | Internal linking suggestions (disabled by default) | +| **Optimizer** | ⏸️ Phase 2 | Content optimization (disabled by default) | + +### Module Status Details + +| Module | Status | Notes | +|--------|--------|-------| +| **SiteBuilder** | ❌ Deprecated | Code exists but feature is removed. Marked for cleanup. | +| **Linker** | ⏸️ Phase 2 | Feature flag: `linker_enabled`. Available but disabled by default. | +| **Optimizer** | ⏸️ Phase 2 | Feature flag: `optimizer_enabled`. Available but disabled by default. | + +To enable Phase 2 modules, update via Django Admin: +- `GlobalModuleSettings` (pk=1) for platform-wide settings +- `ModuleEnableSettings` for per-account settings + +--- + +## Navigation Structure + +``` +Sidebar Menu +├── Dashboard +├── SETUP +│ ├── Add Keywords +│ ├── Content Settings +│ ├── Sites (if enabled) +│ └── Thinker (admin only, if enabled) +├── WORKFLOW +│ ├── Planner (Keywords → Clusters → Ideas) +│ ├── Writer (Queue → Drafts → Images → Review → Published) +│ ├── Automation +│ ├── Linker (if enabled) +│ └── Optimizer (if enabled) +├── ACCOUNT +│ ├── Account Settings (Account → Profile → Team) +│ ├── Plans & Billing (Plan → Upgrade → History) +│ ├── Usage (Limits → Credit History → API Activity) +│ └── AI Models (admin only) +└── HELP + └── Help & Docs +``` + +--- + +## Technical Stack + +| Layer | Technology | +|-------|------------| +| **Backend** | Django 5.x, Django REST Framework, Python 3.11+ | +| **Frontend** | React 19, TypeScript, Vite, TailwindCSS | +| **Database** | PostgreSQL 15+ | +| **Cache/Sessions** | Redis | +| **Task Queue** | Celery + Celery Beat | +| **AI Services** | OpenAI GPT-4, DALL-E 3, Runware | +| **Deployment** | Docker, Docker Compose | + +--- + +## Security + +- **Data Isolation:** Complete multi-tenant separation at database level +- **Authentication:** JWT tokens with Redis session management +- **Encryption:** Data encrypted at rest and in transit +- **Access Control:** Role-based permissions per account +- **Session Security:** Secure cookie handling, session integrity checks + +--- + +## Current Limitations & Known Issues + +**Payment Processing:** +- Stripe/PayPal pending production credentials +- Manual payment methods available + +**Pending Backend Implementation:** +- Content Generation settings (append prompt, tone, length) - UI exists, API pending +- Publishing settings (auto-publish, sync) - UI exists, API pending +- Profile settings save - UI exists, API pending +- Password change functionality +- API Activity tracking (currently placeholder data) + +**Disabled Modules:** +- Linker (internal linking) - Available but disabled +- Optimizer (content optimization) - Available but disabled + +--- + +## Getting Started + +### For New Users +1. Create account and verify email +2. Create your first site (industry + sectors) +3. Connect WordPress (optional) +4. Add keywords from seed database or import CSV +5. Run AI clustering on keywords +6. Generate content ideas from clusters +7. Queue ideas to Writer +8. Generate content and images +9. Review and publish + +### For Admins +1. Configure AI Models (OpenAI API key, Runware key) +2. Customize prompts in Thinker module +3. Set up global module settings +4. Configure automation schedules + +--- + +## Documentation + +| Document | Location | +|----------|----------| +| Technical Docs | `/docs/INDEX.md` | +| API Reference | `/docs/20-API/` | +| Pre-Launch Audit | `/PRE-LAUNCH-AUDIT.md` | +| Changelog | `/CHANGELOG.md` | + +--- + +## Version History + +| Version | Date | Highlights | +|---------|------|------------| +| **1.1.0** | Dec 25, 2025 | UX overhaul, page consolidation, pre-launch audit | +| 1.0.5 | Dec 12, 2025 | Purchase Credits tab | +| 1.0.4 | Dec 12, 2025 | Credit Activity tab | +| 1.0.3 | Dec 12, 2025 | Usage Limits improvements | +| 1.0.2 | Dec 12, 2025 | Design system enforcement | +| 1.0.1 | Dec 12, 2025 | Plan limits UI | +| 1.0.0 | Dec 12, 2025 | Initial production release | + +--- + +*For detailed technical implementation, see the `/docs` folder. For known issues and improvement roadmap, see `/PRE-LAUNCH-AUDIT.md`.* diff --git a/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/REPO-STRUCTURE.md b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/REPO-STRUCTURE.md new file mode 100644 index 00000000..c879b6bc --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/REPO-STRUCTURE.md @@ -0,0 +1,268 @@ +# Repository Structure (App Repo) + +**Last Verified:** January 20, 2026 +**Scope:** `/data/app/igny8` (app repo) +**Excluded from tree:** `.git/`, `node_modules/`, `dist/`, `staticfiles/`, `backups/`, `__pycache__/` + +--- + +## Root + +``` +/data/app/igny8 +├── backend/ +├── docs/ +├── frontend/ +├── KW_DB/ +├── plugins/ +├── scripts/ +├── .claude/ +├── .gitignore +├── .rules +├── CHANGELOG.md +├── CLEANUP_SUMMARY_20260113.md +├── content_generation.md +├── docker-compose.app.yml +├── git-credential-helper.sh +├── idea_genration.md +├── last-session.md +├── README.md +└── test_routes.sh +``` + +--- + +## Backend + +``` +backend/ +├── igny8_core/ +├── migrations/ +├── logs/ +├── scripts/ +├── Dockerfile +├── container_startup.sh +├── create_groups.py +├── manage.py +├── requirements.txt +└── seed_keywords_import_template.csv +``` + +### Django App Core + +``` +backend/igny8_core/ +├── admin/ +├── ai/ +├── api/ +├── auth/ +├── business/ +├── common/ +├── management/ +├── middleware/ +├── migrations/ +├── modules/ +├── plugins/ +├── static/ +├── tasks/ +├── templates/ +├── urls/ +├── utils/ +├── __init__.py +├── asgi.py +├── celery.py +├── settings.py +├── tasks.py +├── urls.py +└── wsgi.py +``` + +### Feature Modules + +``` +backend/igny8_core/modules/ +├── billing/ +├── integration/ +├── linker/ +├── optimizer/ +├── planner/ +├── publisher/ +├── system/ +└── writer/ +``` + +### Business Services + +``` +backend/igny8_core/business/ +├── automation/ +├── billing/ +├── content/ +├── integration/ +├── linking/ +├── notifications/ +├── optimization/ +├── planning/ +└── publishing/ +``` + +--- + +## Frontend + +``` +frontend/ +├── public/ +├── src/ +├── audit-results/ +├── eslint/ +├── Caddyfile +├── Caddyfile.marketing +├── Dockerfile +├── Dockerfile.dev +├── Dockerfile.marketing +├── Dockerfile.marketing.dev +├── LICENSE.md +├── README.md +├── container_startup.sh +├── eslint.config.js +├── index.html +├── marketing.html +├── package.json +├── package-lock.json +├── postcss.config.js +├── tsconfig.app.json +├── tsconfig.json +├── tsconfig.node.json +├── vite.config.ts +└── vitest.config.ts +``` + +### Frontend Source + +``` +frontend/src/ +├── api/ +├── components/ +├── config/ +├── constants/ +├── context/ +├── hooks/ +├── icons/ +├── layout/ +├── marketing/ +├── modules/ +├── pages/ +├── services/ +├── store/ +├── styles/ +├── templates/ +├── types/ +├── utils/ +├── App.tsx +├── main.tsx +├── svg.d.ts +└── vite-env.d.ts +``` + +--- + +## Documentation + +``` +docs/ +├── 00-SYSTEM/ +├── 10-MODULES/ +├── 20-API/ +├── 30-FRONTEND/ +├── 40-WORKFLOWS/ +├── 50-DEPLOYMENT/ +├── 60-PLUGINS/ +├── 90-REFERENCE/ +├── audits/ +├── plans/ +├── FILTER_GUIDELINES.md +└── INDEX.md +``` + +--- + +## Plugins + +``` +plugins/ +└── wordpress/ + ├── dist/ + ├── source/ + │ └── igny8-wp-bridge/ + │ ├── admin/ + │ ├── data/ + │ ├── docs/ + │ ├── includes/ + │ ├── languages/ + │ ├── sync/ + │ ├── templates/ + │ ├── tests/ + │ ├── igny8-bridge.php + │ └── uninstall.php + └── UI-REDESIGN-v1.2.0.md +``` + +--- + +## KW_DB (Seed Keyword CSV Library) + +Top-level categories and subcategories (CSV files omitted for brevity): + +``` +KW_DB/ +├── Advertising_&_Media/ +│ └── Printing_Services/ +├── Apparel_&_Fashion/ +│ ├── Jewelery/ +│ ├── Menswear/ +│ └── Womens_Wear/ +├── Automotive/ +│ ├── Car_Accessories/ +│ ├── Cars_General/ +│ └── Tyres_&_Wheels/ +├── Beauty_&_Personal_Care/ +│ ├── Haircare/ +│ ├── Makeup_&_Cosmetics/ +│ └── Skincare/ +├── Finance_&_Insurance/ +│ ├── Insurance/ +│ ├── Investment_&_Weallth_Management/ +│ └── Loans_&_Lending/ +├── Food_&_Beverage/ +│ ├── Food Delivery/ +│ └── Restaurants/ +├── HealthCare_Medical/ +│ ├── Health_Practitioners/ +│ ├── Massage_&_Therapy/ +│ ├── Physiotherapy_Rehabilitation/ +│ ├── Relaxation_Devices/ +│ └── Wellness_&_Fitness/ +├── Home_&_Garden/ +│ ├── Bedding_&_Mattress/ +│ ├── Furniture/ +│ ├── Home_Decor/ +│ └── Storage_&_Organization/ +├── management/ +├── Real_Estate_&_Construction/ +└── Technology_&_IT_Services/ + ├── AI/ + ├── cloud_services/ + ├── DIgital_Marketing_&_SEO/ + ├── SAAS/ + └── Web_Development_&_Design/ +``` + +--- + +## Scripts + +``` +scripts/ +└── package_app.sh +``` \ No newline at end of file diff --git a/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/TENANCY.md b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/TENANCY.md new file mode 100644 index 00000000..8e9e2908 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/TENANCY.md @@ -0,0 +1,302 @@ +# Multi-Tenancy Architecture + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Backend Path:** `backend/igny8_core/auth/models.py` + +--- + +## Data Hierarchy + +``` +Account (Tenant) +├── Users (team members) +├── Subscription (plan binding) +├── Sites +│ ├── Sectors +│ │ ├── Keywords +│ │ ├── Clusters +│ │ ├── ContentIdeas +│ │ ├── Tasks +│ │ ├── Content +│ │ └── Images +│ └── Integrations (WordPress) +└── Billing (credits, transactions) +``` + +--- + +## Core Models + +### Account + +| Field | Type | Purpose | +|-------|------|---------| +| name | CharField | Account/organization name | +| is_active | Boolean | Enable/disable account | +| credits | Decimal | Plan credits (reset on renewal) | +| bonus_credits | Decimal | Purchased credits (never expire) | +| account_timezone | CharField | IANA timezone (e.g., America/New_York) | +| stripe_customer_id | CharField | Stripe integration | +| paypal_customer_id | CharField | PayPal integration | +| created_at | DateTime | Registration date | + +> **Two-Pool Credit System (v1.8.3):** Plan credits consumed first, bonus credits only when plan = 0. Bonus credits never expire. + +### Plan + +| Field | Type | Purpose | +|-------|------|---------| +| name | CharField | Plan name (Free, Starter, Growth, Scale) | +| included_credits | Integer | Monthly credit allocation | +| max_sites | Integer | Site limit (hard limit) | +| max_users | Integer | User limit (hard limit) | +| max_keywords | Integer | Keyword limit (hard limit) | +| max_ahrefs_queries | Integer | Monthly Ahrefs queries (monthly limit) | +| is_active | Boolean | Available for purchase | +| is_internal | Boolean | Internal/test plan | + +> **Note (v1.5.0+):** Operation limits like `max_clusters`, `max_content_words`, `max_images_basic`, `max_images_premium` were removed. All AI operations are now credit-based. + +### Site + +| Field | Type | Purpose | +|-------|------|---------| +| account | ForeignKey | Owner account | +| name | CharField | Site name | +| domain | CharField | Primary domain | +| is_active | Boolean | Enable/disable | + +### Sector + +| Field | Type | Purpose | +|-------|------|---------| +| site | ForeignKey | Parent site | +| account | ForeignKey | Owner account | +| industry | ForeignKey | Industry template | +| name | CharField | Sector name | +| is_active | Boolean | Enable/disable | + +--- + +## Base Model Classes + +### AccountBaseModel + +**File:** `auth/models.py` + +All account-scoped models inherit from this: + +```python +class AccountBaseModel(models.Model): + account = models.ForeignKey(Account, on_delete=models.CASCADE) + + class Meta: + abstract = True +``` + +**Used by:** Billing records, Settings, API keys + +### SiteSectorBaseModel + +**File:** `auth/models.py` + +All content models inherit from this: + +```python +class SiteSectorBaseModel(AccountBaseModel): + site = models.ForeignKey(Site, on_delete=models.CASCADE) + sector = models.ForeignKey(Sector, on_delete=models.CASCADE) + + class Meta: + abstract = True +``` + +**Used by:** Keywords, Clusters, Ideas, Tasks, Content, Images + +--- + +## ViewSet Base Classes + +### AccountModelViewSet + +**File:** `api/base.py` + +Automatically filters queryset by account: + +```python +class AccountModelViewSet(ModelViewSet): + def get_queryset(self): + qs = super().get_queryset() + if not self.request.user.is_admin_or_developer: + qs = qs.filter(account=self.request.account) + return qs +``` + +### SiteSectorModelViewSet + +**File:** `api/base.py` + +Filters by account + site + sector: + +```python +class SiteSectorModelViewSet(AccountModelViewSet): + def get_queryset(self): + qs = super().get_queryset() + site_id = self.request.query_params.get('site_id') + sector_id = self.request.query_params.get('sector_id') + if site_id: + qs = qs.filter(site_id=site_id) + if sector_id: + qs = qs.filter(sector_id=sector_id) + return qs +``` + +--- + +## Where Tenancy Applies + +### Uses Site/Sector Filtering + +| Module | Filter | +|--------|--------| +| Planner (Keywords, Clusters, Ideas) | site + sector | +| Writer (Tasks, Content, Images) | site + sector | +| Linker | site + sector | +| Optimizer | site + sector | +| Setup/Add Keywords | site + sector | + +### Account-Level Only (No Site/Sector) + +| Module | Filter | +|--------|--------| +| Billing/Plans | account only | +| Account Settings | account only | +| Team Management | account only | +| User Profile | user only | +| System Settings | account only | + +--- + +## Frontend Implementation + +### Site Selection + +**Store:** `store/siteStore.ts` + +```typescript +const useSiteStore = create({ + activeSite: Site | null, + sites: Site[], + loadSites: () => Promise, + setActiveSite: (site: Site) => void, +}); +``` + +### Sector Selection + +**Store:** `store/sectorStore.ts` + +```typescript +const useSectorStore = create({ + activeSector: Sector | null, + sectors: Sector[], + loadSectorsForSite: (siteId: number) => Promise, + setActiveSector: (sector: Sector) => void, +}); +``` + +### Sector Loading Pattern + +Sectors are loaded by `PageHeader` component, not `AppLayout`: + +```typescript +// PageHeader.tsx +useEffect(() => { + if (hideSiteSector) return; // Skip for account pages + + if (activeSite?.id && activeSite?.is_active) { + loadSectorsForSite(activeSite.id); + } +}, [activeSite?.id, hideSiteSector]); +``` + +**Pages with `hideSiteSector={true}`:** +- `/account/*` (settings, team, billing) +- User profile pages + +--- + +## Global Resources (No Tenancy) + +These are system-wide, not tenant-specific: + +| Model | Purpose | +|-------|---------| +| Industry | Global industry taxonomy | +| IndustrySector | Sub-categories within industries | +| SeedKeyword | Global keyword database | +| GlobalIntegrationSettings | Platform API keys | +| GlobalAIPrompt | Default prompt templates | +| GlobalAuthorProfile | Author persona templates | + +--- + +## Tenant Data vs System Data + +### System Data (KEEP on reset) + +- Plans, CreditPackages +- Industries, IndustrySectors +- GlobalIntegrationSettings +- GlobalAIPrompt, GlobalAuthorProfile +- CreditCostConfig +- PaymentMethodConfig + +### Tenant Data (CLEAN on reset) + +- Accounts, Users, Sites, Sectors +- Keywords, Clusters, Ideas, Tasks, Content, Images +- Subscriptions, Invoices, Payments +- CreditTransactions, CreditUsageLogs +- SiteIntegrations, SyncEvents +- AutomationConfigs, AutomationRuns + +--- + +## Admin/Developer Bypass + +Admin and developer users can access all tenants: + +```python +# In auth/models.py +class User: + @property + def is_admin_or_developer(self): + return self.role in ['admin', 'developer'] +``` + +**Bypass Rules:** +- Admin: Full access to own account +- Developer: Full access to ALL accounts +- System accounts protected from deletion + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| Data leak between accounts | Missing account filter | Use AccountModelViewSet | +| Wrong site data | Site not validated for account | Validate site.account == request.account | +| Sector not loading | Site changed but sector not reset | Clear activeSector when activeSite changes | +| Admin can't see all data | Incorrect role check | Check is_admin_or_developer | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| Account switching | 🔜 Planned | Allow users to switch between accounts | +| Sub-accounts | 🔜 Planned | Hierarchical account structure | diff --git a/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/TIMEZONE.md b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/TIMEZONE.md new file mode 100644 index 00000000..939a51f5 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/00-SYSTEM/TIMEZONE.md @@ -0,0 +1,66 @@ +# Timezone Standard + +## Purpose +This document defines the single-source timezone standard for IGNY8 and how all future time-related features must use it. + +## Single Source of Truth +- **Account timezone** is the canonical timezone for all user-visible times and scheduling UI. +- The value is stored on the Account model as `account_timezone` (IANA name, e.g., `America/New_York`). +- Selection modes: + - **Country-derived**: timezone is derived from billing country. + - **Manual**: user picks an IANA timezone that maps to a UTC offset list. + +## Storage Rules +- **Persist timestamps in UTC** in the database. +- **Never store local times** without timezone context. +- Store user selection in `Account.account_timezone` and (when needed) `timezone_mode` and `timezone_offset` for UI display. + +## Display Rules (Frontend) +- All UI formatting must use the account timezone. +- Use shared helpers: + - `getAccountTimezone()` for the active timezone. + - `formatDate()`, `formatDateTime()`, `formatRelativeDate()` for consistent formatting. +- **Do not** call `toLocaleDateString()` or `toLocaleTimeString()` without passing the account timezone. + +## Scheduling Rules +- All scheduling inputs in UI are **account timezone**. +- Convert to UTC before sending to the backend. +- All API payloads for scheduling must send ISO-8601 with timezone offset. +- The backend stores scheduled datetimes in UTC. + +## Backend API Contract +- Endpoints that return timestamps should return UTC ISO strings. +- Endpoints that return “server time” should return **account-local time** for display, plus the account timezone identifier. +- If the account timezone is invalid or missing, fall back to `UTC`. + +## Country List Source +- Country list must be fetched from `/v1/auth/countries/`. +- No hardcoded country lists in UI or backend responses. + +## Implementation Checklist (New Features) +1. **Input**: confirm user inputs are in account timezone. +2. **Conversion**: convert to UTC before persistence or scheduling. +3. **Storage**: store in UTC only. +4. **Output**: format all timestamps with account timezone helpers. +5. **API**: ensure responses include timezone-aware context when needed. + +## Guardrails +- Never introduce a second timezone source per user/site. +- Do not mix server timezone with account timezone in UI. +- Avoid timezone math in the UI; prefer helpers and backend-provided values when possible. + +## Examples +- **Display date in UI**: + - Use `formatDateTime(timestamp)` to render in account timezone. +- **Schedule content**: + - User selects date/time in account timezone → convert to ISO → send to `/schedule/`. + +## Troubleshooting +- If times appear “off”: + - Check account timezone is set. + - Confirm UI uses helpers. + - Confirm backend converts to UTC before save. + +--- +Owner: Platform +Last updated: 2026-01-19 diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/AUTOMATION.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/AUTOMATION.md new file mode 100644 index 00000000..4a9c9cba --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/AUTOMATION.md @@ -0,0 +1,452 @@ +# Automation Module + +**Last Verified:** January 18, 2026 +**Version:** 1.8.1 +**Status:** ✅ Active +**Backend Path:** `backend/igny8_core/business/automation/` +**Frontend Path:** `frontend/src/pages/Automation/` + +--- + +## Quick Reference + +| What | File | Key Items | +|------|------|-----------| +| Models | `business/automation/models.py` | `AutomationConfig`, `AutomationRun`, `DefaultAutomationConfig` | +| Service | `business/automation/services/automation_service.py` | `AutomationService` | +| Logger | `business/automation/services/automation_logger.py` | `AutomationLogger` | +| Celery Tasks | `business/automation/tasks.py` | `run_automation_task`, `check_scheduled_automations`, `check_test_triggers` | +| Publishing Tasks | `igny8_core/tasks/publishing_scheduler.py` | Scheduled publishing | +| **Unified Settings** | `api/unified_settings.py` | **v1.8.0** Consolidated settings API | +| **Default Settings API** | `api/unified_settings.py` | **v1.8.1** `DefaultSettingsAPIView` for reset | +| Frontend Overview | `pages/Automation/AutomationOverview.tsx` | **v1.8.0** Run history dashboard | +| Frontend Run Detail | `pages/Automation/AutomationRunDetail.tsx` | **v1.8.0** Detailed run view | +| Frontend Manual Run | `pages/Automation/AutomationPage.tsx` | Manual run UI | +| **Site Settings** | `pages/Sites/AIAutomationSettings.tsx` | **v1.8.0** Unified settings UI | +| Progress Bar | `components/Automation/GlobalProgressBar.tsx` | Full pipeline progress | +| Processing Card | `components/Automation/CurrentProcessingCard.tsx` | Real-time progress | +| **Scheduling Doc** | `docs/40-WORKFLOWS/AUTOMATION-AND-PUBLISHING-SCHEDULING.md` | **v1.8.1** Complete scheduling guide | + +--- + +## Purpose + +The Automation module runs the complete 7-stage content pipeline automatically: + +``` +Keywords → Clusters → Ideas → Tasks → Content → Image Prompts → Images → Published +``` + +**Settings Location (v1.8.0+):** Site Settings → Automation tab + +--- + +## Scheduling (v1.8.1) + +| Task | Schedule | Purpose | +|------|----------|---------| +| `check_scheduled_automations` | Every hour at `:05` | Check if automations should run | +| `check_test_triggers` | Every minute | Check for admin test triggers | + +**How it works:** +- Users select hour (12-hour AM/PM format), stored as `HH:00` (24-hour) +- Celery compares `scheduled_hour == current_hour` +- 23-hour block prevents re-runs within same day + +**Test Mode (Admin):** +- `test_mode_enabled` + `test_trigger_at` fields on `AutomationConfig` +- Allows immediate triggering without waiting for schedule +- Bypasses 23-hour blocking + +--- + +## 7-Stage Pipeline + +| Stage | Name | AI Function | Credit Cost | Can Skip | +|-------|------|-------------|-------------|----------| +| 1 | Keywords → Clusters | `AutoClusterFunction` | Per batch | ✅ | +| 2 | Clusters → Ideas | `GenerateIdeasFunction` | Per idea | ✅ | +| 3 | Ideas → Tasks | None (local) | None | ✅ | +| 4 | Tasks → Content | `GenerateContentFunction` | Per 100 words | ✅ | +| 5 | Content → Image Prompts | `GenerateImagePromptsFunction` | Per prompt | ✅ | +| 6 | Image Prompts → Images | `process_image_generation_queue` | Per image | ✅ | +| 7 | Review → Published | Publishing Scheduler | None | ✅ | + +**Note:** Stage 7 uses the Publishing Scheduler with `PublishingSettings` for auto-approval and scheduling. + +--- + +## Data Models + +### AutomationConfig + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Target site | +| enabled | Boolean | Enable/disable automation | +| frequency | CharField | hourly/daily/weekly | +| scheduled_time | TimeField | Time to run | +| stage_1_batch_size | Integer | Keywords per batch | +| stage_2_batch_size | Integer | Clusters per batch | +| stage_3_batch_size | Integer | Ideas per batch | +| stage_4_batch_size | Integer | Tasks per batch | +| stage_5_batch_size | Integer | Content per batch | +| stage_6_batch_size | Integer | Images per batch | +| **stage_1_enabled** | Boolean | **v1.8.0** Enable stage 1 | +| **stage_2_enabled** | Boolean | **v1.8.0** Enable stage 2 | +| **stage_3_enabled** | Boolean | **v1.8.0** Enable stage 3 | +| **stage_4_enabled** | Boolean | **v1.8.0** Enable stage 4 | +| **stage_5_enabled** | Boolean | **v1.8.0** Enable stage 5 | +| **stage_6_enabled** | Boolean | **v1.8.0** Enable stage 6 | +| **stage_7_enabled** | Boolean | **v1.8.0** Enable stage 7 | +| **stage_X_use_testing** | Boolean | **v1.8.1** Use testing model (AI stages 1,2,4,5,6) | +| **stage_X_budget_pct** | Integer | **v1.8.1** Credit budget % (AI stages) | +| **max_keywords_per_run** | Integer | **v1.8.0** Per-run limit stage 1 | +| **max_clusters_per_run** | Integer | **v1.8.0** Per-run limit stage 2 | +| **max_ideas_per_run** | Integer | **v1.8.0** Per-run limit stage 3 | +| **max_tasks_per_run** | Integer | **v1.8.0** Per-run limit stage 4 | +| **max_content_per_run** | Integer | **v1.8.0** Per-run limit stage 5 | +| **max_images_per_run** | Integer | **v1.8.0** Per-run limit stage 6 | +| within_stage_delay | Integer | Seconds between batches | +| between_stage_delay | Integer | Seconds between stages | +| last_run_at | DateTime | Last execution | +| next_run_at | DateTime | Next scheduled run | +| **test_mode_enabled** | Boolean | **v1.8.1** Enable test mode for admin | +| **test_trigger_at** | DateTime | **v1.8.1** When to trigger test run | + +### DefaultAutomationConfig (v1.8.1) + +Singleton model for centralized default settings. See [AUTOMATION-AND-PUBLISHING-SCHEDULING.md](../40-WORKFLOWS/AUTOMATION-AND-PUBLISHING-SCHEDULING.md) for full schema. + +| Field | Type | Purpose | +|-------|------|---------| +| is_enabled | Boolean | Default: Enable scheduled automation | +| frequency | CharField | Default frequency (daily/weekly/monthly) | +| next_scheduled_hour | Integer | Next hour to assign (auto-increments) | +| stage_X_enabled | Boolean | Default: Enable each stage | +| stage_X_batch_size | Integer | Default: Batch size per stage | +| stage_X_use_testing | Boolean | Default: Use testing model | +| stage_X_budget_pct | Integer | Default: Credit budget % | +| max_X_per_run | Integer | Default: Per-run limits | +| auto_approval_enabled | Boolean | Default: Auto-approve content | +| auto_publish_enabled | Boolean | Default: Auto-publish content | +| publish_days | JSONField | Default: Days to publish | +| publish_time_slots | JSONField | Default: Time slots to publish | + +### AutomationRun + +| Field | Type | Purpose | +|-------|------|---------| +| config | FK | Parent config | +| trigger_type | CharField | manual/scheduled | +| status | CharField | running/paused/cancelled/completed/failed | +| current_stage | Integer | Current stage (1-7) | +| started_at | DateTime | Start time | +| paused_at | DateTime | Pause time (nullable) | +| resumed_at | DateTime | Resume time (nullable) | +| cancelled_at | DateTime | Cancel time (nullable) | +| completed_at | DateTime | Completion time (nullable) | +| total_credits_used | Decimal | Total credits consumed | +| **initial_snapshot** | JSON | **v1.3.0** Queue sizes at run start | +| stage_1_result | JSON | Stage 1 results | +| stage_2_result | JSON | Stage 2 results | +| stage_3_result | JSON | Stage 3 results | +| stage_4_result | JSON | Stage 4 results | +| stage_5_result | JSON | Stage 5 results | +| stage_6_result | JSON | Stage 6 results | +| stage_7_result | JSON | Stage 7 results | +| error_message | TextField | Error details (nullable) | + +--- + +## API Endpoints + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/automation/config/` | Get/create config | Get automation config | +| PUT | `/api/v1/automation/update_config/` | Update config | Update settings | +| POST | `/api/v1/automation/run_now/` | Start manual run | Start automation | +| GET | `/api/v1/automation/current_run/` | Get current run | Run status/progress | +| GET | `/api/v1/automation/pipeline_overview/` | Get pipeline | Stage status counts | +| GET | `/api/v1/automation/current_processing/` | Get processing | Live processing status | +| **GET** | `/api/v1/automation/run_progress/` | **v1.3.0** | Unified progress data | +| POST | `/api/v1/automation/pause/` | Pause run | Pause after current item | +| POST | `/api/v1/automation/resume/` | Resume run | Resume from saved stage | +| POST | `/api/v1/automation/cancel/` | Cancel run | Cancel after current item | +| GET | `/api/v1/automation/history/` | Get history | Last 20 runs | +| GET | `/api/v1/automation/logs/` | Get logs | Activity log for run | +| GET | `/api/v1/automation/estimate/` | Get estimate | Credit estimate | +| **GET** | `/api/v1/integration/settings/defaults/` | **v1.8.1** | Get default settings for reset | + +**Query Parameters:** All require `?site_id=`, run-specific require `?run_id=` + +### Default Settings Endpoint (v1.8.1) + +Returns centralized defaults from `DefaultAutomationConfig`: +```json +{ + "automation": { "enabled": false, "frequency": "daily", "time": "02:00" }, + "stages": [ + { "number": 1, "enabled": true, "batch_size": 50, "per_run_limit": 0, "use_testing": false, "budget_pct": 15 }, + ... + ], + "delays": { "within_stage": 3, "between_stage": 5 }, + "publishing": { + "auto_approval_enabled": false, + "auto_publish_enabled": false, + "daily_publish_limit": 3, + "publish_days": ["mon", "tue", "wed", "thu", "fri"], + "time_slots": ["09:00", "14:00", "18:00"] + } +} +``` + +### run_progress Endpoint (v1.3.0) + +Returns unified progress data for frontend: +```json +{ + "run": { "run_id": "...", "status": "running", "current_stage": 3 }, + "global_progress": { "total_items": 100, "completed_items": 45, "percentage": 45 }, + "stages": [ + { "number": 1, "status": "completed", "input_count": 50, "processed_count": 50 }, + ... + ], + "metrics": { "credits_used": 120, "duration_seconds": 3600 }, + "initial_snapshot": { "stage_1_initial": 50, ... } +} +``` + +--- + +## Execution Flow + +### Manual Run + +1. User clicks "Run Now" on frontend +2. Frontend calls `POST /automation/run_now/?site_id=X` +3. Backend acquires cache lock `automation_lock_{site_id}` +4. **v1.3.0:** Captures initial snapshot with `_capture_initial_snapshot()` +5. Estimates credits required (1.2x buffer) +6. Validates balance >= estimate +7. Creates `AutomationRun` record +8. Enqueues `run_automation_task` Celery task +8. Returns run ID immediately + +### Stage Execution + +For each stage (1-7): + +1. Check `_check_should_stop()` (paused/cancelled?) +2. Load items for processing +3. Process in batches (respecting batch_size) +4. For AI stages: Call AIEngine function +5. Wait `within_stage_delay` between batches +6. Save stage result JSON +7. Wait `between_stage_delay` before next stage + +### Stage Result Fields + +**Stage 1 (Clustering):** +```json +{ + "keywords_processed": 150, + "clusters_created": 12, + "batches_run": 3, + "credits_used": 45, + "time_elapsed": 120, + "skipped": false, + "partial": false +} +``` + +**Stage 2 (Ideas):** +```json +{ + "clusters_processed": 12, + "ideas_created": 36, + "batches_run": 2, + "credits_used": 72 +} +``` + +**Stage 3 (Tasks):** +```json +{ + "ideas_processed": 36, + "tasks_created": 36, + "batches_run": 4 +} +``` + +**Stage 4 (Content):** +```json +{ + "tasks_processed": 36, + "content_created": 36, + "total_words": 54000, + "batches_run": 6, + "credits_used": 540 +} +``` + +**Stage 5 (Image Prompts):** +```json +{ + "content_processed": 36, + "prompts_created": 180, + "batches_run": 4, + "credits_used": 36 +} +``` + +**Stage 6 (Images):** +```json +{ + "images_processed": 180, + "images_generated": 180, + "batches_run": 18 +} +``` + +**Stage 7 (Review):** +```json +{ + "ready_for_review": 36 +} +``` + +--- + +## Settings Configuration (v1.8.0) + +**Location:** Site Settings → Automation tab +**API:** `GET/PATCH /api/v1/integration/sites/{site_id}/unified-settings/` + +> ⚠️ **v1.8.0 Change:** Settings are now consolidated in Site Settings. The previous standalone `/automation/settings` page has been removed. + +### Settings UI Sections + +1. **Schedule & Frequency Card** + - Enable/disable toggle + - Frequency (hourly/daily/weekly) + - Days of week selection + - Time slot selection + - Next run display + +2. **Capacity Card** + - Total items per run (calculated) + - Stage-by-stage breakdown + +3. **AI Configuration Card** + - Testing model selection (is_testing=true) + - Live model selection (is_testing=false) + - Image model selection + +4. **Stage Configuration (Matrix)** + - Per-stage Enable/Disable toggle + - Per-stage batch size + - Per-stage max items per run (**new in v1.8.0**) + +5. **Help Cards** + - Pipeline flow visualization + - Stage descriptions + +--- + +## Scheduling + +**Celery Beat Task:** `check_scheduled_automations` +**Frequency:** Hourly + +**Logic:** +1. Find configs where `enabled=True` +2. Check if `next_run_at <= now` +3. Check if no active run exists +4. Start `run_automation_task` for eligible configs +5. Update `next_run_at` based on frequency + +--- + +## Lock Mechanism + +**Purpose:** Prevent concurrent runs for same site + +**Key:** `automation_lock_{site_id}` +**Storage:** Redis cache +**Acquired:** On run start +**Released:** On completion/failure/cancel + +--- + +## Credit Validation + +Before starting: +1. Calculate estimated credits for all stages +2. Apply 1.2x safety buffer +3. Compare with account balance +4. Reject if balance < estimate + +During execution: +- Each AI stage checks credits before processing +- Deductions happen after successful AI calls +- `total_credits_used` accumulates across stages + +--- + +## Frontend Integration + +### AutomationOverview (v1.8.0) + +**Path:** `/automation/overview` +**Purpose:** Run history dashboard with: +- All automation runs with status +- Filter by status, date range +- Click to view detailed run information + +### AutomationRunDetail (v1.8.0) + +**Path:** `/automation/runs/:runId` +**Purpose:** Detailed view of individual run with: +- Stage-by-stage progress +- Items processed per stage +- Errors and logs + +### AutomationPage + +**Path:** `/automation` +**Purpose:** Manual run control with: +- **Pipeline Cards:** Stage-by-stage status with pending counts +- **Processing Card:** Live processing status during run +- **Control Buttons:** Run Now, Pause, Resume, Cancel +- **Activity Log:** Real-time log streaming + +### Polling + +- Every ~5s while run is running/paused +- Fetches: `current_run`, `pipeline_overview`, `current_processing` +- Lighter polling when idle + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| "Already running" error | Lock exists from previous run | Wait or check if stuck | +| Insufficient credits | Balance < 1.2x estimate | Add credits | +| Stage skipped | No items to process | Check previous stages | +| Run stuck | Worker crashed | Clear lock, restart | +| Images not generating | Stage 5 didn't create prompts | Check stage 5 result | + +--- + +## Changelog + +| Version | Changes | +|---------|---------| +| v1.8.0 | Unified settings in Site Settings, per-run limits, skip stage functionality | +| v1.7.0 | AutomationOverview dashboard, AutomationRunDetail page | +| v1.3.2 | Stage 7 publishing scheduler integration | +| v1.3.0 | Progress tracking with initial snapshots | diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/BILLING-PAYMENTS-COMPLETE.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/BILLING-PAYMENTS-COMPLETE.md new file mode 100644 index 00000000..552a3393 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/BILLING-PAYMENTS-COMPLETE.md @@ -0,0 +1,756 @@ +# IGNY8 Billing & Payments - Complete Reference + +> **Last Updated:** January 20, 2026 +> **Version:** 2.0 (Two-Pool Credit System) + +--- + +## Table of Contents + +1. [System Overview](#1-system-overview) +2. [Credit System](#2-credit-system) +3. [Payment Methods](#3-payment-methods) +4. [Subscription Lifecycle](#4-subscription-lifecycle) +5. [Credit Packages](#5-credit-packages) +6. [Invoice System](#6-invoice-system) +7. [Renewal Workflow](#7-renewal-workflow) +8. [Admin Operations](#8-admin-operations) +9. [API Reference](#9-api-reference) +10. [Database Schema](#10-database-schema) + +--- + +## 1. System Overview + +### Architecture + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ IGNY8 BILLING SYSTEM │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ STRIPE │ │ PAYPAL │ │ BANK TRANSFER│ │ +│ │ (Card/Intl) │ │ (Intl) │ │ (PK Only) │ │ +│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ PAYMENT GATEWAY LAYER │ │ +│ │ • Webhook Processing • Payment Verification • Logging │ │ +│ └─────────────────────────────┬───────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ INVOICE SERVICE │ │ +│ │ • Create Invoice • Update Status • PDF Generation │ │ +│ └─────────────────────────────┬───────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ CREDIT SERVICE │ │ +│ │ • Plan Credits • Bonus Credits • Deduction • Reset │ │ +│ └─────────────────────────────┬───────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────────────────────────────────────────────────────────┐ │ +│ │ ACCOUNT │ │ +│ │ credits (plan) │ bonus_credits (purchased) │ status │ │ +│ └─────────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +### Key Files + +| Component | File Path | +|-----------|-----------| +| Credit Service | `business/billing/services/credit_service.py` | +| Invoice Service | `business/billing/services/invoice_service.py` | +| Payment Service | `business/billing/services/payment_service.py` | +| Email Service | `business/billing/services/email_service.py` | +| Stripe Webhooks | `business/billing/views/stripe_views.py` | +| PayPal Webhooks | `business/billing/views/paypal_views.py` | +| Subscription Renewal | `business/billing/tasks/subscription_renewal.py` | +| Invoice Lifecycle | `business/billing/tasks/invoice_lifecycle.py` | +| Billing Admin | `modules/billing/admin.py` | +| Billing Models | `business/billing/models.py` | + +--- + +## 2. Credit System + +### Two-Pool Credit Architecture + +``` +┌─────────────────────────────────────────────────────────────┐ +│ ACCOUNT CREDITS │ +├────────────────────────────┬────────────────────────────────┤ +│ PLAN CREDITS │ BONUS CREDITS │ +│ (account.credits) │ (account.bonus_credits) │ +├────────────────────────────┼────────────────────────────────┤ +│ • From subscription plan │ • From credit packages │ +│ • Resets on renewal │ • NEVER expire │ +│ • Used FIRST │ • Used SECOND (after plan=0) │ +│ • Max = plan.included_ │ • No maximum limit │ +│ credits │ │ +└────────────────────────────┴────────────────────────────────┘ +``` + +### Credit Deduction Flow + +``` + ┌──────────────────┐ + │ CREDIT REQUEST │ + │ (e.g., 50) │ + └────────┬─────────┘ + │ + ▼ + ┌──────────────────┐ + │ Check Total │ + │ credits + bonus │ + │ >= requested? │ + └────────┬─────────┘ + │ + ┌──────────────┴──────────────┐ + │ NO │ YES + ▼ ▼ + ┌────────────────┐ ┌────────────────────┐ + │ INSUFFICIENT │ │ Plan Credits >= 50?│ + │ Return False │ └─────────┬──────────┘ + └────────────────┘ │ + ┌──────────┴──────────┐ + │ YES │ NO + ▼ ▼ + ┌───────────────┐ ┌────────────────────┐ + │ Deduct from │ │ Deduct plan credits│ + │ plan credits │ │ to 0, remainder │ + │ only │ │ from bonus_credits │ + └───────────────┘ └────────────────────┘ +``` + +> **Note:** The two-pool logic is internal to `CreditService.deduct_credits()`. All AI functions and other credit consumers are unaffected - they call the same credit check/deduct methods as before. + +### Credit Operations + +| Operation | Method | Affects | Description | +|-----------|--------|---------|-------------| +| Add Plan Credits | `add_credits()` | `credits` | Initial subscription, manual adjustment | +| Add Bonus Credits | `add_bonus_credits()` | `bonus_credits` | Credit package purchases | +| Deduct Credits | `deduct_credits()` | Both pools | AI operations, uses plan first | +| Reset on Renewal | `reset_credits_for_renewal()` | `credits` only | Sets plan credits to new amount | +| Check Balance | `check_credits()` | Read-only | Returns total available | + +### Credit Transaction Types + +| Type | Description | +|------|-------------| +| `subscription` | Plan credits from subscription | +| `purchase` | Bonus credits from credit package | +| `usage` | Credit consumption for AI operations | +| `refund` | Credits returned due to failed operation | +| `manual` | Admin adjustment | +| `renewal` | Reset during subscription renewal | +| `bonus` | Promotional bonus credits | + +--- + +## 3. Payment Methods + +### Payment Method by Country + +``` +┌─────────────────────────────────────────────────────────────┐ +│ PAYMENT METHOD MATRIX │ +├─────────────────┬───────────────────────────────────────────┤ +│ COUNTRY │ AVAILABLE METHODS │ +├─────────────────┼───────────────────────────────────────────┤ +│ Pakistan (PK) │ ✅ Bank Transfer ✅ Stripe (Card) │ +│ │ ❌ PayPal (not available) │ +├─────────────────┼───────────────────────────────────────────┤ +│ Other (Intl) │ ✅ Stripe (Card) ✅ PayPal │ +│ │ ❌ Bank Transfer (not available) │ +└─────────────────┴───────────────────────────────────────────┘ +``` + +### Payment Flow by Method + +#### Stripe (Card) Flow + +``` +┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐ +│ User │────▶│ Frontend │────▶│ Create │────▶│ Stripe │ +│ Clicks │ │ Checkout │ │ Checkout │ │ Hosted │ +│ Pay │ │ │ │ Session │ │ Page │ +└─────────┘ └──────────┘ └─────────────┘ └────┬─────┘ + │ + ▼ +┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐ +│ Account │◀────│ Credit │◀────│ Invoice │◀────│ Webhook │ +│ Active │ │ Added │ │ Paid │ │ Received │ +└─────────┘ └──────────┘ └─────────────┘ └──────────┘ +``` + +#### PayPal Flow + +``` +┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐ +│ User │────▶│ Frontend │────▶│ Create │────▶│ PayPal │ +│ Clicks │ │ Checkout │ │ Order/Sub │ │ Hosted │ +│ Pay │ │ │ │ │ │ Page │ +└─────────┘ └──────────┘ └─────────────┘ └────┬─────┘ + │ + ▼ +┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐ +│ Account │◀────│ Credit │◀────│ Invoice │◀────│ Webhook │ +│ Active │ │ Added │ │ Paid │ │ CAPTURE │ +└─────────┘ └──────────┘ └─────────────┘ └──────────┘ +``` + +#### Bank Transfer Flow (PK Only) + +``` +┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐ +│ User │────▶│ View │────▶│ Manual │────▶│ Upload │ +│ Selects │ │ Bank │ │ Transfer │ │ Proof │ +│ Bank │ │ Details │ │ to Bank │ │ │ +└─────────┘ └──────────┘ └─────────────┘ └────┬─────┘ + │ + ▼ +┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌──────────┐ +│ Account │◀────│ Credit │◀────│ Admin │◀────│ Payment │ +│ Active │ │ Added │ │ Approves │ │ Created │ +└─────────┘ └──────────┘ └─────────────┘ └──────────┘ +``` + +--- + +## 4. Subscription Lifecycle + +### Subscription States + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ SUBSCRIPTION STATE MACHINE │ +└─────────────────────────────────────────────────────────────────────────┘ + + ┌─────────┐ + │ NEW │ + │ SIGNUP │ + └────┬────┘ + │ Create subscription + invoice + ▼ + ┌─────────────┐ Payment Failed ┌─────────────┐ + │ PENDING │─────────────────────────▶│ FAILED │ + │ (awaiting │ │ │ + │ payment) │ └─────────────┘ + └──────┬──────┘ + │ Payment Success + ▼ + ┌─────────────┐ + │ ACTIVE │◀─────────────────────────────────────┐ + │ │ Renewal Payment Success │ + └──────┬──────┘ │ + │ Renewal Date │ + ▼ │ + ┌─────────────┐ Payment Within ┌───────────┴─┐ + │ PENDING │ Grace Period │ │ + │ RENEWAL │────────────────────────▶│ ACTIVE │ + │ │ │ (renewed) │ + └──────┬──────┘ └─────────────┘ + │ Grace Period Expired (7 days) + ▼ + ┌─────────────┐ + │ EXPIRED │ Manual Reactivation + │ │────────────────────────▶ Back to PENDING + └─────────────┘ + + ┌─────────────┐ + │ CANCELLED │ User-initiated cancellation + │ │ (end of current period) + └─────────────┘ +``` + +### Subscription Status Reference + +| Status | Credits Access | Can Use Features | Next Action | +|--------|----------------|------------------|-------------| +| `pending` | ❌ No | ❌ No | Complete payment | +| `active` | ✅ Yes | ✅ Yes | None (auto-renews) | +| `pending_renewal` | ✅ Yes (24h) | ✅ Yes | Pay invoice | +| `expired` | ❌ No | ❌ Limited | Resubscribe | +| `cancelled` | ✅ Until end | ✅ Until end | None | +| `failed` | ❌ No | ❌ No | Retry payment | + +--- + +## 5. Credit Packages + +### Available Packages + +| Package | Credits | USD Price | PKR Price | Per Credit | +|---------|---------|-----------|-----------|------------| +| Starter | 500 | $50.00 | ≈ PKR 14,000 | $0.10 | +| Growth | 2,000 | $200.00 | ≈ PKR 56,000 | $0.10 | +| Scale | 5,000 | $300.00 | ≈ PKR 83,000 | $0.06 | +| Enterprise | 20,000 | $1,200.00 | ≈ PKR 334,000 | $0.06 | + +### Credit Package Purchase Flow + +``` +┌───────────────────────────────────────────────────────────────────────────┐ +│ CREDIT PACKAGE PURCHASE FLOW │ +└───────────────────────────────────────────────────────────────────────────┘ + +User selects package + │ + ▼ +┌───────────────────┐ +│ Create Invoice │ +│ type='credit_ │ +│ package' │ +└─────────┬─────────┘ + │ + ▼ +┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ +│ Stripe/PayPal? │────▶│ Auto-process via │────▶│ Webhook confirms │ +│ │ │ payment gateway │ │ payment success │ +└─────────┬─────────┘ └───────────────────┘ └─────────┬─────────┘ + │ │ + │ Bank Transfer? │ + ▼ │ +┌───────────────────┐ ┌───────────────────┐ │ +│ Payment created │────▶│ Admin reviews & │ │ +│ status='pending_ │ │ approves payment │ │ +│ approval' │ └─────────┬─────────┘ │ +└───────────────────┘ │ │ + ▼ ▼ + ┌───────────────────────────────────────┐ + │ PAYMENT APPROVED │ + └─────────────────┬─────────────────────┘ + │ + ▼ + ┌───────────────────────────────────────┐ + │ CreditService.add_bonus_credits() │ + │ • Adds to account.bonus_credits │ + │ • Creates CreditTransaction │ + │ • NEVER expires │ + └───────────────────────────────────────┘ +``` + +### Credit Package Invoice Lifecycle + +``` +Invoice Created ──▶ 48 hours ──▶ Reminder Sent ──▶ 48 hours ──▶ Invoice Voided + │ │ │ + │ │ │ + ▼ ▼ ▼ + status='pending' status='pending' status='void' + (reminder sent) (auto-cancelled) +``` + +--- + +## 6. Invoice System + +### Invoice Types + +| Type | Description | Auto-Pay | Manual Pay | +|------|-------------|----------|------------| +| `subscription` | Monthly plan payment | Stripe/PayPal | Bank Transfer | +| `credit_package` | One-time credit purchase | Stripe/PayPal | Bank Transfer | +| `addon` | Additional features | Stripe/PayPal | Bank Transfer | +| `custom` | Manual/admin-created | ❌ | ✅ | + +### Invoice Status Flow + +``` +┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ +│ DRAFT │────▶│ SENT │────▶│ PENDING │────▶│ PAID │ +└─────────┘ └─────────┘ └────┬────┘ └─────────┘ + │ + ┌────────┴────────┐ + │ │ + ▼ ▼ + ┌──────────┐ ┌──────────┐ + │ OVERDUE │ │ FAILED │ + └────┬─────┘ └──────────┘ + │ + ▼ + ┌──────────┐ ┌──────────┐ + │ VOID │ │CANCELLED │ + └──────────┘ └──────────┘ +``` + +### Invoice Status Reference + +| Status | Description | User Action | +|--------|-------------|-------------| +| `draft` | Being created | - | +| `sent` | Delivered to user | Pay Now | +| `pending` | Awaiting payment | Pay Now | +| `overdue` | Past due date | Pay Now (urgent) | +| `paid` | Payment received | Download PDF | +| `failed` | Payment failed | Retry/Pay Now | +| `void` | Cancelled by system | - | +| `cancelled` | Cancelled by admin | - | + +--- + +## 7. Renewal Workflow + +### Renewal Timeline by Payment Method + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ RENEWAL TIMELINE - STRIPE/PAYPAL (AUTO-PAY) │ +│ Industry Standard: No Advance Notice │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ Day 0 (Renewal) Day +1 Day +7 │ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌──────────┐ ┌────────────┐ ┌──────────┐ │ +│ │Auto-Pay │ │ If Failed: │ │ Expired │ │ +│ │ Attempt │ │ Retry + │ │ (after │ │ +│ └────┬─────┘ │ Email Sent │ │ retries) │ │ +│ │ └────────────┘ └──────────┘ │ +│ ┌────┴────┐ │ +│ │ SUCCESS │──▶ Receipt email + Credits reset to plan amount │ +│ └────┬────┘ │ +│ │ │ +│ ┌────┴────┐ │ +│ │ FAILURE │──▶ Payment failed email, Stripe retries 4x over 7 days │ +│ └─────────┘ │ +│ │ +│ EMAIL SCHEDULE (Industry Standard - Netflix, Spotify, Adobe): │ +│ • Payment Success: Receipt immediately │ +│ • Payment Failed: Notification after each retry attempt │ +│ • Final Warning: 1 day before account suspension │ +│ • Account Suspended: When grace period ends │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ + +┌─────────────────────────────────────────────────────────────────────────────┐ +│ RENEWAL TIMELINE - BANK TRANSFER │ +│ Simplified 3-Email Flow │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ Day -3 Day 0 Day +1 Day +7 │ +│ │ │ │ │ │ +│ ▼ ▼ ▼ ▼ │ +│ ┌────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ +│ │Invoice │ │Reminder │ │ Urgent │ │ Expired │ │ +│ │Created │ │ Email │ │Reminder │ │ │ │ +│ │+Email │ │(if not │ │+Credits │ │ │ │ +│ │ │ │ paid) │ │ Reset │ │ │ │ +│ └────────┘ └─────────┘ └─────────┘ └─────────┘ │ +│ │ +│ Timeline: │ +│ • Day -3: Invoice created + Email sent with payment instructions │ +│ • Day 0: Reminder email (renewal day, if still unpaid) │ +│ • Day +1: Urgent reminder + credits reset to 0 (if unpaid) │ +│ • Day +7: Subscription expired │ +│ │ +│ EMAILS: │ +│ 1. Invoice Email (Day -3): Invoice attached, bank details, Pay Now link │ +│ 2. Renewal Reminder (Day 0): "Your subscription renews today" │ +│ 3. Urgent Reminder (Day +1): "Payment overdue - action required" │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +### Renewal Credit Behavior + +``` +┌───────────────────────────────────────────────────────────────────┐ +│ CREDIT RESET ON RENEWAL │ +├───────────────────────────────────────────────────────────────────┤ +│ │ +│ SCENARIO 1: Payment Before Renewal │ +│ ───────────────────────────────────── │ +│ • Credits NOT reset early │ +│ • On payment confirmation: │ +│ - plan credits → reset to plan.included_credits │ +│ - bonus_credits → UNCHANGED (never affected) │ +│ │ +│ SCENARIO 2: Payment After Renewal (within 24h) │ +│ ────────────────────────────────────────────── │ +│ • Credits stay unchanged for 24 hours │ +│ • On payment confirmation: │ +│ - plan credits → reset to plan.included_credits │ +│ - bonus_credits → UNCHANGED │ +│ │ +│ SCENARIO 3: No Payment After 24 Hours │ +│ ───────────────────────────────────── │ +│ • plan credits → reset to 0 (task: send_day_after_reminders) │ +│ • bonus_credits → UNCHANGED (user can still use these) │ +│ • Warning email sent │ +│ │ +│ SCENARIO 4: Payment After Credit Reset │ +│ ────────────────────────────────────── │ +│ • On payment confirmation: │ +│ - plan credits → reset to plan.included_credits (restored) │ +│ - bonus_credits → UNCHANGED │ +│ │ +└───────────────────────────────────────────────────────────────────┘ +``` + +### Celery Tasks Schedule + +| Task | Schedule | Purpose | +|------|----------|---------| +| `create_bank_transfer_invoices` | Daily 09:00 | Create invoices 3 days before renewal (bank transfer only) | +| `process_subscription_renewals` | Daily 00:05 | Process auto-pay renewals (Stripe/PayPal) | +| `send_renewal_day_reminders` | Daily 10:00 | Send Day 0 reminder for bank transfer (if unpaid) | +| `send_day_after_reminders` | Daily 09:15 | Send Day +1 urgent reminders + reset credits | +| `check_expired_renewals` | Daily 00:15 | Mark subscriptions expired after 7-day grace period | +| `send_credit_invoice_expiry_reminders` | Daily 09:30 | Remind about expiring credit package invoices | +| `void_expired_credit_invoices` | Daily 00:45 | Auto-void credit invoices after 48h | + +### Email Schedule Summary + +**Stripe/PayPal (Auto-Pay) - Industry Standard:** +| Event | Email | +|-------|-------| +| Payment Success | ✅ Receipt/Confirmation | +| Payment Failed | ⚠️ Retry notification (per attempt) | +| Final Warning | 🚨 1 day before suspension | +| Account Suspended | ❌ Subscription expired | + +**Bank Transfer (Manual Pay):** +| Day | Email | +|-----|-------| +| Day -3 | 📧 Invoice created + payment instructions | +| Day 0 | ⏰ Renewal day reminder (if unpaid) | +| Day +1 | 🚨 Urgent reminder + credits reset warning | + +--- + +## 8. Admin Operations + +### Webhook Events (Payment Logs) + +**Location:** Admin → Billing → Webhook Events + +| Column | Description | +|--------|-------------| +| Event ID | Unique ID from Stripe/PayPal | +| Provider | STRIPE or PAYPAL badge | +| Event Type | e.g., `checkout.session.completed`, `PAYMENT.CAPTURE.COMPLETED` | +| Status | Processed ✓, Failed ✗, Pending ⏳ | +| Process Time | Actual processing duration | +| Created | When webhook received | + +**Actions:** +- Mark as processed +- Retry processing +- View full payload (JSON) + +### Payment Approval (Bank Transfer) + +**Location:** Admin → Billing → Payments + +**Approval Flow:** +1. Filter by `status = pending_approval` +2. Review `manual_reference` and `manual_notes` +3. Check proof of payment upload +4. Change status to `succeeded` +5. System automatically: + - Updates invoice to `paid` + - Activates account (if subscription) + - Adds credits (plan or bonus based on invoice type) + +### Manual Credit Adjustment + +**Location:** Admin → Billing → Credit Transactions + +**To add credits manually:** +1. Go to Account admin +2. Edit the account +3. Modify `credits` (plan) or `bonus_credits` (purchased) +4. Save with note in admin_notes + +**OR use shell:** +```python +from igny8_core.business.billing.services.credit_service import CreditService + +# Add plan credits +CreditService.add_credits( + account=account, + amount=500, + transaction_type='manual', + description='Manual adjustment - support ticket #123' +) + +# Add bonus credits +CreditService.add_bonus_credits( + account=account, + amount=500, + description='Promotional bonus - January 2026' +) +``` + +--- + +## 9. API Reference + +### Endpoints + +| Endpoint | Method | Description | +|----------|--------|-------------| +| `/api/v1/billing/credits/` | GET | Get credit balance | +| `/api/v1/billing/credits/usage/` | GET | Get usage statistics | +| `/api/v1/billing/invoices/` | GET | List invoices | +| `/api/v1/billing/invoices/{id}/` | GET | Invoice detail | +| `/api/v1/billing/invoices/{id}/pdf/` | GET | Download invoice PDF | +| `/api/v1/billing/payments/` | GET | List payments | +| `/api/v1/billing/plans/` | GET | List available plans | +| `/api/v1/billing/subscriptions/` | GET | List subscriptions | +| `/api/v1/billing/credit-packages/` | GET | List credit packages | +| `/api/v1/billing/purchase/credits/` | POST | Purchase credit package | +| `/api/v1/billing/subscribe/` | POST | Subscribe to plan | +| `/api/v1/webhooks/stripe/` | POST | Stripe webhook endpoint | +| `/api/v1/webhooks/paypal/` | POST | PayPal webhook endpoint | + +### Credit Balance Response + +```json +{ + "credits": 3500, + "bonus_credits": 2000, + "total_credits": 5500, + "credits_used_this_month": 1500, + "plan_credits_per_month": 5000, + "subscription_plan": "Scale", + "period_end": "2026-02-12T00:00:00Z" +} +``` + +--- + +## 10. Database Schema + +### Core Tables + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ accounts │ +├─────────────────────────────────────────────────────────────────────────┤ +│ id │ PK │ +│ name │ Account name │ +│ status │ pending, active, expired, etc. │ +│ credits │ Plan credits (resets on renewal) │ +│ bonus_credits │ Purchased credits (never expire) │ +│ plan_id │ FK → plans │ +│ billing_email │ Email for invoices │ +│ billing_country │ Country code (PK, US, etc.) │ +└─────────────────────────────────────────────────────────────────────────┘ + +┌─────────────────────────────────────────────────────────────────────────┐ +│ subscriptions │ +├─────────────────────────────────────────────────────────────────────────┤ +│ id │ PK │ +│ account_id │ FK → accounts │ +│ plan_id │ FK → plans │ +│ status │ pending, active, pending_renewal, expired, etc. │ +│ current_period_start │ Start of current billing period │ +│ current_period_end │ End of current billing period (renewal date) │ +│ metadata │ JSON (stripe_subscription_id, paypal_sub_id) │ +└─────────────────────────────────────────────────────────────────────────┘ + +┌─────────────────────────────────────────────────────────────────────────┐ +│ invoices │ +├─────────────────────────────────────────────────────────────────────────┤ +│ id │ PK │ +│ invoice_number │ Unique invoice number (INV-2026-00001) │ +│ account_id │ FK → accounts │ +│ subscription_id │ FK → subscriptions (nullable) │ +│ invoice_type │ subscription, credit_package, addon, custom │ +│ status │ draft, sent, pending, paid, overdue, void, etc. │ +│ total_amount │ Total amount │ +│ currency │ USD, PKR │ +│ due_date │ Payment due date │ +│ paid_at │ When payment received │ +│ metadata │ JSON (credit_package_id, etc.) │ +└─────────────────────────────────────────────────────────────────────────┘ + +┌─────────────────────────────────────────────────────────────────────────┐ +│ payments │ +├─────────────────────────────────────────────────────────────────────────┤ +│ id │ PK │ +│ invoice_id │ FK → invoices │ +│ account_id │ FK → accounts │ +│ amount │ Payment amount │ +│ currency │ USD, PKR │ +│ payment_method │ stripe, paypal, bank_transfer │ +│ status │ pending_approval, processing, succeeded, failed│ +│ stripe_payment_intent_id│ Stripe reference │ +│ paypal_order_id │ PayPal reference │ +│ manual_reference │ Bank transfer reference │ +│ approved_by_id │ FK → users (admin who approved) │ +│ approved_at │ When approved │ +└─────────────────────────────────────────────────────────────────────────┘ + +┌─────────────────────────────────────────────────────────────────────────┐ +│ credit_transactions │ +├─────────────────────────────────────────────────────────────────────────┤ +│ id │ PK │ +│ account_id │ FK → accounts │ +│ transaction_type │ subscription, purchase, usage, refund, manual, etc. │ +│ amount │ Credits added (+) or deducted (-) │ +│ balance_after │ Balance after this transaction │ +│ description │ Human-readable description │ +│ metadata │ JSON (invoice_id, payment_id, etc.) │ +│ created_at │ Timestamp │ +└─────────────────────────────────────────────────────────────────────────┘ + +┌─────────────────────────────────────────────────────────────────────────┐ +│ webhook_events │ +├─────────────────────────────────────────────────────────────────────────┤ +│ id │ PK │ +│ event_id │ Unique event ID from provider │ +│ provider │ stripe, paypal │ +│ event_type │ checkout.session.completed, PAYMENT.CAPTURE.COMPLETED │ +│ payload │ JSON - full webhook payload │ +│ processed │ Boolean - successfully processed? │ +│ processed_at │ When processed │ +│ error_message│ Error if processing failed │ +│ retry_count │ Number of retry attempts │ +│ created_at │ When received │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## Quick Reference Card + +### Credit Consumption Priority +1. **Plan credits** used first +2. **Bonus credits** used only when plan credits = 0 + +### What Happens on Renewal + +| Event | Plan Credits | Bonus Credits | +|-------|--------------|---------------| +| Payment success | Reset to plan amount | No change | +| No payment (24h) | Reset to 0 | No change | +| Late payment | Reset to plan amount | No change | + +### Payment Method Availability + +| Country | Stripe | PayPal | Bank Transfer | +|---------|--------|--------|---------------| +| Pakistan (PK) | ✅ | ❌ | ✅ | +| Others | ✅ | ✅ | ❌ | + +### Invoice Expiry + +| Invoice Type | Expiry | +|--------------|--------| +| Subscription | 7 days (grace period) | +| Credit Package | 48 hours | + +--- + +*Document generated from current codebase implementation as of January 20, 2026* diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/BILLING.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/BILLING.md new file mode 100644 index 00000000..9395aae5 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/BILLING.md @@ -0,0 +1,384 @@ +# Billing Module + +**Last Verified:** January 20, 2026 +**Status:** ✅ Active (Two-Pool Credit System v2.0 January 2026) +**Backend Path:** `backend/igny8_core/modules/billing/` + `backend/igny8_core/business/billing/` +**Frontend Path:** `frontend/src/pages/Billing/` + `frontend/src/pages/Account/` + +> **Complete Billing Reference:** For comprehensive billing & payment documentation, see [BILLING-PAYMENTS-COMPLETE.md](BILLING-PAYMENTS-COMPLETE.md) +> **Payment System Reference:** For payment gateway documentation (Stripe, PayPal, Bank Transfer), see [PAYMENT-SYSTEM.md](../90-REFERENCE/PAYMENT-SYSTEM.md) + +--- + +## Two-Pool Credit System (v2.0) + +| Pool | Field | Source | Behavior | +|------|-------|--------|----------| +| **Plan Credits** | `account.credits` | Subscription plan | Reset on renewal, reset to 0 if unpaid after 24h | +| **Bonus Credits** | `account.bonus_credits` | Credit packages | **NEVER expire**, **NEVER reset** | + +### Credit Usage Priority +1. **Plan credits** used FIRST +2. **Bonus credits** only used when plan credits = 0 + +### What Happens on Renewal +| Event | Plan Credits | Bonus Credits | +|-------|--------------|---------------| +| Payment success | Reset to plan amount | No change | +| No payment (24h) | Reset to 0 | No change | +| Late payment | Reset to plan amount | No change | + +--- + +## Quick Reference + +| What | File | Key Items | +|------|------|-----------| +| Models | `business/billing/models.py` | `CreditTransaction`, `CreditUsageLog`, `CreditCostConfig`, `AIModelConfig` | +| Service | `business/billing/services/credit_service.py` | `CreditService` | +| Limit Service | `business/billing/services/limit_service.py` | `LimitService` (4 limits only) | +| Views | `modules/billing/views.py` | `CreditBalanceViewSet`, `CreditUsageViewSet` | +| Frontend | `pages/Account/PlansAndBillingPage.tsx` | Plans, credits, billing history | +| Store | `store/billingStore.ts` | `useBillingStore` | + +--- + +## Purpose + +The Billing module manages: +- Credit balance and transactions +- AI model pricing and credit configuration (v1.4.0) +- Usage tracking with 4 simplified limits (v1.5.0) +- Plan enforcement +- Payment processing + +--- + +## Data Models + +### AIModelConfig (NEW v1.4.0) + +Single Source of Truth for all AI models with pricing. + +| Field | Type | Purpose | +|-------|------|---------| +| model_name | CharField(100) | Model identifier (gpt-4o-mini, dall-e-3) | +| model_type | CharField(20) | text / image | +| provider | CharField(50) | openai, anthropic, runware | +| display_name | CharField(200) | Human-readable name | +| is_default | BooleanField | One default per type | +| is_active | BooleanField | Enable/disable | +| cost_per_1k_input | DecimalField | USD cost per 1K input tokens (text) | +| cost_per_1k_output | DecimalField | USD cost per 1K output tokens (text) | +| tokens_per_credit | IntegerField | Text: tokens per 1 credit (e.g., 1000) | +| credits_per_image | IntegerField | Image: credits per image (1, 5, 15) | +| quality_tier | CharField(20) | basic / quality / premium | +| max_tokens | IntegerField | Model token limit | +| context_window | IntegerField | Model context size | +| capabilities | JSONField | vision, function_calling, etc. | + +**Credit Examples:** + +| Model | tokens_per_credit | credits_per_image | quality_tier | +|-------|-------------------|-------------------|--------------| +| gpt-4o | 1000 | - | - | +| gpt-4o-mini | 10000 | - | - | +| runware:97@1 | - | 1 | basic | +| dall-e-3 | - | 5 | quality | +| google:4@2 | - | 15 | premium | + +### CreditTransaction (Ledger) + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| transaction_type | CharField | purchase/subscription/refund/deduction/adjustment | +| amount | Decimal | Positive (add) or negative (deduct) | +| balance_after | Decimal | Balance after transaction | +| description | CharField | Transaction description | +| metadata | JSON | Additional data | +| payment | FK(Payment) | Payment that triggered this (v1.4.0) | +| reference_id | CharField | DEPRECATED: Use payment FK | +| created_at | DateTime | Transaction time | + +### CreditUsageLog (Analytics) + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| operation_type | CharField | clustering/idea_generation/content_generation/image_generation | +| credits_used | Decimal | Credits consumed | +| cost_usd | Decimal | USD cost | +| model_used | CharField | AI model used | +| tokens_in | Integer | Input tokens | +| tokens_out | Integer | Output tokens | +| content_type | FK | Related content type | +| object_id | Integer | Related object ID | +| metadata | JSON | Additional data | +| created_at | DateTime | Usage time | + +### CreditCostConfig (Updated v1.4.0) + +| Field | Type | Purpose | +|-------|------|---------| +| operation_type | CharField(50) PK | Unique operation ID | +| display_name | CharField(100) | Human-readable name | +| base_credits | IntegerField | Fixed credits per operation | +| is_active | BooleanField | Enable/disable | +| description | TextField | Admin notes | + +**Note:** `tokens_per_credit` moved to AIModelConfig in v1.4.0. + +--- + +## Credit Calculation Methods + +### Method 1: Token-Based (Text Models) - Updated v1.4.0 + +Used for: Clustering, Ideas, Content Generation, Optimization + +**Flow:** +1. AI call completes +2. OpenAI returns actual token usage +3. Calculate: `total_tokens = input_tokens + output_tokens` +4. Look up `AIModelConfig.tokens_per_credit` for the model used +5. Calculate: `credits = ceil(total_tokens / tokens_per_credit)` +6. Deduct from balance + +**Example:** +- Model: `gpt-4o-mini` (tokens_per_credit = 10000) +- Tokens used: 15000 +- Credits: `ceil(15000 / 10000)` = 2 credits + +### Method 2: Fixed Cost (Image Models) - Updated v1.4.0 + +Used for: Image Generation + +**Flow:** +1. User selects quality tier (basic/quality/premium) +2. Look up `AIModelConfig.credits_per_image` for selected tier +3. Check balance sufficient: `balance >= num_images * credits_per_image` +4. Deduct credits +5. Make AI call + +**Example:** +- Quality Tier: "quality" (dall-e-3, credits_per_image = 5) +- Images: 3 +- Credits: 3 × 5 = 15 credits +2. Calculate: `credits = num_images * cost_per_image` +3. Check balance sufficient +4. Deduct credits +5. Then make AI call + +--- + +## API Endpoints + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/billing/balance/` | `CreditBalanceViewSet.list` | Current balance + monthly usage | +| GET | `/api/v1/billing/usage/` | `CreditUsageViewSet.list` | Usage log (paginated) | +| GET | `/api/v1/billing/usage/summary/` | `CreditUsageViewSet.summary` | Aggregated by operation | +| GET | `/api/v1/billing/usage/limits/` | `CreditUsageViewSet.limits` | Plan limits + current usage | +| GET | `/api/v1/billing/transactions/` | `TransactionViewSet.list` | Transaction history | + +--- + +## Credit Service API + +### Check Credits + +```python +CreditService.check_credits(account, required_credits) +# Raises InsufficientCreditsError if balance < required +``` + +### Deduct Credits + +```python +CreditService.deduct_credits_for_operation( + account=account, + operation_type='content_generation', + amount=word_count, # For per_word operations + model='gpt-4o-mini', + tokens_in=2500, + tokens_out=1500, + metadata={'content_id': 123} +) +``` + +### Add Credits + +```python +CreditService.add_credits( + account=account, + amount=1000, + transaction_type='purchase', + description='Credit package purchase' +) +``` + +### Calculate Credits for Images (NEW v1.4.0) + +```python +# Calculate credits needed for image generation based on model +credits = CreditService.calculate_credits_for_image( + model_name='dall-e-3', # Model with credits_per_image = 5 + num_images=3 +) +# Returns: 15 (3 images × 5 credits) +``` + +### Check Credits for Image Generation (NEW v1.7.1) + +```python +# Pre-check credits before image generation starts +# Raises InsufficientCreditsError if not enough credits +required = CreditService.check_credits_for_image( + account=account, + model_name='dall-e-3', # Model with credits_per_image = 5 + num_images=3 +) +# Returns: 15 (required credits) if sufficient, raises exception if not +``` + +### Deduct Credits for Image Generation (v1.7.1 Verified) + +```python +# Called after each successful image generation +credits_deducted = CreditService.deduct_credits_for_image( + account=account, + model_name='dall-e-3', + num_images=1, + description='Image generation: Article Title', + metadata={'image_id': 123, 'content_id': 456}, + cost_usd=0.04, + related_object_type='image', + related_object_id=123 +) +# Logs to CreditTransaction and CreditUsageLog +``` + +### Calculate Credits from Tokens by Model (NEW v1.4.0) + +```python +# Calculate credits from token usage based on model's tokens_per_credit +credits = CreditService.calculate_credits_from_tokens_by_model( + model_name='gpt-4o-mini', # Model with tokens_per_credit = 10000 + total_tokens=15000 +) +# Returns: 2 (ceil(15000 / 10000)) +``` + +--- + +## Plan Limits + +### Hard Limits (Never Reset) + +| Limit | Field | Description | +|-------|-------|-------------| +| Sites | `max_sites` | Maximum sites per account | +| Users | `max_users` | Maximum team members | +| Keywords | `max_keywords` | Total keywords allowed | + +### Monthly Limits (Reset on Billing Cycle) + +| Limit | Field | Description | +|-------|-------|-------------| +| Ahrefs Queries | `max_ahrefs_queries` | Live Ahrefs API queries per month | + +**Note:** As of January 2026, the limit system was simplified from 10+ limits to just 4. Credits handle all AI operation costs (content generation, image generation, clustering, etc.) instead of separate per-operation limits. + +--- + +## Usage Limits Panel + +**Component:** `UsageLimitsPanel.tsx` + +Displays: +- Progress bars for 4 limits only (Sites, Users, Keywords, Ahrefs Queries) +- Color coding: blue (safe), yellow (warning), red (critical) +- Days until reset for monthly limits (Ahrefs Queries) +- Upgrade CTA when approaching limits + +--- + +## Credit Costs Reference (Updated v1.4.0) + +**Text Model Credits** (from `AIModelConfig.tokens_per_credit`): + +| Model | tokens_per_credit | Cost/Credit | Notes | +|-------|-------------------|-------------|-------| +| gpt-4o | 1000 | ~$0.015 | High quality, lower throughput | +| gpt-4o-mini | 10000 | ~$0.001 | Fast, cost-effective | +| gpt-4.5-preview | 500 | ~$0.05 | Highest quality | + +**Image Model Credits** (from `AIModelConfig.credits_per_image`): + +| Quality Tier | credits_per_image | Model Example | Notes | +|--------------|-------------------|---------------|-------| +| Basic | 1 | runware:97@1 | Fast generation | +| Quality | 5 | dall-e-3 | Balanced | +| Premium | 15 | google:4@2 | Best quality | + +**Operation Base Costs** (from `CreditCostConfig.base_credits`): + +| Operation | Base Credits | Notes | +|-----------|--------------|-------| +| Clustering | 10 | Per clustering request | +| Idea Generation | 2 | Per idea generated | +| Content Optimization | 5 | Per optimization run | + +--- + +## Frontend Pages + +### Plans & Billing (`/account/plans`) + +**Tabs:** +1. **Current Plan** - Active plan details, renewal date, "View Usage" link +2. **Upgrade Plan** - Pricing table with plan comparison +3. **Billing History** - Invoices and payment history + +### Usage Analytics (`/account/usage`) + +**Tabs:** +1. **Limits & Usage** - Plan limits with progress bars (4 limits only) +2. **Credit History** - Credit transaction history +3. **Credit Insights** - Charts: credits by type, daily timeline, operations breakdown +4. **Activity Log** - API call statistics and operation details + +--- + +## Integration Points + +| From | To | Trigger | +|------|----|---------| +| AIEngine | CreditService | Pre-check and post-deduct | +| Automation | CreditService | Per-stage credit tracking | +| Subscription | Account | Credit allocation | +| Admin | CreditCostConfig | Price adjustments | + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| 402 error | Insufficient credits | Add credits or reduce operation | +| Usage not showing | Log not created | Check CreditService called | +| Limits wrong | Cache stale | Clear cache, reload | +| Monthly usage high | Automation running | Pause automation | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| ~~AI Model Config database~~ | ✅ v1.4.0 | Model pricing moved to AIModelConfig | +| ~~Image model quality tiers~~ | ✅ v1.4.0 | credits_per_image per quality tier | +| ~~Credit service enhancements~~ | ✅ v1.7.1 | Model-specific calculation methods | +| ~~Image generation credit check~~ | ✅ v1.7.1 | Pre-generation credit verification | +| ~~Image generation logging~~ | ✅ v1.7.1 | AITaskLog + notifications for images | diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/INTEGRATIONS.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/INTEGRATIONS.md new file mode 100644 index 00000000..bf86ba14 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/INTEGRATIONS.md @@ -0,0 +1,368 @@ +# Integrations Module + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Status:** ✅ Active +**Backend Path:** `backend/igny8_core/modules/integration/` + `backend/igny8_core/business/integration/` +**Frontend Path:** `frontend/src/pages/Settings/IntegrationSettings.tsx` + +--- + +## Quick Reference + +| What | File | Key Items | +|------|------|-----------| +| Models | `business/integration/models.py` | `SiteIntegration`, `SyncEvent` | +| Views | `modules/integration/views.py` | `SiteIntegrationViewSet` | +| Webhooks | `modules/integration/webhooks.py` | `wordpress_webhook` | +| Services | `business/integration/services/*.py` | Sync services | +| AI Core | `ai/ai_core.py` | OpenAI, Anthropic, Runware, Bria clients | +| Model Registry | `ai/model_registry.py` | Centralized model configs | +| Frontend | `pages/Settings/IntegrationSettings.tsx` | Integration UI | + +--- + +## AI Provider Integrations (v1.3.0) + +### Supported Providers + +| Provider | Type | Models | API Key Field | +|----------|------|--------|---------------| +| OpenAI | Text/Image | gpt-4o, gpt-4o-mini, dall-e-3 | `openai_api_key` | +| Anthropic | Text | claude-3-5-sonnet, claude-3-opus, claude-3-haiku | `anthropic_api_key` | +| Runware | Image | runware-v2 | `runware_api_key` | +| Bria AI | Image | bria-2.3, bria-2.3-fast, bria-2.2 | `bria_api_key` | + +### GlobalIntegrationSettings + +Located in `modules/system/global_settings_models.py`: + +| Field | Type | Purpose | +|-------|------|---------| +| openai_api_key | CharField | OpenAI API key | +| anthropic_api_key | CharField | Anthropic API key (v1.3.0) | +| runware_api_key | CharField | Runware API key | +| bria_api_key | CharField | Bria AI API key (v1.3.0) | +| default_text_model | CharField | Default text model | +| default_image_model | CharField | Default image model | +| default_image_provider | CharField | openai/runware/bria | + +### Model Registry + +Centralized model configuration with caching: + +```python +from igny8_core.ai.model_registry import ModelRegistry + +# Get model config +model = ModelRegistry.get_model('gpt-4o-mini') + +# Calculate cost +cost = ModelRegistry.calculate_cost('gpt-4o-mini', input_tokens=1000, output_tokens=500) + +# List all models +models = ModelRegistry.list_models(model_type='text', provider='openai') +``` + +### Migrations + +- `0012_add_bria_integration.py` - Adds Bria AI integration settings +- `0013_add_anthropic_integration.py` - Adds Anthropic integration settings +- `0009_seed_ai_model_configs.py` - Seeds model configurations + +--- + +## Purpose + +The Integrations module manages: +- AI provider connections (OpenAI, Anthropic, Runware, Bria) +- WordPress site connections +- Two-way content synchronization +- Webhook handling +- External platform integrations + +--- + +## Data Models + +### Authentication Note + +**⚠️ Important:** For WordPress integrations, `Site.wp_api_key` is the **SINGLE source of truth** for API authentication, NOT SiteIntegration fields. The SiteIntegration model is used for sync tracking and multi-platform support (future: Shopify). + +### SiteIntegration + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | IGNY8 site | +| platform | CharField | wordpress/shopify | +| external_site_url | URLField | External site URL | +| is_active | Boolean | Enable/disable | +| sync_enabled | Boolean | Enable auto-sync | +| last_sync_at | DateTime | Last sync time | +| sync_status | CharField | pending/syncing/completed/error | +| sync_error | TextField | Sync error message | +| connection_status | CharField | connected/error | +| config_json | JSON | Platform-specific configuration | +| credentials_json | JSON | (Reserved for future platforms, NOT used for WordPress) | +| created_at | DateTime | Creation date | + +### SyncEvent + +| Field | Type | Purpose | +|-------|------|---------| +| integration | FK | Parent integration | +| event_type | CharField | content_push/content_pull/webhook | +| direction | CharField | igny8_to_wp/wp_to_igny8 | +| content_type | CharField | post/page/product | +| content_id | Integer | IGNY8 content ID | +| external_id | Integer | WordPress post ID | +| status | CharField | pending/success/failed | +| error_message | TextField | Error details | +| metadata | JSON | Additional data | +| created_at | DateTime | Event time | + +### PublishingSettings (v1.3.2) + +Site-level publishing configuration. Used by the publishing scheduler. + +| Field | Type | Purpose | +|-------|------|---------| +| site | OneToOneField | Parent site (unique per site) | +| auto_approval_enabled | BooleanField | Auto-approve content (default: False) | +| auto_publish_enabled | BooleanField | Auto-publish approved content (default: False) | +| daily_publish_limit | IntegerField | Max publications per day (default: 5) | +| weekly_publish_limit | IntegerField | Max per week (default: 20) | +| monthly_publish_limit | IntegerField | Max per month (default: 60) | +| publish_days | JSONField | Days for publishing ["mon","wed","fri"] | +| publish_time_slots | JSONField | Time slots [{"start":"09:00","end":"17:00"}] | + +**Helper Method:** +```python +# Get or create settings for a site +settings, created = PublishingSettings.get_or_create_for_site(site) +``` + +**Related:** See [PUBLISHER.md](PUBLISHER.md) for publishing scheduler details. + +--- + +## API Endpoints + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/integration/` | `SiteIntegrationViewSet.list` | List integrations | +| POST | `/api/v1/integration/` | `SiteIntegrationViewSet.create` | Create integration | +| PUT | `/api/v1/integration/{id}/` | `SiteIntegrationViewSet.update` | Update integration | +| DELETE | `/api/v1/integration/{id}/` | `SiteIntegrationViewSet.destroy` | Remove integration | +| POST | `/api/v1/integration/{id}/test_connection/` | Test connection | Verify credentials | +| POST | `/api/v1/integration/{id}/test_collection_connection/` | Test per-collection | Test specific content type | +| POST | `/api/v1/integration/{id}/sync/` | Trigger sync | Start synchronization | +| GET | `/api/v1/integration/{id}/sync_status/` | Get sync status | Current sync progress | +| POST | `/api/v1/integration/{id}/update_structure/` | Update structure | Refresh site structure | +| GET | `/api/v1/integration/{id}/content_types/` | Get content types | Available types + counts | +| GET | `/api/v1/integration/{id}/sync_health/` | Get sync health | Sync statistics | +| POST | `/api/v1/integration/site_sync/` | Site-level sync | Sync by site ID | + +### Webhooks + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| POST | `/api/v1/integration/webhook/wordpress/` | `wordpress_webhook` | Receive WP updates | + +--- + +## WordPress Integration + +### Setup Flow + +1. User enters WordPress site URL +2. User creates Application Password in WordPress +3. User enters credentials in IGNY8 +4. IGNY8 tests connection via WordPress REST API +5. If successful, saves `SiteIntegration` record + +### Required WordPress Setup + +- WordPress 5.6+ (REST API enabled) +- Application Passwords enabled +- Pretty permalinks enabled +- REST API accessible (no blocking plugins) + +### Test Connection + +**Endpoint:** `POST /integration/{id}/test_connection/` + +**Flow:** +1. Call WordPress `/wp-json/wp/v2/users/me` +2. Verify authentication works +3. Return user info and site capabilities + +--- + +## Content Synchronization + +### IGNY8 → WordPress (Push) + +**Trigger:** User clicks "Publish to WordPress" + +**Flow:** +1. Content is in `approved` status +2. Get `SiteIntegration` for content's site +3. Build WordPress post payload: + - title, content, excerpt, slug + - status: `publish` or `draft` + - categories, tags (mapped) + - featured media (if image exists) +4. Call WordPress REST API: + - `POST /wp-json/wp/v2/posts` (new) + - `PUT /wp-json/wp/v2/posts/{id}` (update) +5. Store `wordpress_id` on Content +6. Create `SyncEvent` record +7. Update Content status to `published` + +### WordPress → IGNY8 (Pull) + +**Trigger:** Manual sync or webhook + +**Flow:** +1. Call WordPress `/wp-json/wp/v2/posts` +2. For each post: + - Check if exists in IGNY8 by `wordpress_id` + - If exists: Update if modified + - If new: Create Content record +3. Sync taxonomies (categories, tags) +4. Create `SyncEvent` records + +### Webhook Handling + +**WordPress Plugin** sends webhooks to IGNY8 when: +- Post created/updated/deleted +- Post status changed (draft → published) + +**Webhook Payload:** +```json +{ + "action": "post_updated", + "post_id": 123, + "post_type": "post", + "site_url": "https://example.com" +} +``` + +**IGNY8 Processing:** +1. Validate webhook signature (optional) +2. Find matching `SiteIntegration` +3. Fetch full post from WordPress +4. Update/create Content in IGNY8 +5. Create `SyncEvent` record + +--- + +## Image Sync + +### Push (IGNY8 → WordPress) + +1. Image record has `image_url` +2. Download image from URL +3. Upload to WordPress Media Library +4. Get WordPress attachment ID +5. Set as featured image on post + +### Pull (WordPress → IGNY8) + +1. Get featured media ID from post +2. Fetch media URL from WordPress +3. Store URL in IGNY8 Images record + +--- + +## Taxonomy Sync + +### Categories + +1. Get WordPress categories via `/wp-json/wp/v2/categories` +2. Create `ContentTaxonomy` records (type=category) +3. Store `wordpress_id` for mapping + +### Tags + +1. Get WordPress tags via `/wp-json/wp/v2/tags` +2. Create `ContentTaxonomy` records (type=tag) +3. Store `wordpress_id` for mapping + +--- + +## Sync Status Tracking + +| Status | Description | +|--------|-------------| +| idle | No sync in progress | +| syncing | Sync currently running | +| error | Last sync failed | + +**Sync Health Metrics:** +- Total synced posts +- Last successful sync +- Failed sync count +- Pending items + +--- + +## Frontend Pages + +### Integration Settings (`/settings/integration`) + +- Add new integration button +- List of configured integrations +- Status indicators (connected/error) +- Test connection button +- Sync now button +- Sync status and history + +### WordPress Sync Dashboard (`/sites/{id}/sync`) + +- Detailed sync status +- Content sync queue +- Error log +- Manual sync triggers + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| Connection failed | Invalid credentials | Verify Application Password | +| 401 Unauthorized | Password expired | Regenerate Application Password | +| 403 Forbidden | REST API blocked | Check security plugins | +| Images not syncing | CORS/URL issues | Verify image URLs accessible | +| Categories missing | Not synced | Run sync_structure first | + +--- + +## Security + +### Credential Storage + +- API keys encrypted at rest +- Never exposed in API responses +- Application Passwords rotatable + +### Webhook Security + +- Optional signature verification +- Site URL validation +- Rate limiting on webhook endpoint + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| Shopify integration | 🔜 Planned | E-commerce platform support | +| Ghost integration | 🔜 Planned | Ghost CMS support | +| Webflow integration | 🔜 Planned | Webflow CMS support | +| Scheduled sync | 🔜 Planned | Automatic periodic sync | +| Conflict resolution | 🔜 Planned | Handle edit conflicts | diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/LINKER.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/LINKER.md new file mode 100644 index 00000000..e86379c8 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/LINKER.md @@ -0,0 +1,184 @@ +# Linker Module + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Status:** ⏸️ Inactive (Disabled by Default) +**Backend Path:** `backend/igny8_core/modules/linker/` +**Frontend Path:** `frontend/src/pages/Linker/` + +--- + +## Module Status + +| Aspect | Current State | Notes | +|--------|---------------|-------| +| Backend API | ✅ Implemented | Endpoints functional | +| Frontend Pages | ✅ Implemented | UI exists | +| Sidebar Nav | ⚠️ Conditional | Hidden when disabled | +| Route Protection | ❌ Not Protected | Direct URL access still works | +| Dashboard References | ❌ Not Hidden | May show in dashboard | +| Default State | Disabled | `linker_enabled = True` in model, but typically disabled | + +**⚠️ Pending Implementation:** Extend module disable to route-level protection and all page references. + +--- + +## Quick Reference + +| What | File | Key Items | +|------|------|-----------| +| Views | `modules/linker/views.py` | `LinkerViewSet` | +| API | `modules/linker/urls.py` | Linker endpoints | +| Frontend Pages | `pages/Linker/index.tsx` | Linker overview | +| Frontend Pages | `pages/Linker/LinkerContent.tsx` | Content for linking | +| API Client | `api/linker.api.ts` | `linkerApi` | +| Module Control | `modules/system/settings_models.py` | `ModuleEnableSettings.linker_enabled` | + +--- + +## Purpose + +The Linker module provides internal linking automation: +- Identify link opportunities in content +- Suggest relevant internal links +- Auto-inject links into content body + +--- + +## API Endpoints + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| POST | `/api/v1/linker/process/` | `LinkerViewSet.process` | Process single content for linking | +| POST | `/api/v1/linker/batch_process/` | `LinkerViewSet.batch_process` | Process multiple content items | + +### Process Request + +```json +{ + "content_id": 123, + "max_links": 5, + "anchor_strategy": "exact_match" +} +``` + +### Process Response + +```json +{ + "content_id": 123, + "links_added": 3, + "link_opportunities": [ + { + "anchor_text": "SEO optimization", + "target_url": "/blog/seo-guide/", + "target_content_id": 456, + "position": 234, + "confidence": 0.85 + } + ] +} +``` + +--- + +## Business Logic + +### Link Candidate Discovery + +**Trigger:** User initiates linking process +**Flow:** +1. Load source content body +2. Extract potential anchor phrases +3. Find matching content by: + - Keyword overlap + - Title similarity + - Same sector/industry +4. Score candidates by relevance +5. Filter to avoid over-linking + +### Link Injection + +**Trigger:** User approves link suggestions +**Flow:** +1. Locate anchor text in content +2. Wrap in `` tag with target URL +3. Ensure no nested links +4. Save updated content body + +--- + +## Module Enable Control + +### Backend Model + +```python +# modules/system/settings_models.py +class ModuleEnableSettings(AccountBaseModel): + linker_enabled = models.BooleanField(default=True) +``` + +### Frontend Check + +```typescript +// layout/AppSidebar.tsx +if (isModuleEnabled('linker')) { + workflowItems.push({ + name: "Linker", + path: "/linker/content", + }); +} +``` + +### Current Limitation + +Direct URL access to `/linker/*` routes still works even when module is disabled. + +--- + +## Frontend Pages + +### Linker Overview (`/linker`) + +- Module overview +- Quick stats +- Start linking action + +### Content for Linking (`/linker/content`) + +- List of content available for linking +- Link status indicators +- Process button per content +- Batch processing action + +--- + +## Integration Points + +| From | To | Trigger | +|------|----|---------| +| Content | Linker | Manual process | +| Linker | Content | Link injection | +| Automation | Linker | Automated linking (future) | + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| Module visible when disabled | Only sidebar hidden | Pending: route protection | +| No link candidates | No matching content | Create more related content | +| Links broken | Target content deleted | Validate target exists | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| Route-level protection | 🔜 Pending | Block access when module disabled | +| Dashboard card hiding | 🔜 Pending | Hide from dashboard when disabled | +| Automation integration | 🔜 Planned | Add to automation pipeline | +| Link density control | 🔜 Planned | Prevent over-linking | +| External link support | 🔜 Planned | Add outbound links | diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/NOTIFICATIONS.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/NOTIFICATIONS.md new file mode 100644 index 00000000..980bd268 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/NOTIFICATIONS.md @@ -0,0 +1,594 @@ +# Notifications Module + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Status:** ✅ Active +**Backend Path:** `backend/igny8_core/business/notifications/` +**Frontend Path:** `frontend/src/store/notificationStore.ts`, `frontend/src/components/header/NotificationDropdown.tsx`, `frontend/src/pages/account/NotificationsPage.tsx` + +--- + +## Quick Reference + +| What | File | Key Items | +|------|------|-----------| +| Models | `business/notifications/models.py` | `Notification`, `NotificationPreference` | +| Views | `business/notifications/views.py` | `NotificationViewSet` | +| Serializers | `business/notifications/serializers.py` | `NotificationSerializer` | +| Services | `business/notifications/services.py` | `NotificationService` | +| Frontend Store | `store/notificationStore.ts` | Zustand notification store | +| Frontend Dropdown | `components/header/NotificationDropdown.tsx` | Notification UI (header bell) | +| Frontend Page | `pages/account/NotificationsPage.tsx` | Full notifications history page | +| API Client | `services/notifications.api.ts` | API methods | + +--- + +## Purpose + +The Notifications module provides real-time user notifications for AI operations, system events, and workflow milestones. Notifications appear in the header dropdown and persist in the database. + +**Key Features:** +- Real-time notifications for AI task completion/failure +- Account-wide or user-specific notifications +- Read/unread state tracking +- Action buttons with navigation +- Auto-fetch and auto-sync with API + +--- + +## Data Models + +### Notification + +| Field | Type | Currently Used? | Purpose | +|-------|------|----------------|---------| +| account | FK | ✅ **Yes** | Owner account (required for multi-tenancy) | +| user | FK | ❌ **No** | User-specific notifications (nullable - if null, visible to all account users). **Currently unused** - all notifications are account-wide | +| notification_type | CharField | ✅ **Yes** | Type from NotificationType choices (for filtering, icons) | +| title | CharField(200) | ✅ **Yes** | Notification title shown in dropdown | +| message | TextField | ✅ **Yes** | Notification body text shown in dropdown | +| severity | CharField | ✅ **Yes** | info/success/warning/error (affects icon color) | +| site | FK | ✅ **Partial** | Related site (nullable). Created but **not displayed** in current dropdown | +| content_type | FK | ❌ **No** | Generic relation to any object. **Future:** Link notification to specific Content/Task/etc. for direct access | +| object_id | PositiveInteger | ❌ **No** | Generic relation ID. **Future:** Used with content_type for object linking | +| action_url | CharField(500) | ✅ **Yes** | Frontend route for action button (e.g., `/planner/clusters`) | +| action_label | CharField(50) | ✅ **Yes** | Action button text (e.g., "View Clusters") | +| is_read | Boolean | ✅ **Yes** | Read status (default: False). Used for unread badge count | +| read_at | DateTime | ✅ **Partial** | When marked read (nullable). Created but **not displayed** in dropdown | +| metadata | JSON | ✅ **Partial** | Additional data (counts, details). Stored but **not displayed** in dropdown | +| created_at | DateTime | ✅ **Yes** | Creation timestamp. Shown as relative time ("2 minutes ago") | +| updated_at | DateTime | ❌ **No** | Last update timestamp. **Currently unused** | + +**Indexes:** +- `(account, -created_at)` - List notifications by account ✅ **Used** +- `(account, is_read, -created_at)` - Filter unread ✅ **Used** +- `(user, -created_at)` - User-specific notifications ❌ **Unused** (all notifications are account-wide) + +--- + +### Why So Many Unused Fields? + +The model was designed with **future expansion** in mind, but the current "dropdown-only" implementation uses less than half of the fields. Here's why they exist: + +**Over-Engineered for Current Use:** +- `content_type` + `object_id` → For direct object linking (planned: click notification, go to that exact content item) +- `user` → For user-specific notifications (planned: "@John, your content is ready") +- `metadata` → For rich data (planned: show counts, progress, details in dedicated page) +- `read_at` → For analytics (planned: "You read this 2 days ago") +- `updated_at` → For editing notifications (planned: update notification instead of creating duplicate) + +**Currently Essential:** +- `account`, `title`, `message`, `severity`, `notification_type` → Core notification data +- `action_url`, `action_label` → Navigation buttons +- `is_read`, `created_at` → Dropdown functionality + +**The Design Mismatch:** +You're right - this is a **database schema designed for a full-featured notification system** (with dedicated page, filtering, search, history) but the frontend only implements a **simple dropdown**. The backend is over-built for the current use case. + +--- + +## Notification Types + +### AI Operations + +| Type | Severity | Trigger | Message Format | +|------|----------|---------|----------------| +| `ai_cluster_complete` | success | Clustering finishes | "Created X clusters from Y keywords" | +| `ai_cluster_failed` | error | Clustering fails | "Failed to cluster keywords: [error]" | +| `ai_ideas_complete` | success | Idea generation finishes | "Generated X content ideas from Y clusters" | +| `ai_ideas_failed` | error | Idea generation fails | "Failed to generate ideas: [error]" | +| `ai_content_complete` | success | Content generation finishes | "Generated X articles (Y words)" | +| `ai_content_failed` | error | Content generation fails | "Failed to generate content: [error]" | +| `ai_images_complete` | success | Image generation finishes | "Generated X images" | +| `ai_images_failed` | error | Image generation fails | "Failed to generate X images: [error]" | +| `ai_prompts_complete` | success | Image prompts created | "X image prompts ready (1 featured + Y in-article)" | +| `ai_prompts_failed` | error | Image prompt creation fails | "Failed to create image prompts: [error]" | + +### Workflow Events + +| Type | Severity | Trigger | Message Format | +|------|----------|---------|----------------| +| `content_ready_review` | info | Content moved to review | "[Title] ready for review" | +| `content_published` | success | Content published | '"[Title]" published to [site]' | +| `content_publish_failed` | error | Publishing fails | 'Failed to publish "[Title]": [error]' | + +### WordPress Sync + +| Type | Severity | Trigger | Message Format | +|------|----------|---------|----------------| +| `wordpress_sync_success` | success | Sync completes | "Synced X items with [site]" | +| `wordpress_sync_failed` | error | Sync fails | "WordPress sync failed for [site]: [error]" | + +### Credits & Billing + +| Type | Severity | Trigger | Message Format | +|------|----------|---------|----------------| +| `credits_low` | warning | Credits < 20% | "You've used X% of your credits. Y remaining." | +| `credits_depleted` | error | Credits exhausted | "Your credits are exhausted. Upgrade to continue." | + +### Setup & System + +| Type | Severity | Trigger | Message Format | +|------|----------|---------|----------------| +| `site_setup_complete` | success | All setup steps done | "[Site] is fully configured and ready!" | +| `keywords_imported` | info | Keywords added | "Added X keywords to [site]" | +| `system_info` | info | System messages | Custom message | + +--- + +## Notification Triggers + +### AI Task Completion (AIEngine) + +**Location:** `backend/igny8_core/ai/engine.py` +**Methods:** `_create_success_notification()`, `_create_failure_notification()` + +**Flow:** +1. AIEngine executes AI function (`auto_cluster`, `generate_ideas`, etc.) +2. On **success** (after DONE phase): + - Calls `_create_success_notification(function_name, save_result, payload)` + - Maps function to NotificationService method + - Creates notification with counts/metrics +3. On **failure** (in `_handle_error()`): + - Calls `_create_failure_notification(function_name, error)` + - Creates error notification with error message + +**Mapping:** +```python +auto_cluster → NotificationService.notify_clustering_complete/failed +generate_ideas → NotificationService.notify_ideas_complete/failed +generate_content → NotificationService.notify_content_complete/failed +generate_image_prompts → NotificationService.notify_prompts_complete/failed +generate_images → NotificationService.notify_images_complete/failed +``` + +### WordPress Publishing + +**Location:** `backend/igny8_core/tasks/wordpress_publishing.py` +**Trigger:** After publishing content to WordPress + +```python +NotificationService.notify_content_published( + account=account, + site=site, + title=content.title, + content_object=content +) +``` + +### WordPress Sync + +**Location:** `backend/igny8_core/tasks/wordpress_publishing.py` +**Trigger:** After syncing posts from WordPress + +```python +NotificationService.notify_wordpress_sync_success( + account=account, + site=site, + count=synced_count +) +``` + +### Credit Alerts + +**Location:** `backend/igny8_core/business/billing/services/credit_service.py` +**Trigger:** After deducting credits + +```python +# When credits drop below threshold +NotificationService.notify_credits_low( + account=account, + percentage_used=80, + credits_remaining=remaining +) + +# When credits exhausted +NotificationService.notify_credits_depleted(account=account) +``` + +### Manual Triggers (Optional) + +Notifications can also be created manually from anywhere: + +```python +from igny8_core.business.notifications.services import NotificationService + +NotificationService.notify_keywords_imported( + account=account, + site=site, + count=keyword_count +) +``` + +**Note:** As of v1.2.1, the following actions **DO create notifications**: +- ✅ AI task completion/failure (clustering, ideas, content, images, prompts) +- ✅ Keyword import via "Add to Workflow" - **Fixed in v1.2.1** + +**Actions that DON'T yet create notifications** (planned): +- ❌ WordPress publishing (needs integration in wordpress_publishing.py) +- ❌ WordPress sync (needs integration in wordpress_publishing.py) +- ❌ Credit alerts (needs integration in credit_service.py) +- ❌ Automation completion (planned for future) + +--- + +## User Interface + +### Notification Dropdown (Header) + +**Location:** Header bell icon (top right) +**File:** `frontend/src/components/header/NotificationDropdown.tsx` + +**Features:** +- Shows last 50 notifications +- Animated badge with unread count +- Click notification to mark read + navigate +- "Mark all read" button +- Auto-refreshes every 30 seconds +- Refreshes when opened (if stale > 1 minute) +- "View All Notifications" link to full page + +### Notifications Page (Full History) + +**Location:** `/account/notifications` +**File:** `frontend/src/pages/account/NotificationsPage.tsx` +**Access:** Sidebar → ACCOUNT → Notifications OR NotificationDropdown → "View All Notifications" + +**Features:** +- **Filters:** + - Severity (info/success/warning/error) + - Notification type (AI operations, WordPress sync, credits, etc.) + - Read status (all/unread/read) + - Site (filter by specific site) + - Date range (from/to dates) +- **Actions:** + - Mark individual notifications as read + - Mark all as read (bulk action) + - Delete individual notifications + - Click notification to navigate to action URL +- **Display:** + - Full notification history with pagination + - Severity icons with color coding + - Relative timestamps ("2 hours ago") + - Site badge when applicable + - Action buttons for related pages + - Unread badge in sidebar menu + +**v1.2.2 Implementation:** +- ✅ Full-page notifications view created +- ✅ Advanced filtering by severity, type, read status, site, date range +- ✅ Bulk actions (mark all read) +- ✅ Individual actions (mark read, delete) +- ✅ Added to sidebar under ACCOUNT section +- ✅ Unread count badge in sidebar +- ✅ Fixed broken link in NotificationDropdown (was `/notifications`, now `/account/notifications`) + +--- + +## API Endpoints + +### List Notifications + +```http +GET /api/v1/notifications/ +``` + +**Query Parameters:** +- `page` - Page number (default: 1) +- `page_size` - Results per page (default: 20) +- `is_read` - Filter by read status (`true`/`false`) +- `notification_type` - Filter by type (e.g., `ai_cluster_complete`) +- `severity` - Filter by severity (`info`/`success`/`warning`/`error`) + +**Response:** +```json +{ + "count": 42, + "next": "/api/v1/notifications/?page=2", + "previous": null, + "results": [ + { + "id": 123, + "notification_type": "ai_cluster_complete", + "severity": "success", + "title": "Clustering Complete", + "message": "Created 5 clusters from 50 keywords", + "is_read": false, + "created_at": "2025-12-28T10:30:00Z", + "read_at": null, + "action_label": "View Clusters", + "action_url": "/planner/clusters", + "site": {"id": 1, "name": "My Blog"}, + "metadata": { + "cluster_count": 5, + "keyword_count": 50 + } + } + ] +} +``` + +### Get Unread Count + +```http +GET /api/v1/notifications/unread-count/ +``` + +**Response:** +```json +{ + "unread_count": 7 +} +``` + +### Mark as Read + +```http +POST /api/v1/notifications/{id}/read/ +``` + +**Response:** +```json +{ + "id": 123, + "is_read": true, + "read_at": "2025-12-28T10:35:00Z" +} +``` + +### Mark All as Read + +```http +POST /api/v1/notifications/read-all/ +``` + +**Response:** +```json +{ + "updated_count": 7, + "message": "Marked 7 notifications as read" +} +``` + +### Delete Notification + +```http +DELETE /api/v1/notifications/{id}/ +``` + +**Response:** `204 No Content` + +--- + +## Frontend Implementation + +### Notification Store + +**File:** `frontend/src/store/notificationStore.ts` + +**Features:** +- Zustand store for state management +- In-memory queue for optimistic UI updates +- API sync for persistent notifications +- Auto-fetch on mount and periodic sync (every 30 seconds) +- Auto-refresh when dropdown opens (if stale > 1 minute) + +**Key Methods:** +```typescript +// Add local notification (optimistic) +addNotification(notification) + +// Mark as read (optimistic + API sync) +markAsRead(id) + +// Mark all as read +markAllAsRead() + +// Fetch from API +fetchNotifications() + +// Sync unread count +syncUnreadCount() +``` + +### Notification Dropdown + +**File:** `frontend/src/components/header/NotificationDropdown.tsx` + +**Features:** +- Badge with unread count (animated ping when > 0) +- Dropdown with notification list +- Click notification to mark read and navigate +- "Mark all read" action +- Empty state when no notifications +- Auto-fetch on open if stale + +**Icon Mapping:** +```typescript +auto_cluster → GroupIcon +generate_ideas → BoltIcon +generate_content → FileTextIcon +generate_images → FileIcon +system → AlertIcon +success → CheckCircleIcon +``` + +--- + +## Business Logic + +### Visibility Rules + +1. **Account-wide notifications** (`user=NULL`): + - Visible to ALL users in the account + - Example: "Automation completed 10 tasks" + +2. **User-specific notifications** (`user=User`): + - Only visible to that specific user + - Example: "Your content is ready for review" + +3. **Site-filtered** (frontend): + - Frontend can filter by site in UI + - Backend always returns all account notifications + +### Read Status + +- Notifications start as `is_read=False` +- Clicking notification marks it read (API call + optimistic update) +- "Mark all read" bulk updates all unread notifications +- Read notifications stay in dropdown (can be filtered out in future) + +### Retention Policy + +- Notifications never auto-delete (future: add retention policy) +- Users can manually delete notifications +- Admin can clean up old notifications via management command (future) + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| Notifications not appearing | AIEngine not calling NotificationService | Fixed in v1.2.1 | +| "Add to workflow" no notification | KeywordViewSet not calling NotificationService | Fixed in v1.2.1 | +| Can't see notification history | No dedicated notifications page | Fixed in v1.2.2 - Page created at /account/notifications | +| "View All" button → 404 | Link to `/notifications` but page doesn't exist | Fixed in v1.2.2 - Link updated to /account/notifications | +| Duplicate notifications | Multiple AI task retries | Check task retry logic | +| Missing notifications | Celery worker crashed | Check Celery logs | +| Unread count wrong | Race condition in state | Refresh page or wait for sync | +| Action URL not working | Incorrect route in action_url | Check NotificationService methods | + +--- + +## Integration Points + +| From | To | Trigger | +|------|----|---------| +| AIEngine | NotificationService | AI task success/failure | +| WordPress Publisher | NotificationService | Publishing/sync events | +| Credit Service | NotificationService | Low credits/depleted | +| Automation | NotificationService | Automation milestones (future) | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| Notification preferences | 🔜 Planned | User can toggle notification types | +| Email notifications | 🔜 Planned | Send email for critical notifications | +| Push notifications | 🔜 Planned | Browser push for real-time alerts | +| Notification retention | 🔜 Planned | Auto-delete after 30/60 days | +| Notification categories | 🔜 Planned | Group by module (Planner, Writer, etc.) | +| Notification sounds | 🔜 Planned | Audio alerts for important events | +| Webhook notifications | 🔜 Planned | POST to external webhook URLs | + +--- + +## Version History + +| Version | Date | Changes | +|---------|------|---------| +| v1.2.2 | Dec 28, 2025 | **NEW:** Full notifications page at /account/notifications with filtering, bulk actions, and sidebar integration | +| v1.2.1 | Dec 28, 2025 | **Fixed:** Notifications now created on AI task completion + keyword import | +| v1.2.0 | Dec 27, 2025 | Initial notifications system implementation | + +--- + +## Testing + +### Test Notification Creation + +```python +# In Django shell: docker exec -it igny8_backend python manage.py shell +from igny8_core.business.notifications.services import NotificationService +from igny8_core.auth.models import Account + +account = Account.objects.first() + +# Test clustering notification +NotificationService.notify_clustering_complete( + account=account, + cluster_count=5, + keyword_count=50 +) + +# Test error notification +NotificationService.notify_clustering_failed( + account=account, + error="Insufficient credits" +) +``` + +### Test Frontend + +1. Run AI operation (clustering, idea generation, etc.) +2. Check notification dropdown (bell icon in header) +3. Verify unread badge appears +4. Click notification to mark read and navigate +5. Click "Mark all read" to clear badge + +--- + +## Debug Commands + +```bash +# Check Celery logs for notification creation +docker logs igny8_celery_worker -f | grep -i "notification" + +# Check notifications in database +docker exec -it igny8_backend python manage.py shell +>>> from igny8_core.business.notifications.models import Notification +>>> Notification.objects.count() +>>> Notification.objects.filter(is_read=False).count() +>>> Notification.objects.last().title + +# Test notification API +curl -H "Authorization: Bearer " \ + http://localhost:8011/api/v1/notifications/ + +# Check notification creation code +grep -r "notify_clustering_complete" backend/ +``` + +--- + +## Architecture Notes + +**Design Pattern:** Service Layer + Repository Pattern +- `NotificationService` provides static methods for creating notifications +- Each notification type has dedicated method with validation +- `Notification.create_notification()` is class method for low-level creation +- Views use `AccountModelViewSet` for automatic account filtering + +**Why Not Signals?** +- Explicit is better than implicit +- Clear call sites for debugging +- Easier to test and mock +- No hidden side effects +- Can pass context-specific data + +**Lazy Imports:** +- NotificationService uses lazy imports in AIEngine to avoid Django app loading issues +- Import inside method, not at module level diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/OPTIMIZER.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/OPTIMIZER.md new file mode 100644 index 00000000..bc63767e --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/OPTIMIZER.md @@ -0,0 +1,263 @@ +# Optimizer Module + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Status:** ⏸️ Inactive (Disabled by Default) +**Backend Path:** `backend/igny8_core/modules/optimizer/` + `backend/igny8_core/business/optimization/` +**Frontend Path:** `frontend/src/pages/Optimizer/` + +--- + +## Module Status + +| Aspect | Current State | Notes | +|--------|---------------|-------| +| Backend API | ✅ Implemented | Endpoints functional | +| Business Logic | ✅ Implemented | Optimization service exists | +| Frontend Pages | ✅ Implemented | UI exists | +| Sidebar Nav | ⚠️ Conditional | Hidden when disabled | +| Route Protection | ❌ Not Protected | Direct URL access still works | +| Dashboard References | ❌ Not Hidden | May show in dashboard | +| Default State | Disabled | `optimizer_enabled = True` in model, but typically disabled | + +**⚠️ Pending Implementation:** Extend module disable to route-level protection and all page references. + +--- + +## Quick Reference + +| What | File | Key Items | +|------|------|-----------| +| Views | `modules/optimizer/views.py` | `OptimizerViewSet` | +| Models | `business/optimization/models.py` | `OptimizationTask` | +| Services | `business/optimization/services/*.py` | Optimization logic | +| AI Function | `ai/functions/optimize.py` | `OptimizeContentFunction` | +| Frontend Pages | `pages/Optimizer/index.tsx` | Optimizer overview | +| Frontend Pages | `pages/Optimizer/OptimizerContent.tsx` | Select content | +| Frontend Pages | `pages/Optimizer/OptimizerPreview.tsx` | Analysis preview | +| API Client | `api/optimizer.api.ts` | `optimizerApi` | +| Module Control | `modules/system/settings_models.py` | `ModuleEnableSettings.optimizer_enabled` | + +--- + +## Purpose + +The Optimizer module provides AI-powered content optimization: +- Analyze existing content for SEO improvements +- Suggest and apply optimizations +- Track before/after scores + +--- + +## Data Models + +### OptimizationTask + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Parent site | +| sector | FK | Parent sector | +| content | FK | Target content | +| entry_point | CharField | auto/igny8/wordpress/external/manual | +| status | CharField | pending/analyzing/optimizing/completed/failed | +| original_score | Integer | Score before optimization | +| optimized_score | Integer | Score after optimization | +| original_content | TextField | Content before changes | +| optimized_content | TextField | Content after changes | +| suggestions | JSON | Optimization suggestions | +| applied_changes | JSON | Changes that were applied | +| credits_used | Decimal | Credits consumed | +| created_at | DateTime | Creation date | +| completed_at | DateTime | Completion date | + +--- + +## API Endpoints + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| POST | `/api/v1/optimizer/optimize/` | `OptimizerViewSet.optimize` | Optimize single content | +| POST | `/api/v1/optimizer/batch_optimize/` | `OptimizerViewSet.batch_optimize` | Optimize multiple items | +| POST | `/api/v1/optimizer/analyze/` | `OptimizerViewSet.analyze` | Analyze without applying | + +### Entry Points + +| Entry Point | Description | +|-------------|-------------| +| `auto` | Auto-detect based on content source | +| `igny8` | IGNY8-generated content | +| `wordpress` | WordPress-synced content | +| `external` | External platform content | +| `manual` | Manual optimization trigger | + +### Optimize Request + +```json +{ + "content_id": 123, + "entry_point": "igny8", + "optimization_goals": ["seo", "readability", "keyword_density"] +} +``` + +### Optimize Response + +```json +{ + "task_id": 456, + "content_id": 123, + "original_score": 65, + "optimized_score": 85, + "suggestions": [ + { + "type": "keyword_density", + "description": "Increase keyword 'SEO' usage", + "applied": true + }, + { + "type": "meta_description", + "description": "Meta description too short", + "applied": true + } + ], + "credits_used": 15 +} +``` + +--- + +## Business Logic + +### Content Analysis + +**Trigger:** User clicks "Analyze" +**Credit Cost:** None (analysis only) + +**Checks:** +- Keyword density and distribution +- Meta title and description optimization +- Heading structure (H1, H2, H3) +- Readability score +- Content length +- Internal/external link count +- Image alt text presence + +### Content Optimization (AI) + +**Trigger:** User clicks "Optimize" +**AI Function:** `OptimizeContentFunction` +**Credit Cost:** Per 200 words + +**Flow:** +1. Load content with metadata +2. Analyze current state +3. AIEngine executes `OptimizeContentFunction`: + - Reviews content against SEO best practices + - Suggests improvements + - Rewrites sections if needed +4. Create `OptimizationTask` record +5. Save original and optimized versions +6. Return comparison view + +--- + +## Module Enable Control + +### Backend Model + +```python +# modules/system/settings_models.py +class ModuleEnableSettings(AccountBaseModel): + optimizer_enabled = models.BooleanField(default=True) +``` + +### Frontend Check + +```typescript +// layout/AppSidebar.tsx +if (isModuleEnabled('optimizer')) { + workflowItems.push({ + name: "Optimizer", + path: "/optimizer/content", + }); +} +``` + +### Current Limitation + +Direct URL access to `/optimizer/*` routes still works even when module is disabled. + +--- + +## Frontend Pages + +### Optimizer Overview (`/optimizer`) + +- Module overview +- Quick stats +- Recent optimizations + +### Select Content (`/optimizer/content`) + +- List of content available for optimization +- Filter by score, status +- Start analysis button +- Batch optimize action + +### Analysis Preview (`/optimizer/preview`) + +- Side-by-side comparison +- Suggestion list +- Accept/reject changes +- Apply optimization button + +--- + +## Optimization Scoring + +| Metric | Weight | Description | +|--------|--------|-------------| +| Keyword Density | 20% | Target 1-3% density | +| Meta Quality | 15% | Title 50-60 chars, desc 150-160 chars | +| Heading Structure | 15% | Proper H1-H6 hierarchy | +| Readability | 15% | Flesch-Kincaid score | +| Content Length | 10% | Meets word count target | +| Internal Links | 10% | 2-5 internal links | +| Image Optimization | 10% | Alt text, sizing | +| Mobile Friendly | 5% | No wide elements | + +--- + +## Integration Points + +| From | To | Trigger | +|------|----|---------| +| Content | Optimizer | Manual analysis/optimize | +| WordPress | Optimizer | Synced content optimization | +| Optimizer | Content | Apply changes | +| Automation | Optimizer | Automated optimization (future) | + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| Module visible when disabled | Only sidebar hidden | Pending: route protection | +| Optimization not improving | Content already good | Check original score | +| High credit usage | Large content | Optimize sections | +| Changes not saving | Apply not clicked | Click "Apply Changes" | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| Route-level protection | 🔜 Pending | Block access when module disabled | +| Dashboard card hiding | 🔜 Pending | Hide from dashboard when disabled | +| Automation integration | 🔜 Planned | Add to automation pipeline | +| Partial optimization | 🔜 Planned | Optimize specific sections only | +| Competitor analysis | 🔜 Planned | Compare against top-ranking content | +| A/B testing | 🔜 Planned | Track performance of optimizations | diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/PLANNER.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/PLANNER.md new file mode 100644 index 00000000..43beb36f --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/PLANNER.md @@ -0,0 +1,232 @@ +# Planner Module + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Status:** ✅ Active +**Backend Path:** `backend/igny8_core/modules/planner/` +**Frontend Path:** `frontend/src/pages/Planner/` + +--- + +## Quick Reference + +| What | File | Key Items | +|------|------|-----------| +| Models | `modules/planner/models.py` | `Keywords`, `Clusters`, `ContentIdeas` | +| Views | `modules/planner/views.py` | `KeywordViewSet`, `ClusterViewSet`, `ContentIdeaViewSet` | +| Serializers | `modules/planner/serializers.py` | Keyword/Cluster/Idea serializers | +| AI Functions | `ai/functions/clustering.py` | `AutoClusterFunction` | +| AI Functions | `ai/functions/ideas.py` | `GenerateIdeasFunction` | +| Frontend Pages | `pages/Planner/Keywords.tsx` | Keyword management | +| Frontend Pages | `pages/Planner/Clusters.tsx` | Cluster management | +| Frontend Pages | `pages/Planner/Ideas.tsx` | Content ideas | + +--- + +## Purpose + +The Planner module manages the SEO content planning pipeline: + +``` +SeedKeywords (Global) → Keywords (Site/Sector) → Clusters → ContentIdeas → Tasks +``` + +--- + +## Data Models + +### Keywords + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Parent site | +| sector | FK | Parent sector | +| seed_keyword | FK | Reference to global SeedKeyword | +| keyword | CharField | Keyword text | +| search_volume | Integer | Monthly search volume | +| difficulty | Integer | SEO difficulty (0-100) | +| cpc | Decimal | Cost per click | +| search_intent | CharField | informational/commercial/transactional/navigational | +| status | CharField | new/mapped/used | +| cluster | FK | Assigned cluster (nullable) | +| created_at | DateTime | Creation date | + +### Clusters + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Parent site | +| sector | FK | Parent sector | +| name | CharField | Cluster name | +| description | TextField | Cluster description | +| primary_keyword | FK | Main keyword | +| status | CharField | draft/active/complete | +| keyword_count | Integer | Number of keywords | +| created_at | DateTime | Creation date | + +### ContentIdeas + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Parent site | +| sector | FK | Parent sector | +| cluster | FK | Source cluster | +| title | CharField | Content title | +| description | TextField | Content brief | +| target_keywords | JSON | Keywords to target | +| content_type | CharField | blog_post/guide/comparison/etc. | +| word_count_target | Integer | Target word count | +| status | CharField | draft/queued/used | +| priority | Integer | Priority score | +| created_at | DateTime | Creation date | + +--- + +## API Endpoints + +### Keywords + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/planner/keywords/` | `KeywordViewSet.list` | List keywords with filtering | +| POST | `/api/v1/planner/keywords/` | `KeywordViewSet.create` | Create single keyword | +| GET | `/api/v1/planner/keywords/{id}/` | `KeywordViewSet.retrieve` | Get keyword detail | +| PUT | `/api/v1/planner/keywords/{id}/` | `KeywordViewSet.update` | Update keyword | +| DELETE | `/api/v1/planner/keywords/{id}/` | `KeywordViewSet.destroy` | Soft delete keyword | +| POST | `/api/v1/planner/keywords/bulk_delete/` | `KeywordViewSet.bulk_delete` | Hard delete multiple | +| POST | `/api/v1/planner/keywords/bulk_status/` | `KeywordViewSet.bulk_status` | Update status for multiple | +| POST | `/api/v1/planner/keywords/add_to_workflow/` | `KeywordViewSet.add_to_workflow` | Add SeedKeywords to workflow | + +**Filters:** `?site_id=`, `?sector_id=`, `?status=`, `?cluster_id=`, `?difficulty_min=`, `?difficulty_max=`, `?volume_min=`, `?volume_max=` + +### Clusters + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/planner/clusters/` | `ClusterViewSet.list` | List clusters | +| POST | `/api/v1/planner/clusters/` | `ClusterViewSet.create` | Create cluster manually | +| POST | `/api/v1/planner/clusters/auto_cluster/` | `ClusterViewSet.auto_cluster` | AI-powered clustering | +| POST | `/api/v1/planner/clusters/generate_ideas/` | `ClusterViewSet.generate_ideas` | Generate ideas from clusters | + +### Content Ideas + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/planner/ideas/` | `ContentIdeaViewSet.list` | List ideas | +| POST | `/api/v1/planner/ideas/` | `ContentIdeaViewSet.create` | Create idea manually | +| POST | `/api/v1/planner/ideas/create_tasks/` | `ContentIdeaViewSet.create_tasks` | Convert ideas to tasks | + +--- + +## Business Logic + +### Auto Clustering (AI) + +**Trigger:** User clicks "Auto Cluster" button +**AI Function:** `AutoClusterFunction` +**Credit Cost:** Based on AI tokens used (see AIModelConfig) + +**Flow:** +1. User selects keywords (or all unclustered) +2. Frontend calls `POST /clusters/auto_cluster/` +3. Backend validates minimum 5 keywords +4. AIEngine executes `AutoClusterFunction`: + - Sends keywords to GPT-4 + - AI groups by semantic similarity + - Returns cluster assignments +5. Creates/updates `Clusters` records +6. Assigns keywords to clusters +7. Returns created clusters + +### Generate Ideas (AI) + +**Trigger:** User clicks "Generate Ideas" on cluster(s) +**AI Function:** `GenerateIdeasFunction` +**Credit Cost:** Based on AI tokens used (see AIModelConfig) + +**Flow:** +1. User selects clusters +2. Frontend calls `POST /clusters/generate_ideas/` +3. Backend validates clusters have keywords +4. AIEngine executes `GenerateIdeasFunction`: + - Analyzes cluster keywords + - Generates content titles + briefs + - Suggests word counts and content types +5. Creates `ContentIdeas` records +6. Returns created ideas + +### Add Keywords to Workflow + +**Trigger:** User selects SeedKeywords in setup +**Credit Cost:** None + +**Flow:** +1. User browses global SeedKeywords +2. Selects keywords to add to their sector +3. Frontend calls `POST /keywords/add_to_workflow/` +4. Backend creates `Keywords` records linked to SeedKeywords +5. Keywords appear in Planner for clustering + +--- + +## Frontend Pages + +### Keywords Page (`/planner/keywords`) + +- Table of all keywords with filtering +- Bulk actions: delete, update status +- Add keywords from SeedKeyword library +- Import keywords from CSV +- Assign to clusters manually + +### Clusters Page (`/planner/clusters`) + +- Grid/list of clusters +- Auto-cluster action (AI) +- Generate ideas action (AI) +- View keywords in cluster +- Cluster status management + +### Ideas Page (`/planner/ideas`) + +- Table of content ideas +- Convert to tasks action +- Edit idea details +- Priority management + +--- + +## Integration Points + +| From | To | Trigger | +|------|----|---------| +| SeedKeywords | Keywords | Add to workflow | +| Keywords | Clusters | Auto clustering | +| Clusters | ContentIdeas | Generate ideas | +| ContentIdeas | Tasks | Create tasks | +| Automation Stage 1 | Clusters | Automated clustering | +| Automation Stage 2 | ContentIdeas | Automated idea generation | + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| Clustering fails | Less than 5 keywords | Ensure minimum keywords | +| Ideas not generating | Cluster has no keywords | Assign keywords to cluster | +| Keywords not showing | Wrong site/sector filter | Check active site/sector | +| Duplicate keywords | Same keyword added twice | Check seed_keyword reference | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| Keyword import improvements | 🔜 Planned | Better CSV parsing and validation | +| Cluster merging | 🔜 Planned | Merge similar clusters | +| Idea prioritization | 🔜 Planned | AI-based priority scoring | diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/PUBLISHER.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/PUBLISHER.md new file mode 100644 index 00000000..f82c6e4c --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/PUBLISHER.md @@ -0,0 +1,536 @@ +# Publisher Module + +**Last Verified:** January 20, 2026 +**Status:** ✅ Active +**Version:** 1.8.4 +**Backend Path:** `backend/igny8_core/modules/publisher/` + `backend/igny8_core/business/publishing/` +**Frontend Path:** `frontend/src/pages/Publisher/` + +--- + +## Quick Reference + +| What | File | Key Items | +|------|------|-----------| +| Views | `modules/publisher/views.py` | `PublishingRecordViewSet`, `DeploymentViewSet`, `PublishContentViewSet` | +| Models | `business/publishing/models.py` | `PublishingRecord`, `DeploymentRecord` | +| Integration Models | `modules/integration/models.py` | `PublishingSettings` | +| **Unified Settings** | `modules/integration/views/unified_settings.py` | **v1.8.0** Consolidated settings API | +| Services | `business/publishing/services/*.py` | Publishing orchestration | +| Scheduler Tasks | `igny8_core/tasks/publishing_scheduler.py` | Celery beat tasks | +| URLs | `modules/publisher/urls.py` | Publisher endpoints | +| Frontend | `pages/Publisher/ContentCalendar.tsx` | Content calendar view | +| **Site Settings** | `pages/Sites/AIAutomationSettings.tsx` | **v1.8.0** Unified settings UI | + +--- + +## Purpose + +The Publisher module manages: +- Content publishing pipeline +- **Publishing scheduler (automated publishing)** +- Publishing record tracking +- Deployment management +- Multi-destination publishing +- **Content calendar visualization** + +**Settings Location (v1.8.0):** Site Settings → Automation tab + +> ⚠️ **v1.8.0 Change:** The standalone `/publisher/settings` page has been removed. Publishing settings are now configured in Site Settings → Automation tab under "Capacity" and "Schedule" sections. + +--- + +## Data Models + +### PublishingRecord + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Parent site | +| content | FK | Source content | +| destination | CharField | wordpress/ghost/webflow | +| external_id | CharField | ID on destination platform | +| external_url | URLField | Published URL | +| status | CharField | pending/published/failed/retracted | +| published_at | DateTime | Publication time | +| metadata | JSON | Additional data | +| created_at | DateTime | Record creation | + +### DeploymentRecord + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Target site | +| deployment_type | CharField | full/incremental | +| status | CharField | pending/deploying/completed/failed | +| items_deployed | Integer | Number of items | +| started_at | DateTime | Start time | +| completed_at | DateTime | Completion time | +| error_log | TextField | Errors encountered | +| metadata | JSON | Deployment details | + +### PublishingSettings (v1.3.2, updated v1.8.0) + +Site-level publishing configuration: + +| Field | Type | Purpose | +|-------|------|---------| +| site | OneToOne | Parent site (unique) | +| auto_approval_enabled | Boolean | Auto-approve content | +| auto_publish_enabled | Boolean | Auto-publish approved content | +| daily_publish_limit | Integer | Max publications per day | +| weekly_publish_limit | Integer | Max publications per week | +| monthly_publish_limit | Integer | Max publications per month | +| publish_days | JSON | Days of week for publishing ["mon","wed","fri"] | +| publish_time_slots | JSON | Time slots for publishing [{"start":"09:00","end":"17:00"}] | +| **total_items_per_run** | Integer | **v1.8.0** Computed capacity display | + +### Content Site Status Fields (v1.3.2) + +Added to Content model for scheduling: + +| Field | Type | Values | +|-------|------|--------| +| site_status | CharField | not_published, scheduled, publishing, published, failed | +| scheduled_publish_at | DateTime | Future publication time (nullable) | +| site_status_updated_at | DateTime | Last status change timestamp | + +--- + +## API Endpoints + +### Unified Settings API (v1.8.0) + +| Method | Path | Purpose | +|--------|------|---------| +| **GET** | `/api/v1/integration/sites/{site_id}/unified-settings/` | Get all automation + publishing settings | +| **PATCH** | `/api/v1/integration/sites/{site_id}/unified-settings/` | Update settings | + +### Publishing & Records + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/publisher/records/` | `PublishingRecordViewSet.list` | List publishing records | +| POST | `/api/v1/publisher/records/` | `PublishingRecordViewSet.create` | Create record | +| GET | `/api/v1/publisher/deployments/` | `DeploymentViewSet.list` | List deployments | +| POST | `/api/v1/publisher/publish/` | `PublishContentViewSet.publish` | Publish content immediately | +| GET | `/api/v1/publisher/publish/status/` | `PublishContentViewSet.status` | Get publishing status | +| GET | `/api/v1/publisher/site-definition/` | `SiteDefinitionViewSet.list` | Public site definitions | + +### Scheduling Endpoints (v1.3.2+) + +| Method | Path | Purpose | Request Body | Response | +|--------|------|---------|--------------|----------| +| **POST** | `/api/v1/writer/content/{id}/schedule/` | Schedule content for future publishing | `{ "scheduled_publish_at": "2025-01-20T09:00:00Z" }` | `{ "success": true, "scheduled_publish_at": "2025-01-20T09:00:00Z" }` | +| **POST** | `/api/v1/writer/content/{id}/reschedule/` | Reschedule existing scheduled content | `{ "scheduled_at": "2025-01-21T10:00:00Z" }` | `{ "success": true, "scheduled_publish_at": "2025-01-21T10:00:00Z" }` | +| **POST** | `/api/v1/writer/content/{id}/unschedule/` | Cancel scheduled publishing | `{}` | `{ "success": true, "message": "Content unscheduled" }` | +| **POST** | `/api/v1/writer/content/bulk_schedule/` | Bulk schedule with site defaults | `{ "content_ids": [1,2,3], "use_site_defaults": true, "site_id": 5 }` | `{ "success": true, "scheduled_count": 3, "schedule_preview": [...] }` | +| **POST** | `/api/v1/writer/content/bulk_schedule_preview/` | Preview bulk schedule times | `{ "content_ids": [1,2,3], "site_id": 5 }` | `{ "schedule_preview": [...], "site_settings": {...} }` | + +### Legacy Publishing Settings (deprecated) + +> ⚠️ **Deprecated in v1.8.0:** Use unified-settings API instead + +| Method | Path | Purpose | +|--------|------|---------| +| ~~GET~~ | ~~`/api/v1/sites/{site_id}/settings?tab=publishing`~~ | ~~Get site publishing settings~~ | +| ~~PUT~~ | ~~`/api/v1/sites/{site_id}/publishing-settings/`~~ | ~~Update publishing settings~~ | + +--- + +## API Usage Examples + +### Publish Content Immediately + +**Request:** +```bash +POST /api/v1/publisher/publish/ +Content-Type: application/json + +{ + "content_id": 123, + "destinations": ["wordpress"] # or ["shopify"], ["custom"] +} +``` + +**Success Response:** +```json +{ + "success": true, + "data": { + "success": true, + "results": [ + { + "destination": "wordpress", + "success": true, + "external_id": "456", + "url": "https://mysite.com/article-title/", + "publishing_record_id": 789, + "platform_type": "wordpress" + } + ] + } +} +``` + +**Error Response:** +```json +{ + "success": false, + "error": "Publishing API error: Invalid credentials" +} +``` + +### Schedule Content for Future Publishing + +**Request:** +```bash +POST /api/v1/writer/content/123/schedule/ +Content-Type: application/json + +{ + "scheduled_publish_at": "2025-01-20T09:00:00Z" +} +``` + +**Response:** +```json +{ + "success": true, + "scheduled_publish_at": "2025-01-20T09:00:00Z", + "site_status": "scheduled" +} +``` + +**Notes:** +- Content `site_status` changes from `not_published` → `scheduled` +- Celery task `process_scheduled_publications` will publish at scheduled time +- Runs every 5 minutes, so publishing happens within 5 min of scheduled time + +### Reschedule Content + +**Request:** +```bash +POST /api/v1/writer/content/123/reschedule/ +Content-Type: application/json + +{ + "scheduled_at": "2025-01-21T10:00:00Z" +} +``` + +**Response:** +```json +{ + "success": true, + "scheduled_publish_at": "2025-01-21T10:00:00Z", + "site_status": "scheduled" +} +``` + +**Use Cases:** +- Reschedule from `site_status='scheduled'` (change time) +- Reschedule from `site_status='failed'` (retry at new time) + +### Unschedule Content + +**Request:** +```bash +POST /api/v1/writer/content/123/unschedule/ +Content-Type: application/json + +{} +``` + +**Response:** +```json +{ + "success": true, + "message": "Content unscheduled successfully", + "site_status": "not_published" +} +``` + +**Notes:** +- Removes content from publishing queue +- Content returns to `site_status='not_published'` +- Can be rescheduled or published immediately later + +### Bulk Schedule with Site Defaults + +**Request:** +```bash +POST /api/v1/writer/content/bulk_schedule/ +Content-Type: application/json + +{ + "content_ids": [123, 124, 125, 126], + "use_site_defaults": true, + "site_id": 45 +} +``` + +**Response:** +```json +{ + "success": true, + "scheduled_count": 4, + "schedule_preview": [ + { + "content_id": 123, + "scheduled_at": "2025-01-17T09:00:00Z", + "title": "First Article" + }, + { + "content_id": 124, + "scheduled_at": "2025-01-17T09:15:00Z", + "title": "Second Article" + }, + { + "content_id": 125, + "scheduled_at": "2025-01-17T09:30:00Z", + "title": "Third Article" + }, + { + "content_id": 126, + "scheduled_at": "2025-01-17T09:45:00Z", + "title": "Fourth Article" + } + ], + "site_settings": { + "base_time": "09:00 AM", + "stagger_interval": 15, + "timezone": "America/New_York" + } +} +``` + +**Notes:** +- Uses site's default publishing schedule from Site Settings +- Automatically staggers publications (e.g., 15 min intervals) +- No limit on number of items (unlike direct publish which is limited to 5) +- All items set to `site_status='scheduled'` + +### Bulk Schedule Preview (Before Confirming) + +**Request:** +```bash +POST /api/v1/writer/content/bulk_schedule_preview/ +Content-Type: application/json + +{ + "content_ids": [123, 124, 125], + "site_id": 45 +} +``` + +**Response:** +```json +{ + "schedule_preview": [ + {"content_id": 123, "scheduled_at": "2025-01-17T09:00:00Z", "title": "Article 1"}, + {"content_id": 124, "scheduled_at": "2025-01-17T09:15:00Z", "title": "Article 2"}, + {"content_id": 125, "scheduled_at": "2025-01-17T09:30:00Z", "title": "Article 3"} + ], + "site_settings": { + "base_time": "09:00 AM", + "stagger_interval": 15, + "timezone": "America/New_York", + "publish_days": ["mon", "tue", "wed", "thu", "fri"] + } +} +``` + +**Use Case:** +- Show user what times items will be scheduled before confirming +- Allow user to adjust site settings if needed +- User clicks "Confirm" to execute actual bulk_schedule + +--- + +## Publishing Scheduler (v1.3.2) + +### Celery Beat Tasks + +Located in `igny8_core/tasks/publishing_scheduler.py`: + +| Task | Schedule | Purpose | +|------|----------|---------| +| `schedule_approved_content` | Every 15 minutes | Assigns publish times to approved content | +| `process_scheduled_publications` | Every 5 minutes | Publishes content when scheduled time arrives | +| `cleanup_failed_publications` | Daily at midnight | Retries or cleans up failed publications | + +### Scheduling Flow + +``` +Approved Content → schedule_approved_content (every 15 min) + ↓ + Check PublishingSettings + ↓ + Assign scheduled_publish_at based on: + - publish_days configuration + - publish_time_slots configuration + - daily/weekly/monthly limits + ↓ + Set site_status = "scheduled" + ↓ +process_scheduled_publications (every 5 min) + ↓ + If scheduled_publish_at <= now: + - Set site_status = "publishing" + - Execute publication + - Set site_status = "published" or "failed" +``` + +### Site Status State Machine + +``` +not_published → scheduled → publishing → published + ↓ ↓ + ↓ → failed + ↓ + not_published (if unscheduled) +``` + +--- + +## Frontend Pages (v1.3.2) + +### Content Calendar (`/publisher/content-calendar`) + +**Purpose:** Visualize and manage scheduled content + +**Features:** +- Calendar view of scheduled publications +- List view alternative +- Filter by site +- Schedule/unschedule actions +- Drag-and-drop rescheduling (planned) + +**Components:** +- `ContentCalendar.tsx` - Main page component +- `CalendarItemTooltip` - Hover details for calendar items +- `SiteInfoBar` - Site context header + +### Publishing Queue (`/publisher/publishing-queue`) + +**Purpose:** Review upcoming publications + +**Features:** +- List of content pending publication +- Status indicators (scheduled, publishing, failed) +- Publish now / unschedule actions + +--- + +## Publishing Flow + +### Single Content Publish + +**Trigger:** User clicks "Publish" or API call +**Flow:** +1. Validate content is in publishable state +2. Get site integration credentials +3. Transform content for destination: + - Format HTML for platform + - Process images + - Map taxonomies +4. Push to destination API +5. Create `PublishingRecord` with external ID +6. Update Content status to `published` + +### Batch Deployment + +**Trigger:** Deployment action +**Flow:** +1. Create `DeploymentRecord` +2. Gather all pending content +3. Process each item: + - Publish to destination + - Create publishing record + - Update content status +4. Update deployment status +5. Log any errors + +--- + +## Destination Adapters + +### WordPress Adapter + +- Uses WordPress REST API +- Supports posts, pages, custom post types +- Handles media upload +- Maps categories/tags + +### Ghost Adapter (Planned) + +- Ghost Admin API integration +- Post publishing +- Image handling + +### Webflow Adapter (Planned) + +- Webflow CMS API +- Collection item publishing +- Asset management + +--- + +## Publishing States + +| Status | Description | +|--------|-------------| +| pending | Ready to publish | +| published | Successfully published | +| failed | Publishing failed | +| retracted | Unpublished/removed | + +--- + +## Site Definition Endpoint + +**Purpose:** Public endpoint for headless CMS use cases + +Returns site structure for external consumption: +- Site metadata +- Available taxonomies +- Content types +- URL structure + +--- + +## Integration Points + +| From | To | Trigger | +|------|----|---------| +| Writer | Publisher | Publish action | +| Automation Stage 7 | Publisher | Auto-publish (future) | +| Publisher | Integrations | Destination APIs | +| Publisher | Content | Status updates | + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| Publish failed | Invalid credentials | Check integration settings | +| Duplicate posts | Published twice | Check existing publishing record | +| Images missing | Upload failed | Check media library access | +| Wrong category | Mapping issue | Verify taxonomy sync | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| Ghost integration | 🔜 Planned | Ghost CMS publishing | +| Webflow integration | 🔜 Planned | Webflow publishing | +| ~~Scheduled publishing~~ | ✅ Implemented (v1.3.2) | Future-date publishing | +| Republish detection | 🔜 Planned | Detect and handle updates | +| ~~Publishing queue~~ | ✅ Implemented (v1.3.2) | Batch publishing with queue | +| Drag-and-drop calendar | 🔜 Planned | Reschedule via drag-and-drop | diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/SYSTEM-SETTINGS.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/SYSTEM-SETTINGS.md new file mode 100644 index 00000000..d764240c --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/SYSTEM-SETTINGS.md @@ -0,0 +1,293 @@ +# System Settings Module + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Status:** ✅ Active +**Backend Path:** `backend/igny8_core/modules/system/` +**Frontend Path:** `frontend/src/pages/Settings/` + +> **Note (v1.8.0):** AI & Automation settings have been consolidated into Site Settings → Automation tab. See [AUTOMATION.md](AUTOMATION.md) for the unified settings API. + +--- + +## Quick Reference + +| What | File | Key Items | +|------|------|-----------| +| Global Models | `modules/system/global_settings_models.py` | `GlobalIntegrationSettings`, `GlobalAIPrompt`, `GlobalAuthorProfile` | +| Account Models | `modules/system/settings_models.py` | `SystemSettings`, `UserSettings` | +| Email Models | `modules/system/email_models.py` | `EmailSettings`, `EmailTemplate`, `EmailLog` | +| AI Settings | `modules/system/ai_settings.py` | `SystemAISettings` | +| Provider Model | `modules/system/models.py` | `IntegrationProvider` | +| Views | `modules/system/settings_views.py` | Settings ViewSets | +| Integration Views | `modules/system/integration_views.py` | AI integration settings | +| **Unified Settings** | `api/unified_settings.py` | **v1.8.0** Site-level consolidated settings | +| Frontend | `pages/Settings/*.tsx` | Settings pages | + +--- + +## Purpose + +The System Settings module manages: +- Platform-wide global settings (API keys, defaults) +- Per-account settings overrides +- AI prompts and configurations +- Module enable/disable +- Author profiles and content strategies + +--- + +## Settings Hierarchy + +``` +Global Settings (Platform-wide) + ↓ +Account Settings (Per-account overrides) + ↓ +User Settings (Per-user preferences) +``` + +**Priority:** User > Account > Global + +--- + +## Global Settings Models + +### GlobalIntegrationSettings (Singleton) + +**Admin:** `/admin/system/globalintegrationsettings/` +**Purpose:** Platform-wide API keys and defaults + +| Field | Type | Purpose | +|-------|------|---------| +| openai_api_key | CharField | OpenAI API key (all accounts) | +| openai_model | CharField | Default model (gpt-4o-mini) | +| openai_temperature | Float | Default temperature (0.7) | +| openai_max_tokens | Integer | Default max tokens (8192) | +| dalle_api_key | CharField | DALL-E API key | +| dalle_model | CharField | Default model (dall-e-3) | +| dalle_size | CharField | Default size (1024x1024) | +| dalle_quality | CharField | Default quality (standard) | +| dalle_style | CharField | Default style (vivid) | +| anthropic_api_key | CharField | Anthropic API key | +| runware_api_key | CharField | Runware API key | + +**Critical:** This is a singleton (only 1 record, pk=1). All accounts use these API keys. + +### GlobalAIPrompt + +**Admin:** `/admin/system/globalaiprompt/` +**Purpose:** Default AI prompt templates + +| Field | Type | Purpose | +|-------|------|---------| +| prompt_type | CharField | clustering/ideas/content_generation/etc. | +| prompt_value | TextField | The actual prompt text | +| description | TextField | What this prompt does | +| variables | JSON | Available variables ({keyword}, {industry}) | +| version | Integer | Prompt version | +| is_active | Boolean | Enable/disable | + +### GlobalAuthorProfile + +**Admin:** `/admin/system/globalauthorprofile/` +**Purpose:** Default author persona templates + +| Field | Type | Purpose | +|-------|------|---------| +| name | CharField | Profile name | +| description | TextField | Description | +| tone | CharField | professional/casual/technical | +| language | CharField | en/es/fr | +| structure_template | JSON | Content structure config | +| category | CharField | saas/ecommerce/blog/technical | +| is_active | Boolean | Enable/disable | + +--- + +## Account Settings Models + +### IntegrationSettings + +**Purpose:** Per-account AI model overrides (NOT API keys) + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| integration_type | CharField | openai/runware/image_generation | +| config | JSON | Model, temperature, max_tokens overrides | +| is_active | Boolean | Enable/disable | + +**Important:** +- Free plan cannot create overrides +- Starter/Growth/Scale can override model/settings +- API keys ALWAYS come from GlobalIntegrationSettings + +### ModuleEnableSettings + +**Purpose:** Enable/disable modules per account + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| planner_enabled | Boolean | Enable Planner | +| writer_enabled | Boolean | Enable Writer | +| thinker_enabled | Boolean | Enable Thinker (AI settings) | +| automation_enabled | Boolean | Enable Automation | +| site_builder_enabled | Boolean | Enable Site Builder | +| linker_enabled | Boolean | Enable Linker | +| optimizer_enabled | Boolean | Enable Optimizer | +| publisher_enabled | Boolean | Enable Publisher | + +**Current Implementation:** +- Controls sidebar navigation visibility +- ⚠️ **Pending:** Extend to other pages and references + +### AIPrompt (Account-Level) + +**Purpose:** Per-account prompt customizations + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| prompt_type | CharField | Prompt type | +| prompt_value | TextField | Current prompt (custom or default) | +| default_prompt | TextField | Original default (for reset) | +| is_customized | Boolean | True if user modified | + +--- + +## API Endpoints + +### Integration Settings + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/system/settings/integrations/openai/` | Get OpenAI settings | Get current model/params | +| PUT | `/api/v1/system/settings/integrations/openai/` | Save OpenAI settings | Save overrides | +| GET | `/api/v1/system/settings/integrations/image_generation/` | Get image settings | Get DALL-E/Runware settings | +| PUT | `/api/v1/system/settings/integrations/image_generation/` | Save image settings | Save overrides | +| POST | `/api/v1/system/settings/integrations/test/` | Test connection | Test API connectivity | + +### Prompts + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/system/prompts/` | List prompts | Get all prompts | +| GET | `/api/v1/system/prompts/{type}/` | Get prompt | Get specific prompt | +| PUT | `/api/v1/system/prompts/{type}/` | Save prompt | Save customization | +| POST | `/api/v1/system/prompts/{type}/reset/` | Reset prompt | Reset to default | + +### Module Settings + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/system/modules/` | Get module settings | Get enable/disable state | +| PUT | `/api/v1/system/modules/` | Save module settings | Update enabled modules | + +--- + +## Settings Flow (Frontend → Backend) + +### Getting OpenAI Settings + +1. Frontend requests: `GET /system/settings/integrations/openai/` +2. Backend checks account's `IntegrationSettings` +3. Gets global defaults from `GlobalIntegrationSettings` +4. Merges: account overrides > global defaults +5. Returns (NEVER includes API keys): +```json +{ + "model": "gpt-4o-mini", + "temperature": 0.7, + "max_tokens": 8192, + "using_global": true +} +``` + +### Saving OpenAI Settings + +1. Frontend sends: `PUT /system/settings/integrations/openai/` +2. Backend STRIPS any API key fields (security) +3. Validates account plan allows overrides +4. Saves to `IntegrationSettings.config` +5. Returns updated settings + +--- + +## Module Enable/Disable + +### How It Works (Current) + +1. On app load, frontend fetches module settings +2. `useModuleStore.isModuleEnabled(name)` checks state +3. `AppSidebar.tsx` conditionally renders menu items: + +```typescript +if (isModuleEnabled('linker')) { + workflowItems.push({ + name: "Linker", + path: "/linker/content", + }); +} +``` + +### Current Limitations (⚠️ Pending Implementation) + +- Only hides sidebar menu items +- Direct URL access still works +- Other page references still show module links +- Dashboard cards may still show disabled modules + +### Required Extension + +Need to add `ModuleGuard` component to: +- Route-level protection +- Dashboard cards/widgets +- Cross-module references +- Settings page links + +--- + +## Frontend Pages + +### AI Settings (`/settings/ai`) + +- OpenAI model selection +- Temperature and max tokens +- Image generation settings +- Test connection button + +### Prompts (`/thinker/prompts`) + +- List all prompt types +- Edit prompt text +- Reset to default +- Variable reference + +### Module Settings (Admin Only) + +- Enable/disable modules +- Per-account configuration + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| Settings not saving | Plan restriction | Upgrade plan | +| API key exposed | Security flaw | Should never happen - check code | +| Module still visible | Cache stale | Clear cache, reload | +| Prompt reset not working | default_prompt missing | Re-run migration | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| Module guard extension | 🔜 Pending | Extend disable to all pages, not just sidebar | +| AIModelConfig database | 🔜 Planned | Move model pricing to database | +| Strategy templates | 🔜 Planned | Global strategy library | +| Per-user preferences | 🔜 Planned | User-level setting overrides | diff --git a/v2/Live Docs on Server/igny8-app-docs/10-MODULES/WRITER.md b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/WRITER.md new file mode 100644 index 00000000..0537c284 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/10-MODULES/WRITER.md @@ -0,0 +1,295 @@ +# Writer Module + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Status:** ✅ Active +**Backend Path:** `backend/igny8_core/modules/writer/` +**Frontend Path:** `frontend/src/pages/Writer/` + +--- + +## Quick Reference + +| What | File | Key Items | +|------|------|-----------| +| Models | `modules/writer/models.py` | `Tasks`, `Content`, `Images`, `ContentTaxonomy` | +| Views | `modules/writer/views.py` | `TaskViewSet`, `ContentViewSet`, `ImageViewSet` | +| AI Functions | `ai/functions/content.py` | `GenerateContentFunction` | +| AI Functions | `ai/functions/images.py` | `GenerateImagesFunction`, `GenerateImagePromptsFunction` | +| Frontend Pages | `pages/Writer/Tasks.tsx` | Task management | +| Frontend Pages | `pages/Writer/Content.tsx` | Content listing | +| Frontend Pages | `pages/Writer/ContentViewer.tsx` | Content preview/edit | + +--- + +## Purpose + +The Writer module manages the content creation pipeline: + +``` +ContentIdeas → Tasks → Content → Images → Review → Publish +``` + +--- + +## Data Models + +### Tasks + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Parent site | +| sector | FK | Parent sector | +| content_idea | FK | Source idea (nullable) | +| title | CharField | Task/content title | +| description | TextField | Task brief | +| target_keywords | JSON | Keywords to target | +| content_type | CharField | blog_post/guide/comparison/etc. | +| word_count_target | Integer | Target word count | +| status | CharField | pending/in_progress/completed/cancelled | +| assigned_to | FK | Assigned user (nullable) | +| due_date | DateTime | Due date (nullable) | +| priority | Integer | Priority level | +| created_at | DateTime | Creation date | + +### Content + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Parent site | +| sector | FK | Parent sector | +| task | FK | Source task (nullable) | +| title | CharField | Content title | +| slug | SlugField | URL slug | +| content_body | TextField | HTML content | +| excerpt | TextField | Short summary | +| meta_title | CharField | SEO meta title | +| meta_description | CharField | SEO meta description | +| word_count | Integer | Actual word count | +| status | CharField | draft/review/approved/published | +| content_type | CharField | post/page/product | +| content_structure | CharField | article/guide/comparison/review/listicle | +| source | CharField | igny8/wordpress/manual | +| wordpress_id | Integer | WP post ID (if synced) | +| published_at | DateTime | Publication date | +| created_at | DateTime | Creation date | + +### Images + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Parent site | +| sector | FK | Parent sector | +| content | FK | Parent content | +| image_type | CharField | featured/desktop/mobile/in_article | +| prompt | TextField | Generation prompt | +| image_url | URLField | Image URL | +| alt_text | CharField | Alt text for SEO | +| status | CharField | pending/generating/completed/failed | +| position | Integer | Order for in-article images | +| provider | CharField | dalle/runware | +| model | CharField | dall-e-3/runware:97@1 | +| created_at | DateTime | Creation date | + +### ContentTaxonomy + +| Field | Type | Purpose | +|-------|------|---------| +| account | FK | Owner account | +| site | FK | Parent site | +| name | CharField | Category/tag name | +| slug | SlugField | URL slug | +| taxonomy_type | CharField | category/tag | +| parent | FK | Parent taxonomy (for hierarchy) | +| description | TextField | Description | +| wordpress_id | Integer | WP term ID (if synced) | + +--- + +## API Endpoints + +### Tasks + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/writer/tasks/` | `TaskViewSet.list` | List tasks | +| POST | `/api/v1/writer/tasks/` | `TaskViewSet.create` | Create task | +| POST | `/api/v1/writer/tasks/bulk_create/` | `TaskViewSet.bulk_create` | Create multiple tasks | +| POST | `/api/v1/writer/tasks/{id}/generate_content/` | `TaskViewSet.generate_content` | AI content generation | + +### Content + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/writer/content/` | `ContentViewSet.list` | List content | +| POST | `/api/v1/writer/content/` | `ContentViewSet.create` | Create content manually | +| PUT | `/api/v1/writer/content/{id}/` | `ContentViewSet.update` | Update content | +| POST | `/api/v1/writer/content/{id}/update_content/` | `ContentViewSet.update_content` | Update with validation | +| POST | `/api/v1/writer/content/{id}/generate_images/` | `ContentViewSet.generate_images` | Generate images | +| POST | `/api/v1/writer/content/{id}/publish_to_wordpress/` | `ContentViewSet.publish_to_wordpress` | Publish to WP | + +### Images + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/api/v1/writer/images/` | `ImageViewSet.list` | List images | +| POST | `/api/v1/writer/images/generate_for_content/` | `ImageViewSet.generate_for_content` | Generate images | +| POST | `/api/v1/writer/images/regenerate/` | `ImageViewSet.regenerate` | Regenerate image | + +--- + +## Business Logic + +### Content Generation (AI) + +**Trigger:** User clicks "Generate" on task +**AI Function:** `GenerateContentFunction` +**Credit Cost:** Based on AI tokens used (see AIModelConfig) + +**Flow:** +1. User has task with title, keywords, word count target +2. Frontend calls `POST /tasks/{id}/generate_content/` +3. Backend validates task and credits +4. AIEngine executes `GenerateContentFunction`: + - Loads account's AI prompts and strategy + - Sends to GPT-4 with structured output + - Receives HTML content with proper structure +5. Creates `Content` record linked to task +6. Updates task status to `completed` +7. Returns content for review + +### Image Prompt Generation (AI) + +**Trigger:** Part of content generation or explicit +**AI Function:** `GenerateImagePromptsFunction` +**Credit Cost:** Based on AI tokens used (see AIModelConfig) + +**Flow:** +1. Content exists with body +2. AI analyzes content sections +3. Generates prompts for: + - Featured image (1) + - In-article images (configurable count) +4. Creates `Images` records with prompts, status=pending + +### Image Generation (AI) + +**Trigger:** User clicks "Generate Images" or automation +**AI Function:** `GenerateImagesFunction` +**Credit Cost:** Deducted per image (see AIModelConfig.credits_per_image) + +**Flow:** +1. Image record exists with prompt, status=pending +2. Backend calls DALL-E or Runware API +3. Receives image URL +4. Updates `Images` record with URL, status=completed + +### WordPress Publishing + +**Trigger:** User clicks "Publish to WordPress" +**Credit Cost:** None + +**Flow:** +1. Content is in `approved` status +2. Site has WordPress integration configured +3. Backend calls WordPress REST API: + - Creates/updates post + - Uploads featured image + - Sets categories/tags +4. Updates Content with `wordpress_id` +5. Sets status to `published` + +--- + +## Content Structures + +| Structure | Purpose | Typical Sections | +|-----------|---------|------------------| +| article | General blog post | Intro, Body, Conclusion | +| guide | How-to content | Steps, Tips, Summary | +| comparison | Product comparison | Features, Pros/Cons, Verdict | +| review | Product review | Overview, Features, Rating | +| listicle | List-based content | Numbered items with details | +| pillar | Long-form authority | Multiple sections with depth | + +--- + +## Frontend Pages + +### Tasks Page (`/writer/tasks`) + +- Table of all tasks +- Filter by status, assigned user +- Generate content action +- Bulk actions + +### Content Page (`/writer/content`) + +- Table of all content +- Filter by status, content type +- Quick preview +- Publish actions + +### Content Viewer (`/writer/content/{id}`) + +- Full content preview +- Edit mode +- Image management +- Publish to WordPress +- Status management + +### Draft/Review/Approved Tabs + +- Filtered views by status +- Different actions per status +- **v1.2.0**: "Published" tab renamed to "Approved" + +--- + +## Content Status Flow + +``` +draft → review → approved → published + ↓ + (rejected) → draft (revision) +``` + +--- + +## Integration Points + +| From | To | Trigger | +|------|----|---------| +| ContentIdeas | Tasks | Create tasks | +| Tasks | Content | Generate content | +| Content | Images | Generate images | +| Content | WordPress | Publish | +| WordPress | Content | Sync imports | +| Automation Stage 4 | Content | Automated generation | +| Automation Stage 5-6 | Images | Automated image generation | + +--- + +## Common Issues + +| Issue | Cause | Fix | +|-------|-------|-----| +| Content too short | Low word count target | Increase target in task | +| Images not generating | No prompts created | Run image prompt generation first | +| WordPress publish fails | Invalid credentials | Check integration settings | +| Content stuck in draft | No manual status update | Update status via UI or API | +| Duplicate content | Re-running generation | Check if content already exists | + +--- + +## Planned Changes + +| Feature | Status | Description | +|---------|--------|-------------| +| Content revisions | 🔜 Planned | Track content version history | +| Multi-language | 🔜 Planned | Generate content in different languages | +| Batch generation | 🔜 Planned | Generate multiple content pieces at once | +| Regenerate sections | 🔜 Planned | AI regenerate specific sections | diff --git a/v2/Live Docs on Server/igny8-app-docs/20-API/ENDPOINTS.md b/v2/Live Docs on Server/igny8-app-docs/20-API/ENDPOINTS.md new file mode 100644 index 00000000..958ab214 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/20-API/ENDPOINTS.md @@ -0,0 +1,588 @@ +# API Endpoints Reference + +**Last Verified:** January 20, 2026 +**Version:** 1.8.4 +**Base URL:** `/api/v1/` +**Documentation:** `/api/docs/` (Swagger) | `/api/redoc/` (ReDoc) + +--- + +## Authentication + +All endpoints require authentication unless noted. + +**Methods:** +- `Authorization: Bearer ` - JWT token +- `Authorization: ApiKey ` - API key (WordPress integration) +- Session cookie (Django Admin) + +--- + +## Auth Endpoints (`/api/v1/auth/`) + +| Method | Path | Handler | Auth | Purpose | +|--------|------|---------|------|---------| +| POST | `/register/` | `RegisterView` | ❌ | Create account | +| POST | `/login/` | `LoginView` | ❌ | Get tokens | +| POST | `/logout/` | `LogoutView` | ✅ | Invalidate session | +| POST | `/token/refresh/` | `RefreshTokenView` | ✅ | Refresh access token | +| POST | `/password/change/` | `ChangePasswordView` | ✅ | Change password | +| POST | `/password/reset/` | `RequestPasswordResetView` | ❌ | Request reset email | +| POST | `/password/reset/confirm/` | `ResetPasswordView` | ❌ | Confirm reset | +| GET | `/groups/` | `RoleViewSet.list` | ✅ | List roles | +| GET | `/users/` | `UserViewSet.list` | ✅ | List users | +| POST | `/users/` | `UserViewSet.create` | ✅ | Create user | +| GET | `/account/` | `AccountViewSet.retrieve` | ✅ | Get account | +| PUT | `/account/` | `AccountViewSet.update` | ✅ | Update account | +| GET | `/sites/` | `SiteViewSet.list` | ✅ | List sites | +| POST | `/sites/` | `SiteViewSet.create` | ✅ | Create site | +| GET | `/sectors/` | `SectorViewSet.list` | ✅ | List sectors | +| POST | `/sectors/` | `SectorViewSet.create` | ✅ | Create sector | +| GET | `/industries/` | `IndustryViewSet.list` | ✅ | List industries | +| GET | `/keywords-library/` | `SeedKeywordViewSet.list` | ✅ | List keywords library (v1.8.2) | +| GET | `/keywords-library/sector_stats/` | `SeedKeywordViewSet.sector_stats` | ✅ | Get sector statistics (v1.8.2) | + +--- + +## Keywords Library Endpoints (v1.8.2) + +**New Endpoint:** `/api/v1/keywords-library/` +**Previous:** `/api/v1/auth/seed-keywords/` (deprecated, no backward compatibility) + +### List Keywords + +``` +GET /api/v1/keywords-library/ +``` + +**Query Parameters:** +- `sector_ids` _(string, comma-separated)_ - Filter by specific sector IDs (e.g., `1,2,3`) + - **New in v1.8.2:** Ensures sites only see keywords from their configured sectors +- `search` _(string)_ - Search keyword names +- `country` _(string)_ - Filter by country code (e.g., `US`, `UK`) +- `volume_min` _(number)_ - Minimum search volume +- `volume_max` _(number)_ - Maximum search volume +- `difficulty` _(string)_ - SEO difficulty level (`easy`, `medium`, `hard`, `very_hard`) +- `is_high_opportunity` _(boolean)_ - Filter high-opportunity keywords +- `is_paid` _(boolean)_ - Filter paid/premium keywords +- `ordering` _(string)_ - Sort field (prefix `-` for descending) + - Options: `keyword`, `volume`, `difficulty`, `country` + - Default: `-volume` +- `page` _(number)_ - Page number for pagination +- `page_size` _(number)_ - Results per page (default: 20) + +**Example Request:** +```bash +GET /api/v1/keywords-library/?sector_ids=1,2,3&country=US&difficulty=easy&ordering=-volume&page=1 +``` + +**Response:** +```json +{ + "count": 150, + "next": "http://api.igny8.com/api/v1/keywords-library/?page=2§or_ids=1,2,3", + "previous": null, + "results": [ + { + "id": 1, + "keyword": "cloud computing services", + "volume": 12000, + "difficulty": "medium", + "country": "US", + "industry_sector": 1, + "industry_sector_name": "Cloud Infrastructure & Services", + "is_high_opportunity": true, + "is_paid": false, + "credit_cost": 0, + "created_at": "2025-01-15T10:00:00Z" + } + ] +} +``` + +### Sector Statistics + +``` +GET /api/v1/keywords-library/sector_stats/ +``` + +Returns aggregated statistics per sector for the keywords library. + +**Query Parameters:** +- `sector_ids` _(string, comma-separated)_ - Filter by specific sector IDs + - **New in v1.8.2:** Returns stats only for specified sectors + +**Example Request:** +```bash +GET /api/v1/keywords-library/sector_stats/?sector_ids=1,2,3 +``` + +**Response:** +```json +[ + { + "sector_id": 1, + "sector_name": "Cloud Infrastructure & Services", + "sector_description": "Keywords related to cloud computing, hosting, and infrastructure services", + "stats": { + "total": 250, + "added": 45, + "available": 205, + "high_opportunity": 80, + "paid": 30, + "free": 220 + } + } +] +``` + +**Stat Definitions:** +- `total` - All keywords in sector +- `added` - Keywords site has added to their workflow +- `available` - Keywords not yet added (total - added) +- `high_opportunity` - Premium keywords with high volume and potential +- `paid` - Premium keywords requiring credits +- `free` - Keywords with no credit cost + +**Use Cases:** +1. **Sector Metric Cards** - Display stats per sector with clickable filters +2. **Smart Suggestions** - Show available counts for bulk-add operations +3. **Progress Tracking** - Track keyword adoption across sectors +4. **Budget Planning** - Understand credit requirements for paid keywords + +--- + +## Planner Endpoints (`/api/v1/planner/`) + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/keywords/` | `KeywordViewSet.list` | List keywords | +| POST | `/keywords/` | `KeywordViewSet.create` | Create keyword | +| GET | `/keywords/{id}/` | `KeywordViewSet.retrieve` | Get keyword | +| PUT | `/keywords/{id}/` | `KeywordViewSet.update` | Update keyword | +| DELETE | `/keywords/{id}/` | `KeywordViewSet.destroy` | Delete keyword | +| POST | `/keywords/bulk_delete/` | `KeywordViewSet.bulk_delete` | Hard delete multiple | +| POST | `/keywords/bulk_status/` | `KeywordViewSet.bulk_status` | Update status | +| POST | `/keywords/add_to_workflow/` | `KeywordViewSet.add_to_workflow` | Add seed keywords | +| GET | `/clusters/` | `ClusterViewSet.list` | List clusters | +| POST | `/clusters/` | `ClusterViewSet.create` | Create cluster | +| POST | `/clusters/auto_cluster/` | `ClusterViewSet.auto_cluster` | AI clustering | +| POST | `/clusters/generate_ideas/` | `ClusterViewSet.generate_ideas` | Generate ideas | +| GET | `/ideas/` | `ContentIdeaViewSet.list` | List ideas | +| POST | `/ideas/` | `ContentIdeaViewSet.create` | Create idea | +| POST | `/ideas/create_tasks/` | `ContentIdeaViewSet.create_tasks` | Convert to tasks | + +**Query Parameters:** +- `?site_id=` - Filter by site +- `?sector_id=` - Filter by sector +- `?status=` - Filter by status +- `?cluster_id=` - Filter by cluster +- `?difficulty_min=`, `?difficulty_max=` - Difficulty range +- `?volume_min=`, `?volume_max=` - Volume range + +--- + +## Writer Endpoints (`/api/v1/writer/`) + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/tasks/` | `TaskViewSet.list` | List tasks | +| POST | `/tasks/` | `TaskViewSet.create` | Create task | +| POST | `/tasks/bulk_create/` | `TaskViewSet.bulk_create` | Create multiple | +| POST | `/tasks/{id}/generate_content/` | `TaskViewSet.generate_content` | AI generation | +| GET | `/content/` | `ContentViewSet.list` | List content | +| POST | `/content/` | `ContentViewSet.create` | Create content | +| GET | `/content/{id}/` | `ContentViewSet.retrieve` | Get content | +| PUT | `/content/{id}/` | `ContentViewSet.update` | Update content | +| POST | `/content/{id}/update_content/` | `ContentViewSet.update_content` | Update with validation | +| POST | `/content/{id}/generate_images/` | `ContentViewSet.generate_images` | Generate images | +| POST | `/content/{id}/publish_to_wordpress/` | `ContentViewSet.publish_to_wordpress` | Publish to WP | +| POST | `/content/{id}/schedule/` | `ContentViewSet.schedule` | Schedule for publishing (v1.3.2) | +| POST | `/content/{id}/unschedule/` | `ContentViewSet.unschedule` | Remove from schedule (v1.3.2) | +| GET | `/images/` | `ImageViewSet.list` | List images | +| POST | `/images/generate_for_content/` | `ImageViewSet.generate_for_content` | Generate images | +| POST | `/images/regenerate/` | `ImageViewSet.regenerate` | Regenerate image | +| GET | `/taxonomies/` | `TaxonomyViewSet.list` | List taxonomies | + +**Content Query Parameters (v1.3.2):** +- `?status__in=draft,review,approved` - Filter by multiple workflow statuses +- `?site_status=scheduled` - Filter by publishing status +- `?site_id=` - Filter by site + +**Schedule Endpoint Request:** +```json +POST /api/v1/writer/content/{id}/schedule/ +{ + "scheduled_publish_at": "2026-01-15T09:00:00Z" +} +``` + +**Schedule Endpoint Response:** +```json +{ + "content_id": 123, + "site_status": "scheduled", + "scheduled_publish_at": "2026-01-15T09:00:00Z" +} +``` + +--- + +## Billing Endpoints (`/api/v1/billing/`) + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/balance/` | `CreditBalanceViewSet.list` | Current balance | +| GET | `/usage/` | `CreditUsageViewSet.list` | Usage log | +| GET | `/usage/summary/` | `CreditUsageViewSet.summary` | Usage summary | +| GET | `/usage/limits/` | `CreditUsageViewSet.limits` | Plan limits | +| GET | `/transactions/` | `TransactionViewSet.list` | Transaction history | + +--- + +## Integration Endpoints (`/api/v1/integration/`) + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/` | `SiteIntegrationViewSet.list` | List integrations | +| POST | `/` | `SiteIntegrationViewSet.create` | Create integration | +| PUT | `/{id}/` | `SiteIntegrationViewSet.update` | Update integration | +| DELETE | `/{id}/` | `SiteIntegrationViewSet.destroy` | Delete integration | +| POST | `/{id}/test_connection/` | Test connection | Verify credentials | +| POST | `/{id}/test_collection_connection/` | Test collection | Test specific type | +| POST | `/{id}/sync/` | Trigger sync | Start sync | +| GET | `/{id}/sync_status/` | Sync status | Current progress | +| POST | `/{id}/update_structure/` | Update structure | Refresh site data | +| GET | `/{id}/content_types/` | Content types | Available types | +| GET | `/{id}/sync_health/` | Sync health | Statistics | +| POST | `/site_sync/` | Site-level sync | Sync by site ID | +| POST | `/webhook/wordpress/` | WordPress webhook | Receive WP updates | + +### Unified Settings Endpoints (v1.8.0) + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/sites/{site_id}/unified-settings/` | `UnifiedSiteSettingsViewSet.retrieve` | Get all site settings (automation, publishing, AI) | +| PATCH | `/sites/{site_id}/unified-settings/` | `UnifiedSiteSettingsViewSet.partial_update` | Update settings (partial) | +| **GET** | `/settings/defaults/` | **v1.8.1** `DefaultSettingsAPIView` | Get default settings for reset functionality | + +### Default Settings Endpoint (v1.8.1) + +Returns centralized defaults from `DefaultAutomationConfig` singleton: + +```json +GET /api/v1/integration/settings/defaults/ + +{ + "automation": { + "enabled": false, + "frequency": "daily", + "time": "02:00" + }, + "stages": [ + {"number": 1, "enabled": true, "batch_size": 50, "per_run_limit": 0, "use_testing": false, "budget_pct": 15}, + {"number": 2, "enabled": true, "batch_size": 1, "per_run_limit": 0, "use_testing": false, "budget_pct": 10}, + // ... stages 3-7 + ], + "delays": { + "within_stage": 3, + "between_stage": 5 + }, + "publishing": { + "auto_approval_enabled": false, + "auto_publish_enabled": false, + "daily_publish_limit": 3, + "weekly_publish_limit": 15, + "monthly_publish_limit": 50, + "publish_days": ["mon", "tue", "wed", "thu", "fri"], + "time_slots": ["09:00", "14:00", "18:00"] + }, + "images": { + "style": "photorealistic", + "max_images": 4 + } +} +``` + +**Unified Settings Response:** +```json +{ + "automation_config": { + "enabled": true, + "frequency": "daily", + "scheduled_days": ["mon", "wed", "fri"], + "scheduled_time": "09:00:00", + "next_run_at": "2026-01-18T09:00:00Z", + "stage_1_enabled": true, "stage_1_batch_size": 50, "max_keywords_per_run": 100, + "stage_2_enabled": true, "stage_2_batch_size": 10, "max_clusters_per_run": 20, + // ... stages 3-7 + }, + "publishing_settings": { + "auto_approval_enabled": true, + "auto_publish_enabled": true, + "daily_publish_limit": 3, + "weekly_publish_limit": 15, + "monthly_publish_limit": 50, + "publish_days": ["mon", "tue", "wed", "thu", "fri"], + "publish_time_slots": [{"start": "09:00", "end": "17:00"}], + "total_items_per_run": 500 + }, + "stage_configs": [ + {"stage": 1, "enabled": true, "batch_size": 50, "max_per_run": 100}, + // ... stages 2-7 + ], + "ai_settings": { + "testing_model_id": 2, + "live_model_id": 1, + "image_model_id": 3 + } +} +``` + +### Publishing Settings Endpoints (deprecated v1.8.0) + +> ⚠️ **Deprecated:** Use `/sites/{site_id}/unified-settings/` instead + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/sites/{site_id}/publishing-settings/` | `PublishingSettingsViewSet.retrieve` | Get publishing settings | +| PUT | `/sites/{site_id}/publishing-settings/` | `PublishingSettingsViewSet.update` | Update settings (full) | +| PATCH | `/sites/{site_id}/publishing-settings/` | `PublishingSettingsViewSet.partial_update` | Update settings (partial) | + +**Publishing Settings Response:** +```json +{ + "id": 1, + "site": 5, + "auto_approval_enabled": true, + "auto_publish_enabled": true, + "daily_publish_limit": 3, + "weekly_publish_limit": 15, + "monthly_publish_limit": 50, + "publish_days": ["mon", "tue", "wed", "thu", "fri"], + "publish_time_slots": ["09:00", "14:00", "18:00"], + "created_at": "2026-01-03T10:00:00Z", + "updated_at": "2026-01-03T10:00:00Z" +} +``` + +--- + +## System Endpoints (`/api/v1/system/`) + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/settings/integrations/openai/` | Get OpenAI settings | Current config | +| PUT | `/settings/integrations/openai/` | Save OpenAI settings | Update config | +| GET | `/settings/integrations/image_generation/` | Get image settings | Current config | +| PUT | `/settings/integrations/image_generation/` | Save image settings | Update config | +| POST | `/settings/integrations/test/` | Test connection | Verify API keys | +| GET | `/settings/content/{key}/` | `ContentSettingsViewSet.retrieve` | Get content settings | +| POST | `/settings/content/{key}/save/` | `ContentSettingsViewSet.save_settings` | Save content settings | +| GET | `/prompts/` | List prompts | All prompts | +| GET | `/prompts/{type}/` | Get prompt | Specific prompt | +| PUT | `/prompts/{type}/` | Save prompt | Update prompt | +| POST | `/prompts/{type}/reset/` | Reset prompt | Reset to default | +| GET | `/modules/` | Get modules | Module enable state | +| PUT | `/modules/` | Save modules | Update enabled | +| GET | `/health/` | Health check | System status | + +**Content Settings Keys:** +- `content_generation` - AI writing settings (default_article_length, default_tone, include_faq, enable_internal_linking, etc.) +- `publishing` - Publishing defaults (default_publish_status, auto_schedule, schedule_frequency, schedule_times) + +--- + +## Notification Endpoints (`/api/v1/notifications/`) - v1.2.0 + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/` | `NotificationViewSet.list` | List notifications (paginated) | +| GET | `/{id}/` | `NotificationViewSet.retrieve` | Get notification detail | +| DELETE | `/{id}/` | `NotificationViewSet.destroy` | Delete notification | +| POST | `/{id}/read/` | `NotificationViewSet.read` | Mark single notification as read | +| POST | `/read-all/` | `NotificationViewSet.read_all` | Mark all notifications as read | +| GET | `/unread-count/` | `NotificationViewSet.unread_count` | Get unread notification count | + +**Query Parameters:** +- `?page=` - Page number for pagination +- `?page_size=` - Results per page (default 20) +- `?is_read=` - Filter by read status (true/false) +- `?notification_type=` - Filter by type (ai_task, system, credit, billing, integration, content, info) + +**Notification Types:** +- `ai_cluster_complete`, `ai_cluster_failed` - Clustering operations +- `ai_ideas_complete`, `ai_ideas_failed` - Idea generation +- `ai_content_complete`, `ai_content_failed` - Content generation +- `ai_images_complete`, `ai_images_failed` - Image generation +- `ai_prompts_complete`, `ai_prompts_failed` - Image prompt generation +- `content_ready_review`, `content_published`, `content_publish_failed` - Workflow +- `wordpress_sync_success`, `wordpress_sync_failed` - WordPress sync +- `credits_low`, `credits_depleted` - Billing alerts +- `site_setup_complete`, `keywords_imported` - Setup +- `system_info` - System notifications + +**Response Format:** +```json +{ + "id": 1, + "notification_type": "ai_content_complete", + "severity": "success", + "title": "Content Generated", + "message": "Generated 5 articles successfully", + "is_read": false, + "created_at": "2025-12-27T12:00:00Z", + "read_at": null, + "action_label": "View Content", + "action_url": "/writer/content", + "metadata": {"count": 5, "credits": 250} +} +``` + +--- + +## Automation Endpoints (`/api/v1/automation/`) + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/config/` | Get config | Automation config | +| PUT | `/update_config/` | Update config | Save settings | +| POST | `/run_now/` | Run now | Start manual run | +| GET | `/current_run/` | Current run | Run status | +| GET | `/pipeline_overview/` | Pipeline | Stage counts | +| GET | `/current_processing/` | Processing | Live status | +| POST | `/pause/` | Pause | Pause run | +| POST | `/resume/` | Resume | Resume run | +| POST | `/cancel/` | Cancel | Cancel run | +| GET | `/history/` | History | Past runs | +| GET | `/logs/` | Logs | Activity log | +| GET | `/estimate/` | Estimate | Credit estimate | +| **GET** | `/runs/` | **v1.8.0** List runs | All automation runs (paginated) | +| **GET** | `/runs/{id}/` | **v1.8.0** Run detail | Single run with stages, logs | + +**Query Parameters:** All require `?site_id=`, run-specific require `?run_id=` + +### Automation Runs Response (v1.8.0) + +```json +GET /api/v1/automation/runs/?site_id=1 + +{ + "count": 25, + "results": [ + { + "id": 1, + "site": 1, + "status": "completed", + "started_at": "2026-01-18T09:00:00Z", + "completed_at": "2026-01-18T09:45:00Z", + "current_stage": 7, + "total_stages": 7, + "items_processed": 150, + "credits_used": 450, + "error_message": null + } + ] +} +``` + +--- + +## Linker Endpoints (`/api/v1/linker/`) + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| POST | `/process/` | `LinkerViewSet.process` | Process single content | +| POST | `/batch_process/` | `LinkerViewSet.batch_process` | Process multiple | + +--- + +## Optimizer Endpoints (`/api/v1/optimizer/`) + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| POST | `/optimize/` | `OptimizerViewSet.optimize` | Optimize content | +| POST | `/batch_optimize/` | `OptimizerViewSet.batch_optimize` | Batch optimize | +| POST | `/analyze/` | `OptimizerViewSet.analyze` | Analyze only | + +--- + +## Publisher Endpoints (`/api/v1/publisher/`) + +| Method | Path | Handler | Purpose | +|--------|------|---------|---------| +| GET | `/records/` | `PublishingRecordViewSet.list` | List records | +| POST | `/records/` | `PublishingRecordViewSet.create` | Create record | +| GET | `/deployments/` | `DeploymentViewSet.list` | List deployments | +| POST | `/publish/` | `PublishContentViewSet.publish` | Publish content | +| GET | `/publish/status/` | `PublishContentViewSet.status` | Publish status | +| GET | `/site-definition/` | `SiteDefinitionViewSet.list` | Public site def | + +--- + +## Response Format + +### Success Response + +```json +{ + "success": true, + "data": { ... }, + "message": "Optional message" +} +``` + +### Error Response + +```json +{ + "success": false, + "error": "Error message", + "code": "ERROR_CODE" +} +``` + +### Paginated Response + +```json +{ + "count": 100, + "next": "http://api.igny8.com/api/v1/planner/keywords/?page=2", + "previous": null, + "results": [ ... ] +} +``` + +--- + +## HTTP Status Codes + +| Code | Meaning | +|------|---------| +| 200 | Success | +| 201 | Created | +| 400 | Bad Request | +| 401 | Unauthorized | +| 402 | Payment Required (insufficient credits) | +| 403 | Forbidden | +| 404 | Not Found | +| 429 | Rate Limited | +| 500 | Server Error | + +--- + +## Rate Limiting + +Rate limits are scoped by operation type: + +| Scope | Limit | +|-------|-------| +| AI operations | 60/min | +| Content operations | 100/min | +| Auth operations | 20/min | +| General | 300/min | + +Rate limit headers included in responses: +- `X-RateLimit-Limit` +- `X-RateLimit-Remaining` +- `X-RateLimit-Reset` diff --git a/v2/Live Docs on Server/igny8-app-docs/30-FRONTEND/COMPONENT-SYSTEM.md b/v2/Live Docs on Server/igny8-app-docs/30-FRONTEND/COMPONENT-SYSTEM.md new file mode 100644 index 00000000..1c435f52 --- /dev/null +++ b/v2/Live Docs on Server/igny8-app-docs/30-FRONTEND/COMPONENT-SYSTEM.md @@ -0,0 +1,683 @@ +# IGNY8 Frontend Component System + +**Last Updated:** January 20, 2026 +**Version:** 1.8.4 + +> **🔒 ENFORCED BY ESLINT** - Violations will trigger warnings/errors during build. +> This document is the single source of truth for all UI components. + +--- + +## Quick Reference Card + +| Element | Component | Import Path | +|---------|-----------|-------------| +| Button | `Button` | `components/ui/button/Button` | +| Icon Button | `IconButton` | `components/ui/button/IconButton` | +| Button Group | `ButtonGroup` | `components/ui/button-group/ButtonGroup` | +| Text Input | `InputField` | `components/form/input/InputField` | +| Checkbox | `Checkbox` | `components/form/input/Checkbox` | +| Radio | `Radio` | `components/form/input/Radio` | +| File Upload | `FileInput` | `components/form/input/FileInput` | +| Textarea | `TextArea` | `components/form/input/TextArea` | +| Dropdown | `Select` | `components/form/Select` | +| Searchable Dropdown | `SelectDropdown` | `components/form/SelectDropdown` | +| Multi-Select | `MultiSelect` | `components/form/MultiSelect` | +| Toggle Switch | `Switch` | `components/form/switch/Switch` | +| Badge | `Badge` | `components/ui/badge/Badge` | +| Card | `Card` | `components/ui/card/Card` | +| Modal | `Modal` | `components/ui/modal` | +| Alert | `Alert` | `components/ui/alert/Alert` | +| Spinner | `Spinner` | `components/ui/spinner/Spinner` | +| Tabs | `Tabs` | `components/ui/tabs/Tabs` | +| Tooltip | `Tooltip` | `components/ui/tooltip/Tooltip` | +| Calendar Tooltip | `CalendarItemTooltip` | `components/ui/tooltip/CalendarItemTooltip` | +| Toast | `useToast` | `components/ui/toast/ToastContainer` | +| Icons | `*Icon` | `icons` (e.g., `../../icons`) | + +--- + +## 1. BUTTONS + +### Button (Standard) + +```tsx +import Button from '../../components/ui/button/Button'; + + +``` + +**Common Patterns:** +```tsx +// Primary action + + +// Success/confirm + + +// Danger/destructive + + +// Secondary/cancel + + +// With icon + +``` + +### IconButton (Icon-only) + +```tsx +import IconButton from '../../components/ui/button/IconButton'; + +} // Required: Icon component + variant="ghost" // solid | outline | ghost + tone="neutral" // brand | success | warning | danger | neutral + size="sm" // xs | sm | md | lg + shape="rounded" // rounded | circle + onClick={handler} + disabled={false} + title="Close" // Required: Accessibility label + aria-label="Close" // Optional: Override aria-label +/> +``` + +**Common Patterns:** +```tsx +// Close button +} variant="ghost" tone="neutral" title="Close" /> + +// Delete button +} variant="ghost" tone="danger" title="Delete" /> + +// Edit button +} variant="ghost" tone="brand" title="Edit" /> + +// Add button (circular) +} variant="solid" tone="brand" shape="circle" title="Add" /> +``` + +--- + +## 2. FORM INPUTS + +### InputField (Text/Number/Email/Password) + +```tsx +import InputField from '../../components/form/input/InputField'; + + setValue(e.target.value)} + id="field-id" + name="field-name" + disabled={false} + error={false} // Shows error styling + success={false} // Shows success styling + hint="Helper text" // Text below input + min="0" // For number inputs + max="100" // For number inputs + step={1} // For number inputs +/> +``` + +### TextArea (Multi-line) + +```tsx +import TextArea from '../../components/form/input/TextArea'; + + + +// ✅ ALWAYS + + + + +// ✅ ALWAYS + + +