temproary docs uplaoded

This commit is contained in:
IGNY8 VPS (Salman)
2026-03-23 09:02:49 +00:00
parent cb6eca4483
commit 128b186865
113 changed files with 68897 additions and 0 deletions

View File

@@ -0,0 +1,860 @@
import { useState } from "react";
const Section = ({ title, children, defaultOpen = false }) => {
const [open, setOpen] = useState(defaultOpen);
return (
<div className="mb-4 border border-gray-200 rounded-xl overflow-hidden">
<button
onClick={() => setOpen(!open)}
className="w-full flex items-center justify-between p-4 bg-gray-50 hover:bg-gray-100 transition-colors"
>
<span className="text-lg font-bold text-gray-900">{title}</span>
<span className="text-xl text-gray-500">{open ? "" : "+"}</span>
</button>
{open && <div className="p-5 bg-white">{children}</div>}
</div>
);
};
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 (
<span className={`px-2 py-0.5 rounded-full text-xs font-semibold ${colors[color]}`}>
{children}
</span>
);
};
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 (
<div className={`border-2 rounded-xl p-4 ${borderColors[color]}`}>
<h3 className="font-bold text-lg mb-1">{title}</h3>
<p className="text-xs text-gray-500 mb-3">{subtitle}</p>
{children}
</div>
);
};
const AppBlock = ({ name, purpose, port, badge }) => (
<div className="flex items-center gap-2 p-2 bg-white rounded-lg border border-gray-200 mb-2">
<div className="flex-1">
<div className="flex items-center gap-2">
<span className="font-semibold text-sm">{name}</span>
{badge && <Badge color={badge.color}>{badge.text}</Badge>}
</div>
<p className="text-xs text-gray-500">{purpose}</p>
</div>
{port && <span className="text-xs font-mono text-gray-400">:{port}</span>}
</div>
);
const CostRow = ({ item, monthly, notes }) => (
<div className="flex items-center justify-between py-2 border-b border-gray-100">
<div>
<span className="font-medium text-sm">{item}</span>
{notes && <p className="text-xs text-gray-400">{notes}</p>}
</div>
<span className="font-bold text-sm">{monthly}</span>
</div>
);
const Step = ({ num, title, code }) => (
<div className="mb-4">
<div className="flex items-center gap-2 mb-2">
<span className="w-6 h-6 rounded-full bg-gray-900 text-white text-xs flex items-center justify-center font-bold">
{num}
</span>
<span className="font-semibold text-sm">{title}</span>
</div>
{code && (
<pre className="bg-gray-900 text-green-400 text-xs p-3 rounded-lg overflow-x-auto whitespace-pre-wrap">
{code}
</pre>
)}
</div>
);
const Arrow = ({ label }) => (
<div className="flex flex-col items-center py-2">
<span className="text-xs text-gray-500 mb-1">{label}</span>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" className="text-gray-400">
<path d="M12 4v16m0 0l-4-4m4 4l4-4" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
</div>
);
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 (
<div className="min-h-screen bg-white p-4 max-w-4xl mx-auto">
<div className="mb-6">
<h1 className="text-2xl font-black text-gray-900">IGNY8 Self-Hosted AI Infrastructure</h1>
<p className="text-sm text-gray-500 mt-1">Hostinger VPS + Vast.ai GPU Zero API Costs Architecture</p>
</div>
<div className="flex gap-1 mb-6 overflow-x-auto pb-2">
{tabs.map((t) => (
<button
key={t.id}
onClick={() => setTab(t.id)}
className={`px-3 py-1.5 rounded-lg text-xs font-semibold whitespace-nowrap transition-colors ${
tab === t.id ? "bg-gray-900 text-white" : "bg-gray-100 text-gray-600 hover:bg-gray-200"
}`}
>
{t.label}
</button>
))}
</div>
{tab === "overview" && (
<div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<ServerBox title="Hostinger VPS" subtitle="CPU-only • Web + AI Orchestration" color="blue">
<AppBlock name="Plesk" purpose="Web hosting panel — client sites, IGNY8 frontend" port="8443" />
<AppBlock name="Flowise" purpose="AI workflow builder — RAG chatbots, content pipelines" port="3000" badge={{ color: "green", text: "IGNY8 Core" }} />
<AppBlock name="Open WebUI" purpose="ChatGPT-like interface for clients" port="3001" badge={{ color: "blue", text: "Client-facing" }} />
<AppBlock name="Chroma" purpose="Vector database for RAG / knowledge bases" port="8000" />
<AppBlock name="LiteLLM" purpose="API gateway — routes to Vast.ai GPU" port="4000" badge={{ color: "purple", text: "Bridge" }} />
<AppBlock name="Nginx" purpose="Reverse proxy + SSL for all services" port="443" />
</ServerBox>
<ServerBox title="Vast.ai GPU Server" subtitle="2x RTX 3090 (48GB) • AI Inference" color="purple">
<AppBlock name="Ollama" purpose="LLM inference engine" port="11434" badge={{ color: "orange", text: "GPU" }} />
<AppBlock name="Qwen3 32B" purpose="Content writing for IGNY8" badge={{ color: "green", text: "Text Gen" }} />
<AppBlock name="Qwen3 30B-A3B" purpose="Fast inference for chat / SEO tasks" badge={{ color: "green", text: "Text Gen" }} />
<AppBlock name="FLUX.1 / SD 3.5" purpose="Image generation via ComfyUI" port="8188" badge={{ color: "teal", text: "Image Gen" }} />
<AppBlock name="Wan 2.1 / LTX-Video" purpose="Video generation via ComfyUI" badge={{ color: "red", text: "Video Gen" }} />
<AppBlock name="ComfyUI" purpose="Unified UI for image + video generation" port="8188" />
</ServerBox>
</div>
<div className="bg-gray-50 rounded-xl p-4 mb-4">
<h3 className="font-bold text-sm mb-3">How They Connect</h3>
<div className="space-y-2 text-xs">
<div className="flex items-center gap-2">
<Badge color="blue">Hostinger</Badge>
<span className="text-gray-400"> LiteLLM proxy </span>
<Badge color="purple">Vast.ai Ollama</Badge>
<span className="text-gray-500">Text generation (OpenAI-compatible API)</span>
</div>
<div className="flex items-center gap-2">
<Badge color="blue">Flowise</Badge>
<span className="text-gray-400"> LiteLLM </span>
<Badge color="purple">Qwen3 models</Badge>
<span className="text-gray-500">IGNY8 content writing pipeline</span>
</div>
<div className="flex items-center gap-2">
<Badge color="blue">IGNY8 App</Badge>
<span className="text-gray-400"> HTTP API </span>
<Badge color="purple">ComfyUI</Badge>
<span className="text-gray-500">Image/video generation requests</span>
</div>
<div className="flex items-center gap-2">
<Badge color="blue">Open WebUI</Badge>
<span className="text-gray-400"> Ollama API </span>
<Badge color="purple">Any loaded model</Badge>
<span className="text-gray-500">Client chat interface</span>
</div>
</div>
</div>
<div className="bg-green-50 border border-green-200 rounded-xl p-4">
<h3 className="font-bold text-sm text-green-800 mb-2">Zero API Cost Model</h3>
<div className="text-xs text-green-700 space-y-1">
<p> All LLM inference runs on your own GPU no OpenAI/Anthropic API charges</p>
<p> Image generation uses open-source FLUX.1/SD 3.5 no Midjourney/DALL-E costs</p>
<p> Video generation uses Wan 2.1/LTX-Video no Runway/Sora costs</p>
<p> Only fixed costs: Hostinger VPS (~$12-25/mo) + Vast.ai GPU (~$200/mo)</p>
<p> Total: ~$215-225/month for unlimited AI generation</p>
</div>
</div>
</div>
)}
{tab === "hostinger" && (
<div>
<Section title="Recommended VPS Plan" defaultOpen={true}>
<div className="space-y-3">
<div className="bg-blue-50 p-3 rounded-lg">
<p className="font-bold text-sm">KVM 4 or higher recommended</p>
<p className="text-xs text-gray-600 mt-1">4 vCPU, 16GB RAM, 200GB NVMe handles Plesk + all CPU services comfortably</p>
</div>
<div className="text-sm space-y-2">
<p className="font-semibold">What runs on Hostinger (CPU-only):</p>
<div className="grid grid-cols-2 gap-2">
<div className="bg-white p-2 rounded border"><span className="font-mono text-xs">Plesk</span> Web hosting panel</div>
<div className="bg-white p-2 rounded border"><span className="font-mono text-xs">Flowise</span> AI workflow engine</div>
<div className="bg-white p-2 rounded border"><span className="font-mono text-xs">Open WebUI</span> Chat interface</div>
<div className="bg-white p-2 rounded border"><span className="font-mono text-xs">Chroma</span> Vector DB</div>
<div className="bg-white p-2 rounded border"><span className="font-mono text-xs">LiteLLM</span> API proxy</div>
<div className="bg-white p-2 rounded border"><span className="font-mono text-xs">Nginx</span> Reverse proxy</div>
</div>
</div>
<div className="text-xs text-gray-500 bg-yellow-50 p-3 rounded-lg">
<strong>Important:</strong> Don't install Ollama on Hostinger — it will be too slow on CPU. All AI inference goes through LiteLLM → Vast.ai GPU server.
</div>
</div>
</Section>
<Section title="Docker Compose Stack">
<pre className="bg-gray-900 text-green-400 text-xs p-4 rounded-lg overflow-x-auto whitespace-pre-wrap">{`# 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:`}</pre>
</Section>
<Section title="LiteLLM Config (Bridge to Vast.ai)">
<pre className="bg-gray-900 text-green-400 text-xs p-4 rounded-lg overflow-x-auto whitespace-pre-wrap">{`# 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`}</pre>
<div className="mt-3 text-xs text-gray-500 bg-orange-50 p-3 rounded-lg">
<strong>Security:</strong> Use SSH tunnel or WireGuard VPN between Hostinger and Vast.ai. Never expose Ollama port directly to the internet.
</div>
</Section>
<Section title="Nginx Reverse Proxy">
<pre className="bg-gray-900 text-green-400 text-xs p-4 rounded-lg overflow-x-auto whitespace-pre-wrap">{`# /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;
}
}`}</pre>
</Section>
</div>
)}
{tab === "vastai" && (
<div>
<Section title="Server Spec: m:49870" defaultOpen={true}>
<div className="grid grid-cols-2 gap-3 mb-4">
<div className="bg-purple-50 p-3 rounded-lg">
<p className="text-xs text-gray-500">GPU</p>
<p className="font-bold">2x RTX 3090 (48GB total)</p>
</div>
<div className="bg-purple-50 p-3 rounded-lg">
<p className="text-xs text-gray-500">CPU</p>
<p className="font-bold">AMD EPYC 7543 (13.5/128 cores)</p>
</div>
<div className="bg-purple-50 p-3 rounded-lg">
<p className="text-xs text-gray-500">RAM</p>
<p className="font-bold">54GB / 516GB</p>
</div>
<div className="bg-purple-50 p-3 rounded-lg">
<p className="text-xs text-gray-500">Storage</p>
<p className="font-bold">442GB NVMe</p>
</div>
<div className="bg-purple-50 p-3 rounded-lg">
<p className="text-xs text-gray-500">Location</p>
<p className="font-bold">Bulgaria</p>
</div>
<div className="bg-purple-50 p-3 rounded-lg">
<p className="text-xs text-gray-500">Cost</p>
<p className="font-bold">$0.277/hr (~$200/mo)</p>
</div>
</div>
<div className="bg-yellow-50 border border-yellow-200 p-3 rounded-lg text-xs">
<strong>Note:</strong> 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.
</div>
</Section>
<Section title="What Runs on Vast.ai GPU">
<div className="space-y-3">
<div className="bg-white border-2 border-green-300 rounded-lg p-3">
<div className="flex items-center gap-2 mb-2">
<Badge color="green">Text Gen</Badge>
<span className="font-bold text-sm">Ollama + Qwen3 Models</span>
</div>
<p className="text-xs text-gray-600">IGNY8 content writing, SEO content, chat responses</p>
<div className="mt-2 text-xs space-y-1">
<p>• Qwen3 32B (dense) — ~20GB VRAM, best quality</p>
<p>• Qwen3 30B-A3B (MoE) — ~19GB VRAM, fastest</p>
<p>• Qwen3 14B — ~9GB VRAM, for concurrent tasks</p>
<p>• Load models on demand via Ollama</p>
</div>
</div>
<div className="bg-white border-2 border-teal-300 rounded-lg p-3">
<div className="flex items-center gap-2 mb-2">
<Badge color="teal">Image Gen</Badge>
<span className="font-bold text-sm">ComfyUI + FLUX.1 / Stable Diffusion</span>
</div>
<p className="text-xs text-gray-600">Blog images, social media graphics, product visuals for IGNY8</p>
<div className="mt-2 text-xs space-y-1">
<p>• FLUX.1 [dev] — best quality, ~12GB VRAM</p>
<p>• Stable Diffusion 3.5 — wide ecosystem, ~8GB VRAM</p>
<p>• SDXL-Lightning — fast generation, ~6GB VRAM</p>
<p>• All via ComfyUI API (port 8188)</p>
</div>
</div>
<div className="bg-white border-2 border-red-300 rounded-lg p-3">
<div className="flex items-center gap-2 mb-2">
<Badge color="red">Video Gen</Badge>
<span className="font-bold text-sm">Wan 2.1 / LTX-Video via ComfyUI</span>
</div>
<p className="text-xs text-gray-600">Short videos for social media, product demos</p>
<div className="mt-2 text-xs space-y-1">
<p>• Wan 2.1 (14B) — best quality, uses full 48GB</p>
<p>• Wan 2.1 (1.3B) — fast, only ~8GB VRAM</p>
<p>• LTX-Video — fastest, ~12GB VRAM, 768x512</p>
<p>• ⚠️ Unload LLM before running video gen (shared VRAM)</p>
</div>
</div>
</div>
</Section>
<Section title="VRAM Management Strategy">
<div className="bg-gray-50 p-4 rounded-lg">
<p className="text-sm font-semibold mb-3">48GB total — you can't run everything simultaneously</p>
<div className="space-y-3">
<div className="bg-white p-3 rounded border-l-4 border-green-500">
<p className="font-semibold text-xs">Mode 1: Content Writing (Default)</p>
<p className="text-xs text-gray-500 mt-1">Qwen3 32B (~20GB) + FLUX.1 image gen (~12GB) = ~32GB</p>
<p className="text-xs text-green-600 mt-1"> Fits comfortably, both can run simultaneously</p>
</div>
<div className="bg-white p-3 rounded border-l-4 border-blue-500">
<p className="font-semibold text-xs">Mode 2: Fast Throughput</p>
<p className="text-xs text-gray-500 mt-1">Qwen3 30B-A3B MoE (~19GB) + FLUX.1 (~12GB) = ~31GB</p>
<p className="text-xs text-blue-600 mt-1"> Blazing fast text + images together</p>
</div>
<div className="bg-white p-3 rounded border-l-4 border-red-500">
<p className="font-semibold text-xs">Mode 3: Video Generation</p>
<p className="text-xs text-gray-500 mt-1">Unload LLM Wan 2.1 14B uses full 48GB</p>
<p className="text-xs text-red-600 mt-1"> Schedule video jobs during off-peak, unload text model first</p>
</div>
</div>
<p className="text-xs text-gray-500 mt-3">Ollama auto-unloads models after 5min idle. Use <code className="bg-gray-200 px-1 rounded">OLLAMA_KEEP_ALIVE</code> to control.</p>
</div>
</Section>
<Section title="Secure Connection (SSH Tunnel)">
<pre className="bg-gray-900 text-green-400 text-xs p-4 rounded-lg overflow-x-auto whitespace-pre-wrap">{`# 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`}</pre>
</Section>
</div>
)}
{tab === "models" && (
<div>
<Section title="Text Generation — For IGNY8 Content" defaultOpen={true}>
<div className="overflow-x-auto">
<table className="w-full text-xs">
<thead>
<tr className="bg-gray-50">
<th className="text-left p-2">Model</th>
<th className="text-left p-2">VRAM</th>
<th className="text-left p-2">Speed</th>
<th className="text-left p-2">Best For</th>
<th className="text-left p-2">License</th>
</tr>
</thead>
<tbody>
<tr className="border-b bg-green-50">
<td className="p-2 font-bold">Qwen3 32B </td>
<td className="p-2">~20GB</td>
<td className="p-2">~15-25 tok/s</td>
<td className="p-2">Long-form SEO content, articles</td>
<td className="p-2"><Badge color="green">Apache 2.0</Badge></td>
</tr>
<tr className="border-b bg-blue-50">
<td className="p-2 font-bold">Qwen3 30B-A3B </td>
<td className="p-2">~19GB</td>
<td className="p-2">~40-60 tok/s</td>
<td className="p-2">Fast chat, SEO meta, bulk content</td>
<td className="p-2"><Badge color="green">Apache 2.0</Badge></td>
</tr>
<tr className="border-b">
<td className="p-2">Qwen3 14B</td>
<td className="p-2">~9GB</td>
<td className="p-2">~30-50 tok/s</td>
<td className="p-2">Concurrent light tasks</td>
<td className="p-2"><Badge color="green">Apache 2.0</Badge></td>
</tr>
<tr className="border-b">
<td className="p-2">Qwen3 8B</td>
<td className="p-2">~5GB</td>
<td className="p-2">~50-80 tok/s</td>
<td className="p-2">Classification, tagging, simple tasks</td>
<td className="p-2"><Badge color="green">Apache 2.0</Badge></td>
</tr>
</tbody>
</table>
</div>
<div className="mt-3 bg-green-50 p-3 rounded-lg text-xs">
<strong>IGNY8 Strategy:</strong> Use 30B-A3B MoE as default (fast bulk content), switch to 32B dense for premium long-form articles. Ollama handles model switching automatically.
</div>
</Section>
<Section title="Image Generation — For IGNY8 Visuals">
<div className="overflow-x-auto">
<table className="w-full text-xs">
<thead>
<tr className="bg-gray-50">
<th className="text-left p-2">Model</th>
<th className="text-left p-2">VRAM</th>
<th className="text-left p-2">Speed</th>
<th className="text-left p-2">Quality</th>
<th className="text-left p-2">License</th>
</tr>
</thead>
<tbody>
<tr className="border-b bg-teal-50">
<td className="p-2 font-bold">FLUX.1 [dev] </td>
<td className="p-2">~12GB</td>
<td className="p-2">~8-15s/img</td>
<td className="p-2">Excellent rivals Midjourney</td>
<td className="p-2"><Badge color="orange">Non-commercial*</Badge></td>
</tr>
<tr className="border-b bg-green-50">
<td className="p-2 font-bold">Stable Diffusion 3.5 </td>
<td className="p-2">~8GB</td>
<td className="p-2">~5-10s/img</td>
<td className="p-2">Very good + huge ecosystem</td>
<td className="p-2"><Badge color="green">Community</Badge></td>
</tr>
<tr className="border-b">
<td className="p-2">SDXL-Lightning</td>
<td className="p-2">~6GB</td>
<td className="p-2">~1-2s/img</td>
<td className="p-2">Good for fast iterations</td>
<td className="p-2"><Badge color="green">Open</Badge></td>
</tr>
<tr className="border-b">
<td className="p-2">Z-Image-Turbo</td>
<td className="p-2">~16GB</td>
<td className="p-2">&lt;1s/img</td>
<td className="p-2">Excellent + text rendering</td>
<td className="p-2"><Badge color="green">Apache 2.0</Badge></td>
</tr>
</tbody>
</table>
</div>
<div className="mt-3 bg-orange-50 p-3 rounded-lg text-xs">
<strong>*FLUX.1 [dev] licensing:</strong> 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).
</div>
</Section>
<Section title="Video Generation — For IGNY8 Social Content">
<div className="overflow-x-auto">
<table className="w-full text-xs">
<thead>
<tr className="bg-gray-50">
<th className="text-left p-2">Model</th>
<th className="text-left p-2">VRAM</th>
<th className="text-left p-2">Resolution</th>
<th className="text-left p-2">Duration</th>
<th className="text-left p-2">License</th>
</tr>
</thead>
<tbody>
<tr className="border-b bg-red-50">
<td className="p-2 font-bold">Wan 2.1 (1.3B) </td>
<td className="p-2">~8GB</td>
<td className="p-2">480p</td>
<td className="p-2">5-8s clips</td>
<td className="p-2"><Badge color="green">Apache 2.0</Badge></td>
</tr>
<tr className="border-b bg-blue-50">
<td className="p-2 font-bold">LTX-Video </td>
<td className="p-2">~12GB</td>
<td className="p-2">768x512</td>
<td className="p-2">5-7s clips</td>
<td className="p-2"><Badge color="green">Apache 2.0</Badge></td>
</tr>
<tr className="border-b">
<td className="p-2">Wan 2.1 (14B)</td>
<td className="p-2">~40GB+</td>
<td className="p-2">720p</td>
<td className="p-2">5-10s clips</td>
<td className="p-2"><Badge color="green">Apache 2.0</Badge></td>
</tr>
<tr className="border-b">
<td className="p-2">Wan2GP (optimized)</td>
<td className="p-2">~12GB</td>
<td className="p-2">720p</td>
<td className="p-2">8-15s clips</td>
<td className="p-2"><Badge color="green">Open</Badge></td>
</tr>
</tbody>
</table>
</div>
<div className="mt-3 bg-blue-50 p-3 rounded-lg text-xs">
<strong>Best approach:</strong> 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).
</div>
</Section>
<Section title="Running Models Simultaneously">
<div className="bg-gray-50 p-4 rounded-lg text-xs space-y-2">
<p className="font-bold text-sm mb-2">48GB VRAM Budget Practical Combos:</p>
<div className="bg-white p-2 rounded border border-green-300">
<strong>🟢 Combo A (Daily IGNY8 ops):</strong> Qwen3 30B-A3B (19GB) + SD 3.5 images (8GB) + Wan 1.3B video (8GB) = 35GB
</div>
<div className="bg-white p-2 rounded border border-blue-300">
<strong>🔵 Combo B (Premium content):</strong> Qwen3 32B (20GB) + FLUX.1 images (12GB) = 32GB
</div>
<div className="bg-white p-2 rounded border border-orange-300">
<strong>🟠 Combo C (Video focus):</strong> Wan 14B video (40GB+) = needs all VRAM, unload everything else
</div>
<div className="bg-white p-2 rounded border border-purple-300">
<strong>🟣 Combo D (Multi-client chat):</strong> Qwen3 14B (9GB) × multiple concurrent users = fast, lightweight
</div>
</div>
</Section>
</div>
)}
{tab === "setup" && (
<div>
<Section title="Phase 1: Hostinger VPS Setup" defaultOpen={true}>
<Step num={1} title="Get VPS & Install Docker" code={`# SSH into your Hostinger VPS
ssh root@your-vps-ip
# Install Docker
curl -fsSL https://get.docker.com | sh
docker compose version # verify
# Install Plesk (if not pre-installed)
sh <(curl https://autoinstall.plesk.com/one-click-installer)`} />
<Step num={2} title="Deploy the AI Stack" code={`# Create project directory
mkdir -p /opt/ai-stack && cd /opt/ai-stack
# Create docker-compose.yml (as shown in Hostinger tab)
# Create litellm_config.yaml
# Launch everything
docker compose up -d
# Verify all services
docker compose ps`} />
<Step num={3} title="Setup Nginx + SSL" code={`# Install certbot
apt install certbot python3-certbot-nginx
# Get SSL certs for your subdomains
certbot --nginx -d flowise.yourdomain.com
certbot --nginx -d chat.yourdomain.com
certbot --nginx -d api.yourdomain.com
# Setup nginx configs (as shown in Hostinger tab)`} />
</Section>
<Section title="Phase 2: Vast.ai GPU Server Setup">
<Step num={1} title="Rent & SSH into GPU" code={`# Rent m:49870 (or your chosen instance)
# Vast.ai gives you SSH command like:
ssh -p PORT root@VAST_IP -L 8080:localhost:8080
# First check GPU
nvidia-smi # Should show 2x RTX 3090`} />
<Step num={2} title="Install Ollama + Models" code={`# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh
# Start Ollama (listen on all interfaces for tunnel)
OLLAMA_HOST=0.0.0.0 ollama serve &
# Pull Qwen3 models
ollama pull qwen3:32b # ~20GB, best quality
ollama pull qwen3:30b-a3b # ~19GB, fastest
ollama pull qwen3:14b # ~9GB, lightweight
ollama pull qwen3:8b # ~5GB, ultra-light
# Test
ollama run qwen3:30b-a3b "Write a 100-word SEO article about coffee"`} />
<Step num={3} title="Install ComfyUI (Image + Video)" code={`# Install ComfyUI
cd /root
git clone https://github.com/comfyanonymous/ComfyUI.git
cd ComfyUI
pip install -r requirements.txt
# Download image models
cd models/checkpoints/
# Stable Diffusion 3.5
wget https://huggingface.co/stabilityai/stable-diffusion-3.5-large/resolve/main/sd3.5_large.safetensors
# Download FLUX.1 (if desired)
# wget from HuggingFace...
# Download video models
cd /root/ComfyUI/models/
# Install Wan2GP for optimized video gen
cd /root
git clone https://github.com/deepbeepmeep/Wan2GP.git
cd Wan2GP && pip install -r requirements.txt
# Start ComfyUI
cd /root/ComfyUI
python main.py --listen 0.0.0.0 --port 8188 &`} />
<Step num={4} title="Create Persistent SSH Tunnel from Hostinger" code={`# On Hostinger VPS — install autossh
apt install autossh
# Generate SSH key (if not done)
ssh-keygen -t ed25519 -f /root/.ssh/vastai_key
# Copy key to Vast.ai
ssh-copy-id -i /root/.ssh/vastai_key -p PORT root@VAST_IP
# Create systemd service for persistent tunnel
cat > /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`} />
</Section>
<Section title="Phase 3: Connect Everything">
<Step num={1} title="Update LiteLLM config to use tunnel" code={`# litellm_config.yaml — now uses localhost (via tunnel)
model_list:
- model_name: qwen3-32b
litellm_params:
model: ollama/qwen3:32b
api_base: http://localhost:11434
- model_name: qwen3-30b-moe
litellm_params:
model: ollama/qwen3:30b-a3b
api_base: http://localhost:11434
# Restart LiteLLM
docker compose restart litellm`} />
<Step num={2} title="Configure Flowise for IGNY8" code={`# In Flowise UI (flowise.yourdomain.com):
# 1. Add ChatOllama node → set base URL: http://litellm:4000
# 2. Set model: qwen3-30b-moe (for content writing)
# 3. Add Chroma vector store → URL: http://chromadb:8000
# 4. Build your IGNY8 content pipeline:
# Prompt → Qwen3 → SEO optimizer → Output
# For image generation in IGNY8:
# Use HTTP Request node → http://localhost:8188/api/prompt
# Send ComfyUI workflow JSON for image generation`} />
<Step num={3} title="Test the Full Pipeline" code={`# Test LLM via LiteLLM
curl http://localhost:4000/v1/chat/completions \\
-H "Content-Type: application/json" \\
-H "Authorization: Bearer sk-your-key" \\
-d '{
"model": "qwen3-30b-moe",
"messages": [{"role": "user", "content": "Write SEO meta for a coffee shop"}]
}'
# Test ComfyUI image gen
curl http://localhost:8188/api/prompt \\
-H "Content-Type: application/json" \\
-d '{"prompt": {...comfyui_workflow_json...}}'
# Test Open WebUI
# Visit chat.yourdomain.com → should connect to Ollama models`} />
</Section>
</div>
)}
{tab === "costs" && (
<div>
<Section title="Monthly Cost Breakdown" defaultOpen={true}>
<div className="space-y-1 mb-4">
<CostRow item="Hostinger VPS (KVM 4)" monthly="~$16-25/mo" notes="16GB RAM, 4 vCPU — Plesk + AI stack" />
<CostRow item="Vast.ai GPU (m:49870)" monthly="~$200/mo" notes="2x RTX 3090, 48GB VRAM — 24/7" />
<CostRow item="Domains / SSL" monthly="~$5/mo" notes="Subdomains for services" />
<CostRow item="Plesk License" monthly="~$15/mo" notes="Web Admin Edition (or use free alternatives)" />
</div>
<div className="bg-gray-900 text-white p-4 rounded-xl">
<div className="flex justify-between items-center">
<span className="font-bold text-lg">Total Monthly</span>
<span className="font-black text-2xl text-green-400">~$235-245/mo</span>
</div>
<p className="text-xs text-gray-400 mt-1">For unlimited AI text + image + video generation</p>
</div>
</Section>
<Section title="vs. API Costs Comparison">
<div className="space-y-3">
<div className="bg-red-50 border border-red-200 p-3 rounded-lg">
<p className="font-bold text-sm text-red-800">If Using APIs Instead:</p>
<div className="text-xs text-red-700 mt-2 space-y-1">
<p> OpenAI GPT-4o: ~$0.005/1K tokens 1M tokens/day = $150/mo just for text</p>
<p> Midjourney: $30/mo (limited) or $0.01-0.04/image</p>
<p> Runway Gen-3: $0.05/sec video 100 videos/mo = $250/mo</p>
<p> DALL-E 3: $0.04/image 500 images/mo = $20/mo</p>
<p className="font-bold mt-2">Conservative estimate: $400-600+/month with scale</p>
</div>
</div>
<div className="bg-green-50 border border-green-200 p-3 rounded-lg">
<p className="font-bold text-sm text-green-800">Your Self-Hosted Setup:</p>
<div className="text-xs text-green-700 mt-2 space-y-1">
<p> Unlimited text generation $0 marginal cost</p>
<p> Unlimited image generation $0 marginal cost</p>
<p> Unlimited video generation $0 marginal cost</p>
<p> Fixed cost regardless of usage volume</p>
<p className="font-bold mt-2">Fixed: ~$240/month scales to infinity</p>
</div>
</div>
</div>
</Section>
<Section title="When This Pays for Itself">
<div className="bg-gray-50 p-4 rounded-lg text-xs space-y-2">
<p><strong>Break-even point:</strong> Once IGNY8 processes ~50+ articles/month with images, self-hosting is cheaper than APIs.</p>
<p><strong>At scale:</strong> If IGNY8 generates 500+ articles + 1000+ images + 100+ videos per month, you're saving $300-500+/month vs APIs.</p>
<p><strong>Added bonus:</strong> No rate limits, no API key management, no vendor lock-in, full data privacy.</p>
<p><strong>Revenue potential:</strong> Sell the same infrastructure as a service to Alorig clients — chat.yourdomain.com as a white-label AI assistant.</p>
</div>
</Section>
</div>
)}
<div className="mt-8 bg-gray-50 rounded-xl p-4 text-xs text-gray-500">
<p className="font-bold text-gray-700 mb-2">Architecture Summary</p>
<p>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.</p>
</div>
</div>
);
}

View File

@@ -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**

View File

@@ -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 <head> 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 + `<head>` 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 `<head>` |
| 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 `<head>` 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*

View File

@@ -0,0 +1,578 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1200">
<title>IGNY8 Linker Module — SAG Authority Flow</title>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root {
--bg: #0a0e1a;
--surface: #111827;
--surface-light: #1a2236;
--border: #2a3654;
--text: #e2e8f0;
--text-muted: #94a3b8;
--text-dim: #64748b;
--homepage: #f59e0b;
--hub: #3b82f6;
--blog: #10b981;
--product: #ec4899;
--service: #8b5cf6;
--term: #06b6d4;
--category: #f97316;
--brand: #ef4444;
--comparison: #14b8a6;
--vertical-up: #fbbf24;
--vertical-down: #60a5fa;
--sibling: #34d399;
--cross-cluster: #f472b6;
--taxonomy-ctx: #22d3ee;
--breadcrumb: #a78bfa;
--related: #fb923c;
--ext-t1: #fcd34d;
--ext-t2: #93c5fd;
--ext-t3: #a5b4fc;
--ext-t4: #86efac;
--ext-t5: #fca5a5;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: var(--bg);
color: var(--text);
font-family: 'Outfit', sans-serif;
overflow-x: hidden;
min-height: 100vh;
}
.header {
border-bottom: 1px solid var(--border);
padding: 14px 24px;
display: flex;
align-items: center;
justify-content: space-between;
background: linear-gradient(180deg, var(--surface-light) 0%, var(--bg) 100%);
}
.header-left { display: flex; align-items: center; gap: 14px; }
.logo {
width: 36px; height: 36px; border-radius: 10px;
background: linear-gradient(135deg, #3b82f6, #8b5cf6);
display: flex; align-items: center; justify-content: center;
font-size: 16px; font-weight: 800; color: #fff;
}
.header-title { font-size: 16px; font-weight: 700; letter-spacing: -0.3px; }
.header-sub { font-size: 11px; color: var(--text-dim); font-family: 'JetBrains Mono', monospace; }
.view-toggle {
display: flex; gap: 4px; background: var(--surface); border-radius: 8px; padding: 3px;
}
.view-btn {
padding: 6px 14px; border-radius: 6px; border: none;
background: transparent; color: var(--text-dim);
font-size: 11px; font-weight: 600; cursor: pointer;
font-family: 'Outfit', sans-serif; text-transform: uppercase; letter-spacing: 0.5px;
transition: all 0.2s;
}
.view-btn.active {
background: linear-gradient(135deg, #3b82f6, #6366f1); color: #fff;
}
.layout { display: flex; height: calc(100vh - 65px); }
.sidebar {
width: 220px; border-right: 1px solid var(--border);
padding: 16px; overflow-y: auto; background: var(--surface);
flex-shrink: 0;
}
.sidebar-label {
font-size: 9px; font-weight: 700; color: var(--text-dim);
letter-spacing: 1.5px; margin-bottom: 10px; margin-top: 4px;
}
.filter-btn {
display: flex; align-items: center; gap: 8px; width: 100%;
padding: 7px 10px; margin-bottom: 3px; border-radius: 6px;
border: 1px solid transparent; background: transparent;
color: var(--text-muted); font-size: 10px; font-weight: 500;
cursor: pointer; text-align: left; font-family: 'Outfit', sans-serif;
transition: all 0.2s;
}
.filter-btn:hover { background: rgba(255,255,255,0.03); }
.filter-btn.active { border-color: rgba(255,255,255,0.1); }
.filter-dot {
width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0;
}
.divider { height: 1px; background: var(--border); margin: 14px 0; }
.page-type-item {
display: flex; align-items: center; gap: 8px; padding: 4px 10px; margin-bottom: 2px;
}
.page-type-dot {
width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0;
}
.page-type-label { font-size: 10px; color: var(--text-muted); }
.page-type-count { font-size: 8px; color: var(--text-dim); font-family: 'JetBrains Mono', monospace; }
.health-box {
padding: 10px; border-radius: 8px; margin-top: 4px;
}
.health-row { display: flex; justify-content: space-between; margin-bottom: 6px; }
.health-label { font-size: 10px; color: var(--text-muted); }
.health-value { font-size: 12px; font-weight: 700; font-family: 'JetBrains Mono', monospace; }
.health-bar { height: 4px; background: var(--border); border-radius: 2px; overflow: hidden; }
.health-fill { height: 100%; border-radius: 2px; }
.health-stats {
margin-top: 8px; padding: 8px 10px; border-radius: 6px;
}
.health-stat { font-size: 9px; color: var(--text-dim); margin-bottom: 2px; }
.health-stat span { font-weight: 700; }
.canvas-area { flex: 1; position: relative; overflow: hidden; }
.stats-bar {
position: absolute; top: 12px; left: 50%; transform: translateX(-50%); z-index: 10;
display: flex; gap: 8px; background: rgba(17,24,39,0.9); border-radius: 10px;
padding: 6px 12px; border: 1px solid var(--border); backdrop-filter: blur(8px);
}
.stat-item {
text-align: center; padding: 2px 10px;
border-right: 1px solid var(--border);
}
.stat-item:last-child { border-right: none; }
.stat-value { font-size: 16px; font-weight: 800; font-family: 'JetBrains Mono', monospace; }
.stat-label { font-size: 7px; color: var(--text-dim); letter-spacing: 0.5px; }
svg text { user-select: none; }
.link-line { transition: opacity 0.35s ease; }
.node-group { cursor: pointer; transition: opacity 0.35s ease; }
@keyframes pulse-ring {
0%, 100% { r: 58; opacity: 0.25; }
50% { r: 66; opacity: 0.08; }
}
@keyframes flow-dot {
0% { offset-distance: 0%; opacity: 0; }
10% { opacity: 1; }
90% { opacity: 1; }
100% { offset-distance: 100%; opacity: 0; }
}
</style>
</head>
<body>
<!-- Header -->
<div class="header">
<div class="header-left">
<div class="logo"></div>
<div>
<div class="header-title">IGNY8 Linker Module</div>
<div class="header-sub">SAG Authority Flow Visualization</div>
</div>
</div>
<div class="view-toggle">
<button class="view-btn active" data-view="internal">Internal</button>
<button class="view-btn" data-view="external">External</button>
<button class="view-btn" data-view="combined">Combined</button>
</div>
</div>
<div class="layout">
<!-- Sidebar -->
<div class="sidebar" id="sidebar"></div>
<!-- Canvas -->
<div class="canvas-area">
<div class="stats-bar" id="stats-bar"></div>
<svg id="canvas" width="100%" height="100%" viewBox="0 0 1020 720" preserveAspectRatio="xMidYMid meet"></svg>
</div>
</div>
<script>
(function() {
// ─── STATE ───
let activeFilter = 'all';
let activeView = 'internal';
// ─── COLORS ───
const C = {
homepage:'#f59e0b', hub:'#3b82f6', blog:'#10b981', product:'#ec4899',
service:'#8b5cf6', term:'#06b6d4', category:'#f97316', brand:'#ef4444',
comparison:'#14b8a6',
verticalUp:'#fbbf24', verticalDown:'#60a5fa', sibling:'#34d399',
crossCluster:'#f472b6', taxonomyCtx:'#22d3ee', breadcrumb:'#a78bfa', related:'#fb923c',
extT1:'#fcd34d', extT2:'#93c5fd', extT3:'#a5b4fc', extT4:'#86efac', extT5:'#fca5a5',
text:'#e2e8f0', muted:'#94a3b8', dim:'#64748b', border:'#2a3654',
bg:'#0a0e1a', surface:'#111827'
};
// ─── DATA ───
const filters = [
{ key:'all', label:'All Links', color: C.text },
{ key:'vertical', label:'Vertical (Hub ↕ Blog)', color: C.verticalUp },
{ key:'sibling', label:'Sibling (Blog ↔ Blog)', color: C.sibling },
{ key:'cross', label:'Cross-Cluster (Hub ↔ Hub)', color: C.crossCluster },
{ key:'taxonomy', label:'Taxonomy (Term → Hubs)', color: C.taxonomyCtx },
{ key:'breadcrumb', label:'Breadcrumb (Structural)', color: C.breadcrumb },
{ key:'related', label:'Related (Cross-Cluster)', color: C.related },
];
const pageTypes = [
{ type:'homepage', label:'Homepage', count:'1 page' },
{ type:'hub', label:'Cluster Hubs', count:'12 pages' },
{ type:'blog', label:'Blog Posts', count:'36 pages' },
{ type:'term', label:'Term Pages', count:'24 pages' },
{ type:'product', label:'Products', count:'50 pages' },
{ type:'service', label:'Services', count:'6 pages' },
{ type:'category', label:'Categories', count:'4 pages' },
{ type:'brand', label:'Brand Pages', count:'3 pages' },
{ type:'comparison', label:'Comparisons', count:'5 pages' },
];
const nodes = [
{ id:'home', x:500, y:95, label:'Homepage', type:'homepage', tier:'T1', info:'15 outbound', size:54 },
{ id:'cat1', x:160, y:178, label:'Category: Foot', type:'category', info:'8 links', size:34 },
{ id:'cat2', x:840, y:178, label:'Category: Neck', type:'category', info:'6 links', size:34 },
{ id:'hub1', x:300, y:295, label:'Foot × Neuro', type:'hub', tier:'T2', info:'Hub · 12 links', size:46 },
{ id:'hub2', x:500, y:198, label:'EMS × Foot', type:'hub', tier:'T2', info:'Hub · 10 links', size:44 },
{ id:'hub3', x:700, y:295, label:'Heated × Neck', type:'hub', tier:'T3', info:'Hub · 9 links', size:42 },
{ id:'term1', x:155, y:300, label:'Neuropathy', type:'term', info:'→ 3 hubs', size:34 },
{ id:'term2', x:845, y:300, label:'Heated', type:'term', info:'→ 2 hubs', size:34 },
{ id:'blog1', x:235, y:462, label:'Doctor Picks', type:'blog', tier:'T4', info:'6 links', size:32 },
{ id:'blog2', x:330, y:430, label:'EMS vs TENS', type:'blog', tier:'T4', info:'5 links', size:32 },
{ id:'blog3', x:395, y:478, label:'Does It Help?', type:'blog', tier:'T4', info:'4 links', size:32 },
{ id:'blog4', x:625, y:430, label:'Best Heated', type:'blog', tier:'T4', info:'5 links', size:32 },
{ id:'blog5', x:720, y:462, label:'Neck Pain Fix', type:'blog', tier:'T4', info:'4 links', size:32 },
{ id:'blog6', x:575, y:478, label:'Heat Therapy', type:'blog', tier:'T4', info:'4 links', size:32 },
{ id:'prod1', x:175, y:418, label:'RENPHO Pro', type:'product', info:'3 links', size:30 },
{ id:'prod2', x:825, y:418, label:'Homedics Heat', type:'product', info:'3 links', size:30 },
{ id:'comp1', x:500, y:558, label:'Brand Compare', type:'comparison', tier:'T5', info:'8 links', size:34 },
];
const links = [
// Type 1: Vertical Up — Blog → Hub (mandatory)
{ from:'blog1', to:'hub1', type:'vertical', color:C.verticalUp, label:'MANDATORY' },
{ from:'blog2', to:'hub1', type:'vertical', color:C.verticalUp },
{ from:'blog3', to:'hub1', type:'vertical', color:C.verticalUp },
{ from:'blog4', to:'hub3', type:'vertical', color:C.verticalUp, label:'MANDATORY' },
{ from:'blog5', to:'hub3', type:'vertical', color:C.verticalUp },
{ from:'blog6', to:'hub3', type:'vertical', color:C.verticalUp },
// Type 2: Vertical Down — Hub → Blog/Product
{ from:'hub1', to:'blog1', type:'vertical', color:C.verticalDown },
{ from:'hub1', to:'blog2', type:'vertical', color:C.verticalDown },
{ from:'hub3', to:'blog4', type:'vertical', color:C.verticalDown },
{ from:'hub3', to:'blog5', type:'vertical', color:C.verticalDown },
{ from:'hub1', to:'prod1', type:'vertical', color:C.verticalDown },
{ from:'hub3', to:'prod2', type:'vertical', color:C.verticalDown },
// Type 3: Sibling — Blog ↔ Blog
{ from:'blog1', to:'blog2', type:'sibling', color:C.sibling, label:'MAX 2', curve:-22 },
{ from:'blog2', to:'blog3', type:'sibling', color:C.sibling, curve:-18 },
{ from:'blog4', to:'blog5', type:'sibling', color:C.sibling, label:'MAX 2', curve:-22 },
// Type 4: Cross-Cluster — Hub ↔ Hub
{ from:'hub1', to:'hub3', type:'cross', color:C.crossCluster, label:'SHARED: "Foot"', curve:35 },
{ from:'hub1', to:'hub2', type:'cross', color:C.crossCluster, curve:20 },
{ from:'hub2', to:'hub3', type:'cross', color:C.crossCluster, curve:20 },
// Type 5: Taxonomy — Term → Hubs
{ from:'term1', to:'hub1', type:'taxonomy', color:C.taxonomyCtx, label:'ALL HUBS' },
{ from:'term1', to:'hub2', type:'taxonomy', color:C.taxonomyCtx },
{ from:'term2', to:'hub3', type:'taxonomy', color:C.taxonomyCtx, label:'ALL HUBS' },
{ from:'term2', to:'hub2', type:'taxonomy', color:C.taxonomyCtx },
// Type 6: Breadcrumb
{ from:'home', to:'hub1', type:'breadcrumb', color:C.breadcrumb },
{ from:'home', to:'hub2', type:'breadcrumb', color:C.breadcrumb },
{ from:'home', to:'hub3', type:'breadcrumb', color:C.breadcrumb },
{ from:'home', to:'cat1', type:'breadcrumb', color:C.breadcrumb },
{ from:'home', to:'cat2', type:'breadcrumb', color:C.breadcrumb },
// Type 7: Related (cross-cluster blogs)
{ from:'blog3', to:'blog4', type:'related', color:C.related, label:'CROSS-CLUSTER', curve:25 },
{ from:'blog6', to:'blog2', type:'related', color:C.related, curve:-25 },
];
const externalLinks = [
{ target:'home', count:'10-30', dr:'30-60', tier:'T1', color:C.extT1, ox:-70, oy:-50 },
{ target:'hub1', count:'5-15', dr:'25-50', tier:'T2', color:C.extT2, ox:-75, oy:-45 },
{ target:'hub2', count:'5-15', dr:'25-50', tier:'T2', color:C.extT2, ox:-70, oy:-50 },
{ target:'hub3', count:'5-15', dr:'25-50', tier:'T2', color:C.extT2, ox:75, oy:-45 },
{ target:'blog1', count:'1-2', dr:'20-35', tier:'T4', color:C.extT4, ox:-55, oy:-35 },
{ target:'comp1', count:'2-6', dr:'25-40', tier:'T5', color:C.extT5, ox:-70, oy:-45 },
];
// ─── HELPERS ───
function nodeById(id) { return nodes.find(n => n.id === id); }
function svgEl(tag, attrs, parent) {
const el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (const [k, v] of Object.entries(attrs || {})) {
if (k === 'textContent') el.textContent = v;
else el.setAttribute(k, v);
}
if (parent) parent.appendChild(el);
return el;
}
function isVisible(linkType) {
if (activeFilter === 'all') return true;
return linkType === activeFilter;
}
function curvePath(x1, y1, x2, y2, curveAmt) {
if (!curveAmt) return `M${x1},${y1} L${x2},${y2}`;
const dx = x2 - x1, dy = y2 - y1;
const len = Math.sqrt(dx*dx + dy*dy) || 1;
const mx = (x1+x2)/2, my = (y1+y2)/2;
const cx = mx + (dy/len)*curveAmt;
const cy = my - (dx/len)*curveAmt;
return `M${x1},${y1} Q${cx},${cy} ${x2},${y2}`;
}
// ─── RENDER SIDEBAR ───
function renderSidebar() {
const sb = document.getElementById('sidebar');
sb.innerHTML = '';
// Link type filters
const l1 = document.createElement('div'); l1.className = 'sidebar-label'; l1.textContent = 'LINK TYPES'; sb.appendChild(l1);
filters.forEach(f => {
const btn = document.createElement('button');
btn.className = 'filter-btn' + (activeFilter === f.key ? ' active' : '');
btn.style.borderColor = activeFilter === f.key ? f.color + '40' : 'transparent';
btn.style.background = activeFilter === f.key ? f.color + '12' : 'transparent';
btn.style.color = activeFilter === f.key ? f.color : '';
btn.innerHTML = `<div class="filter-dot" style="background:${f.color}"></div>${f.label}`;
btn.onclick = () => { activeFilter = activeFilter === f.key ? 'all' : f.key; render(); };
sb.appendChild(btn);
});
// Divider
sb.appendChild(Object.assign(document.createElement('div'), { className: 'divider' }));
// Page types
const l2 = document.createElement('div'); l2.className = 'sidebar-label'; l2.textContent = 'PAGE TYPES'; sb.appendChild(l2);
pageTypes.forEach(p => {
const d = document.createElement('div'); d.className = 'page-type-item';
d.innerHTML = `<div class="page-type-dot" style="background:${C[p.type]}40;border:1.5px solid ${C[p.type]}"></div>
<div><div class="page-type-label">${p.label}</div><div class="page-type-count">${p.count}</div></div>`;
sb.appendChild(d);
});
sb.appendChild(Object.assign(document.createElement('div'), { className: 'divider' }));
// Health
const l3 = document.createElement('div'); l3.className = 'sidebar-label'; l3.textContent = 'HEALTH'; sb.appendChild(l3);
const hbox = document.createElement('div'); hbox.className = 'health-box';
hbox.style.background = C.hub + '08'; hbox.style.border = `1px solid ${C.hub}20`;
hbox.innerHTML = `
<div class="health-row"><span class="health-label">Link Coverage</span><span class="health-value" style="color:${C.hub}">87/100</span></div>
<div class="health-bar"><div class="health-fill" style="width:87%;background:linear-gradient(90deg,${C.hub},${C.term})"></div></div>`;
sb.appendChild(hbox);
const hs = document.createElement('div'); hs.className = 'health-stats';
hs.style.background = C.sibling + '08';
hs.innerHTML = `
<div class="health-stat">Orphan Pages: <span style="color:#ef4444">0</span></div>
<div class="health-stat">Broken Links: <span style="color:#ef4444">2</span></div>
<div class="health-stat">Over-linked: <span style="color:${C.homepage}">1</span></div>
<div class="health-stat">Avg Links/Page: <span style="color:${C.hub}">6.2</span></div>`;
sb.appendChild(hs);
}
// ─── RENDER STATS BAR ───
function renderStats() {
const bar = document.getElementById('stats-bar');
const stats = [
{ value:'215', label:'Total Links', color:C.hub },
{ value:'141', label:'Internal', color:C.sibling },
{ value:'83', label:'External', color:C.crossCluster },
{ value:'7', label:'Link Types', color:C.term },
{ value:'0', label:'Orphans', color:C.sibling },
];
bar.innerHTML = stats.map((s,i) =>
`<div class="stat-item" ${i===stats.length-1?'style="border-right:none"':''}>
<div class="stat-value" style="color:${s.color}">${s.value}</div>
<div class="stat-label">${s.label}</div>
</div>`
).join('');
}
// ─── RENDER SVG CANVAS ───
function renderCanvas() {
const svg = document.getElementById('canvas');
svg.innerHTML = '';
// Defs
const defs = svgEl('defs', {}, svg);
defs.innerHTML = `
<marker id="ah" markerWidth="8" markerHeight="6" refX="7" refY="3" orient="auto">
<polygon points="0 0, 8 3, 0 6" fill="${C.dim}"/>
</marker>
<radialGradient id="glow-c" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="${C.homepage}12"/><stop offset="100%" stop-color="transparent"/>
</radialGradient>`;
// Background glow + rings
svgEl('circle', { cx:500, cy:330, r:300, fill:'url(#glow-c)' }, svg);
[80,150,220,290,360].forEach(r => svgEl('circle', { cx:500, cy:330, r, fill:'none', stroke:C.border+'28', 'stroke-width':'0.5', 'stroke-dasharray':'4,8' }, svg));
// Cluster boundaries
const clG = svgEl('g', { opacity:'0.5' }, svg);
svgEl('rect', { x:185, y:255, width:270, height:265, rx:16, fill:'none', stroke:C.hub+'20', 'stroke-width':'1', 'stroke-dasharray':'6,4' }, clG);
svgEl('text', { x:195, y:272, fill:C.hub+'35', 'font-size':'8', 'font-family':"'JetBrains Mono', monospace", textContent:'CLUSTER: Foot × Neuropathy' }, clG);
svgEl('rect', { x:535, y:255, width:270, height:265, rx:16, fill:'none', stroke:C.hub+'20', 'stroke-width':'1', 'stroke-dasharray':'6,4' }, clG);
svgEl('text', { x:545, y:272, fill:C.hub+'35', 'font-size':'8', 'font-family':"'JetBrains Mono', monospace", textContent:'CLUSTER: Heated × Neck' }, clG);
// ─── DRAW LINKS ───
const linkGroup = svgEl('g', { id:'link-layer' }, svg);
if (activeView === 'internal' || activeView === 'combined') {
links.forEach(lk => {
const from = nodeById(lk.from), to = nodeById(lk.to);
if (!from || !to) return;
const vis = isVisible(lk.type);
const g = svgEl('g', { class:'link-line', opacity: vis ? '0.75' : '0.05' }, linkGroup);
const dash = lk.type === 'breadcrumb' ? '4,4' : lk.type === 'related' ? '8,4' : 'none';
const path = curvePath(from.x, from.y, to.x, to.y, lk.curve || (lk.type==='cross'?30 : 0));
const pathId = 'p-' + lk.from + '-' + lk.to;
svgEl('path', { id: pathId, d: path, fill:'none', stroke: lk.color, 'stroke-width': vis && activeFilter !== 'all' ? '2.2' : '1.2', 'stroke-dasharray': dash }, g);
// Animated dot for active filter
if (vis && activeFilter !== 'all') {
const dot = svgEl('circle', { r:'3', fill: lk.color, opacity:'0.9' }, g);
const anim = svgEl('animateMotion', { dur: '2.5s', repeatCount:'indefinite' }, dot);
svgEl('mpath', { href: '#'+pathId }, anim);
}
// Label
if (lk.label && vis) {
const mx = (from.x + to.x) / 2, my = (from.y + to.y) / 2;
const dx = to.x-from.x, dy = to.y-from.y, len = Math.sqrt(dx*dx+dy*dy)||1;
const off = lk.curve || (lk.type==='cross'?30:0);
const cx = mx + (dy/len)*off*0.5, cy = my - (dx/len)*off*0.5;
svgEl('rect', { x:cx-38, y:cy-9, width:76, height:15, rx:3, fill:C.bg, stroke:lk.color+'35', 'stroke-width':'0.5' }, g);
svgEl('text', { x:cx, y:cy+2, 'text-anchor':'middle', fill:lk.color+'cc', 'font-size':'7', 'font-family':"'JetBrains Mono', monospace", textContent: lk.label }, g);
}
});
}
// ─── EXTERNAL LINKS ───
if (activeView === 'external' || activeView === 'combined') {
const extG = svgEl('g', { id:'ext-layer' }, svg);
externalLinks.forEach(el => {
const n = nodeById(el.target);
if (!n) return;
const sx = n.x + el.ox, sy = n.y + el.oy;
const ex = n.x + (el.ox > 0 ? 12 : -12) * (Math.abs(el.ox)/el.ox || 1);
const ey = n.y - 5;
const g = svgEl('g', {}, extG);
svgEl('line', { x1:sx, y1:sy, x2:n.x + (el.ox>0?10:-10), y2:n.y-8, stroke:el.color, 'stroke-width':'2', 'marker-end':'url(#ah)' }, g);
svgEl('rect', { x:sx-30, y:sy-18, width:60, height:26, rx:4, fill:el.color+'18', stroke:el.color+'45', 'stroke-width':'1' }, g);
svgEl('text', { x:sx, y:sy-6, 'text-anchor':'middle', fill:el.color, 'font-size':'8', 'font-weight':'600', 'font-family':"'JetBrains Mono', monospace", textContent: el.count+' links' }, g);
svgEl('text', { x:sx, y:sy+5, 'text-anchor':'middle', fill:C.dim, 'font-size':'7', 'font-family':"'JetBrains Mono', monospace", textContent: 'DR '+el.dr }, g);
svgEl('text', { x:sx, y:sy-22, 'text-anchor':'middle', fill:el.color+'90', 'font-size':'7', 'font-weight':'700', 'font-family':"'JetBrains Mono', monospace", textContent: el.tier+' EXTERNAL' }, g);
});
// Authority flow label
svgEl('text', { x:430, y:155, 'text-anchor':'middle', fill:C.homepage+'45', 'font-size':'8', 'font-family':"'JetBrains Mono', monospace", textContent:'AUTHORITY FLOWS DOWN ▼', transform:'rotate(-12 430 155)' }, extG);
svgEl('text', { x:500, y:395, 'text-anchor':'middle', fill:C.verticalUp+'35', 'font-size':'8', 'font-family':"'JetBrains Mono', monospace", textContent:'▲ AUTHORITY FLOWS UP' }, extG);
}
// ─── DRAW NODES ───
const nodeLayer = svgEl('g', { id:'node-layer' }, svg);
nodes.forEach(n => {
const col = C[n.type] || '#666';
const sz = n.size || 36;
const g = svgEl('g', { class:'node-group' }, nodeLayer);
// Outer ring
svgEl('circle', { cx:n.x, cy:n.y, r:sz, fill:col+'15', stroke:col+'55', 'stroke-width':'1.5' }, g);
svgEl('circle', { cx:n.x, cy:n.y, r:sz-5, fill:col+'08', stroke:'none' }, g);
// Tier badge
if (n.tier) {
svgEl('rect', { x:n.x+sz*0.48, y:n.y-sz+1, width:28, height:16, rx:8, fill:col }, g);
svgEl('text', { x:n.x+sz*0.48+14, y:n.y-sz+12.5, 'text-anchor':'middle', fill:'#000', 'font-size':'9', 'font-weight':'700', 'font-family':"'JetBrains Mono', monospace", textContent:n.tier }, g);
}
// Labels
const lbl = n.label.length > 15 ? n.label.slice(0,14)+'…' : n.label;
svgEl('text', { x:n.x, y:n.y-4, 'text-anchor':'middle', fill:C.text, 'font-size':'10.5', 'font-weight':'600', 'font-family':"'Outfit', sans-serif", textContent:lbl }, g);
svgEl('text', { x:n.x, y:n.y+10, 'text-anchor':'middle', fill:C.muted, 'font-size':'8', 'font-family':"'JetBrains Mono', monospace", textContent:n.type.toUpperCase() }, g);
if (n.info) {
svgEl('text', { x:n.x, y:n.y+22, 'text-anchor':'middle', fill:C.dim, 'font-size':'7.5', 'font-family':"'JetBrains Mono', monospace", textContent:n.info }, g);
}
});
// ─── LEGENDS ───
const legG = svgEl('g', {}, svg);
// Internal legend
const iLeg = [
{ color:C.verticalUp, label:'Blog → Hub (mandatory)' },
{ color:C.verticalDown, label:'Hub → Blog / Product' },
{ color:C.sibling, label:'Blog ↔ Blog (max 2)' },
{ color:C.crossCluster, label:'Hub ↔ Hub (shared attr)' },
{ color:C.taxonomyCtx, label:'Term → All Connected Hubs' },
{ color:C.breadcrumb, label:'Breadcrumb (structural)', dash:'4,4' },
{ color:C.related, label:'Related (cross-cluster)', dash:'8,4' },
];
svgEl('text', { x:30, y:562, fill:C.muted, 'font-size':'9', 'font-weight':'700', 'font-family':"'Outfit', sans-serif", 'letter-spacing':'1.5', textContent:'INTERNAL LINKS' }, legG);
iLeg.forEach((it, i) => {
svgEl('line', { x1:30, y1:578+i*17, x2:48, y2:578+i*17, stroke:it.color, 'stroke-width':'2', 'stroke-dasharray': it.dash||'none' }, legG);
svgEl('text', { x:56, y:582+i*17, fill:C.dim, 'font-size':'8.5', 'font-family':"'JetBrains Mono', monospace", textContent:it.label }, legG);
});
// External legend (when visible)
if (activeView === 'external' || activeView === 'combined') {
const eLeg = [
{ color:C.extT1, label:'T1 → Homepage (10-30)' },
{ color:C.extT2, label:'T2 → Top Hubs (5-15)' },
{ color:C.extT3, label:'T3 → Other Hubs (3-10)' },
{ color:C.extT4, label:'T4 → Select Blogs (1-4)' },
{ color:C.extT5, label:'T5 → Auth Magnets (2-6)' },
];
svgEl('text', { x:800, y:562, fill:C.muted, 'font-size':'9', 'font-weight':'700', 'font-family':"'Outfit', sans-serif", 'letter-spacing':'1.5', textContent:'EXTERNAL LINKS' }, legG);
eLeg.forEach((it, i) => {
svgEl('line', { x1:800, y1:578+i*17, x2:818, y2:578+i*17, stroke:it.color, 'stroke-width':'2' }, legG);
svgEl('text', { x:826, y:582+i*17, fill:C.dim, 'font-size':'8.5', 'font-family':"'JetBrains Mono', monospace", textContent:it.label }, legG);
});
}
// Density rule box
svgEl('rect', { x:370, y:622, width:260, height:42, rx:8, fill:C.surface, stroke:C.border, 'stroke-width':'1' }, svg);
svgEl('text', { x:500, y:639, 'text-anchor':'middle', fill:C.muted, 'font-size':'9', 'font-weight':'600', 'font-family':"'Outfit', sans-serif", textContent:'DENSITY RULE' }, svg);
svgEl('text', { x:500, y:653, 'text-anchor':'middle', fill:C.dim, 'font-size':'7.5', 'font-family':"'JetBrains Mono', monospace", textContent:'1-2 links per 300 words · No orphans · Max 8 words/anchor' }, svg);
}
// ─── VIEW TOGGLE ───
document.querySelectorAll('.view-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.view-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
activeView = btn.dataset.view;
render();
});
});
// ─── RENDER ALL ───
function render() {
renderSidebar();
renderStats();
renderCanvas();
}
render();
})();
</script>
</body>
</html>

View File

@@ -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.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff