From 701ac12d5770a77159f6691e9ba36593422c1924 Mon Sep 17 00:00:00 2001 From: cawcenter Date: Sun, 14 Dec 2025 18:51:56 -0500 Subject: [PATCH] Migrate Engines to God Mode and add Directus Shim --- god-mode/migrations/01_init_sites.sql | 22 + .../src/components/debug/DebugToolbar.tsx | 178 ++++++++ .../src/components/engine/BlockRenderer.tsx | 39 ++ .../src/components/engine/blocks/Content.tsx | 13 + .../src/components/engine/blocks/Features.tsx | 40 ++ .../src/components/engine/blocks/Hero.tsx | 38 ++ .../src/components/testing/ContentTester.tsx | 0 .../components/testing/DuplicateDetector.tsx | 0 .../src/components/testing/GrammarCheck.tsx | 0 .../src/components/testing/LinkChecker.tsx | 0 .../src/components/testing/SEOValidator.tsx | 0 .../components/testing/SchemaValidator.tsx | 0 .../src/components/testing/TestRunner.tsx | 109 +++++ .../src/components/ui/UnderConstruction.tsx | 29 ++ god-mode/src/components/ui/alert-dialog.tsx | 43 ++ god-mode/src/components/ui/badge.tsx | 35 ++ god-mode/src/components/ui/button.tsx | 55 +++ god-mode/src/components/ui/card.tsx | 78 ++++ god-mode/src/components/ui/checkbox.tsx | 20 + god-mode/src/components/ui/dialog.tsx | 31 ++ god-mode/src/components/ui/dropdown-menu.tsx | 200 ++++++++ god-mode/src/components/ui/input.tsx | 22 + god-mode/src/components/ui/label.tsx | 12 + god-mode/src/components/ui/progress.tsx | 14 + god-mode/src/components/ui/select.tsx | 20 + god-mode/src/components/ui/slider.tsx | 20 + god-mode/src/components/ui/spinner.tsx | 22 + god-mode/src/components/ui/switch.tsx | 33 ++ god-mode/src/components/ui/table.tsx | 119 +++++ god-mode/src/components/ui/tabs.tsx | 52 +++ god-mode/src/components/ui/textarea.tsx | 19 + god-mode/src/lib/analytics/metrics.ts | 0 god-mode/src/lib/analytics/tracking.ts | 0 god-mode/src/lib/assembler/data.ts | 44 ++ god-mode/src/lib/assembler/engine.ts | 68 +++ god-mode/src/lib/assembler/quality.ts | 0 god-mode/src/lib/assembler/seo.ts | 0 god-mode/src/lib/assembler/spintax.ts | 0 god-mode/src/lib/assembler/variables.ts | 0 god-mode/src/lib/cartesian/CartesianEngine.ts | 214 +++++++++ god-mode/src/lib/cartesian/GrammarEngine.ts | 49 ++ god-mode/src/lib/cartesian/HTMLRenderer.ts | 60 +++ .../src/lib/cartesian/MetadataGenerator.ts | 15 + god-mode/src/lib/cartesian/SpintaxParser.ts | 42 ++ .../src/lib/cartesian/UniquenessManager.ts | 33 ++ god-mode/src/lib/collections/config.ts | 107 +++++ god-mode/src/lib/db.ts | 16 + god-mode/src/lib/directus-enhanced.ts | 12 + god-mode/src/lib/directus/client.ts | 242 ++++++++++ god-mode/src/lib/directus/fetchers.ts | 319 +++++++++++++ god-mode/src/lib/godMode.ts | 236 ++++++++++ god-mode/src/lib/intelligence/types.ts | 38 ++ god-mode/src/lib/queue/config.ts | 44 ++ god-mode/src/lib/react-query.ts | 10 + god-mode/src/lib/schemas.ts | 404 +++++++++++++++++ god-mode/src/lib/seo/cartesian.ts | 361 +++++++++++++++ god-mode/src/lib/seo/image-generator.ts | 176 ++++++++ god-mode/src/lib/seo/velocity-scheduler.ts | 195 ++++++++ god-mode/src/lib/testing/seo.ts | 95 ++++ god-mode/src/lib/theme/config.ts | 138 ++++++ god-mode/src/lib/utils.ts | 7 + god-mode/src/lib/utils/circuit-breaker.ts | 103 +++++ god-mode/src/lib/utils/dry-run.ts | 64 +++ god-mode/src/lib/utils/logger.ts | 56 +++ god-mode/src/lib/utils/transactions.ts | 71 +++ god-mode/src/lib/validation/schemas.ts | 134 ++++++ god-mode/src/lib/variables/context.ts | 0 god-mode/src/lib/variables/interpolation.ts | 0 god-mode/src/lib/variables/templates.ts | 0 god-mode/src/lib/wordpress/WordPressClient.ts | 138 ++++++ god-mode/src/pages/api/god/[...action].ts | 426 ++++++++++++++---- god-mode/src/pages/api/seo/approve-batch.ts | 88 ++++ god-mode/src/pages/api/seo/articles.ts | 43 ++ .../src/pages/api/seo/assemble-article.ts | 224 +++++++++ .../src/pages/api/seo/generate-article.ts | 318 +++++++++++++ .../src/pages/api/seo/generate-headlines.ts | 380 ++++++++++++++++ .../src/pages/api/seo/generate-test-batch.ts | 177 ++++++++ god-mode/src/pages/api/seo/get-nearby.ts | 150 ++++++ god-mode/src/pages/api/seo/insert-links.ts | 166 +++++++ god-mode/src/pages/api/seo/process-queue.ts | 290 ++++++++++++ god-mode/src/pages/api/seo/publish-article.ts | 198 ++++++++ god-mode/src/pages/api/seo/scan-duplicates.ts | 170 +++++++ .../src/pages/api/seo/schedule-production.ts | 176 ++++++++ god-mode/src/pages/api/seo/sitemap-drip.ts | 126 ++++++ god-mode/src/pages/api/seo/stats.ts | 59 +++ god-mode/src/pages/api/system/health.ts | 22 + god-mode/src/pages/api/testing/check-links.ts | 0 .../pages/api/testing/detect-duplicates.ts | 0 .../src/pages/api/testing/validate-seo.ts | 0 god-mode/src/types/cartesian.ts | 109 +++++ god-mode/tsconfig.json | 6 +- 91 files changed, 7785 insertions(+), 97 deletions(-) create mode 100644 god-mode/migrations/01_init_sites.sql create mode 100644 god-mode/src/components/debug/DebugToolbar.tsx create mode 100644 god-mode/src/components/engine/BlockRenderer.tsx create mode 100644 god-mode/src/components/engine/blocks/Content.tsx create mode 100644 god-mode/src/components/engine/blocks/Features.tsx create mode 100644 god-mode/src/components/engine/blocks/Hero.tsx create mode 100644 god-mode/src/components/testing/ContentTester.tsx create mode 100644 god-mode/src/components/testing/DuplicateDetector.tsx create mode 100644 god-mode/src/components/testing/GrammarCheck.tsx create mode 100644 god-mode/src/components/testing/LinkChecker.tsx create mode 100644 god-mode/src/components/testing/SEOValidator.tsx create mode 100644 god-mode/src/components/testing/SchemaValidator.tsx create mode 100644 god-mode/src/components/testing/TestRunner.tsx create mode 100644 god-mode/src/components/ui/UnderConstruction.tsx create mode 100644 god-mode/src/components/ui/alert-dialog.tsx create mode 100644 god-mode/src/components/ui/badge.tsx create mode 100644 god-mode/src/components/ui/button.tsx create mode 100644 god-mode/src/components/ui/card.tsx create mode 100644 god-mode/src/components/ui/checkbox.tsx create mode 100644 god-mode/src/components/ui/dialog.tsx create mode 100644 god-mode/src/components/ui/dropdown-menu.tsx create mode 100644 god-mode/src/components/ui/input.tsx create mode 100644 god-mode/src/components/ui/label.tsx create mode 100644 god-mode/src/components/ui/progress.tsx create mode 100644 god-mode/src/components/ui/select.tsx create mode 100644 god-mode/src/components/ui/slider.tsx create mode 100644 god-mode/src/components/ui/spinner.tsx create mode 100644 god-mode/src/components/ui/switch.tsx create mode 100644 god-mode/src/components/ui/table.tsx create mode 100644 god-mode/src/components/ui/tabs.tsx create mode 100644 god-mode/src/components/ui/textarea.tsx create mode 100644 god-mode/src/lib/analytics/metrics.ts create mode 100644 god-mode/src/lib/analytics/tracking.ts create mode 100644 god-mode/src/lib/assembler/data.ts create mode 100644 god-mode/src/lib/assembler/engine.ts create mode 100644 god-mode/src/lib/assembler/quality.ts create mode 100644 god-mode/src/lib/assembler/seo.ts create mode 100644 god-mode/src/lib/assembler/spintax.ts create mode 100644 god-mode/src/lib/assembler/variables.ts create mode 100644 god-mode/src/lib/cartesian/CartesianEngine.ts create mode 100644 god-mode/src/lib/cartesian/GrammarEngine.ts create mode 100644 god-mode/src/lib/cartesian/HTMLRenderer.ts create mode 100644 god-mode/src/lib/cartesian/MetadataGenerator.ts create mode 100644 god-mode/src/lib/cartesian/SpintaxParser.ts create mode 100644 god-mode/src/lib/cartesian/UniquenessManager.ts create mode 100644 god-mode/src/lib/collections/config.ts create mode 100644 god-mode/src/lib/db.ts create mode 100644 god-mode/src/lib/directus-enhanced.ts create mode 100644 god-mode/src/lib/directus/client.ts create mode 100644 god-mode/src/lib/directus/fetchers.ts create mode 100644 god-mode/src/lib/godMode.ts create mode 100644 god-mode/src/lib/intelligence/types.ts create mode 100644 god-mode/src/lib/queue/config.ts create mode 100644 god-mode/src/lib/react-query.ts create mode 100644 god-mode/src/lib/schemas.ts create mode 100644 god-mode/src/lib/seo/cartesian.ts create mode 100644 god-mode/src/lib/seo/image-generator.ts create mode 100644 god-mode/src/lib/seo/velocity-scheduler.ts create mode 100644 god-mode/src/lib/testing/seo.ts create mode 100644 god-mode/src/lib/theme/config.ts create mode 100644 god-mode/src/lib/utils.ts create mode 100644 god-mode/src/lib/utils/circuit-breaker.ts create mode 100644 god-mode/src/lib/utils/dry-run.ts create mode 100644 god-mode/src/lib/utils/logger.ts create mode 100644 god-mode/src/lib/utils/transactions.ts create mode 100644 god-mode/src/lib/validation/schemas.ts create mode 100644 god-mode/src/lib/variables/context.ts create mode 100644 god-mode/src/lib/variables/interpolation.ts create mode 100644 god-mode/src/lib/variables/templates.ts create mode 100644 god-mode/src/lib/wordpress/WordPressClient.ts create mode 100644 god-mode/src/pages/api/seo/approve-batch.ts create mode 100644 god-mode/src/pages/api/seo/articles.ts create mode 100644 god-mode/src/pages/api/seo/assemble-article.ts create mode 100644 god-mode/src/pages/api/seo/generate-article.ts create mode 100644 god-mode/src/pages/api/seo/generate-headlines.ts create mode 100644 god-mode/src/pages/api/seo/generate-test-batch.ts create mode 100644 god-mode/src/pages/api/seo/get-nearby.ts create mode 100644 god-mode/src/pages/api/seo/insert-links.ts create mode 100644 god-mode/src/pages/api/seo/process-queue.ts create mode 100644 god-mode/src/pages/api/seo/publish-article.ts create mode 100644 god-mode/src/pages/api/seo/scan-duplicates.ts create mode 100644 god-mode/src/pages/api/seo/schedule-production.ts create mode 100644 god-mode/src/pages/api/seo/sitemap-drip.ts create mode 100644 god-mode/src/pages/api/seo/stats.ts create mode 100644 god-mode/src/pages/api/system/health.ts create mode 100644 god-mode/src/pages/api/testing/check-links.ts create mode 100644 god-mode/src/pages/api/testing/detect-duplicates.ts create mode 100644 god-mode/src/pages/api/testing/validate-seo.ts create mode 100644 god-mode/src/types/cartesian.ts diff --git a/god-mode/migrations/01_init_sites.sql b/god-mode/migrations/01_init_sites.sql new file mode 100644 index 0000000..011adff --- /dev/null +++ b/god-mode/migrations/01_init_sites.sql @@ -0,0 +1,22 @@ +-- Create sites table for Multi-Tenancy +CREATE TABLE IF NOT EXISTS sites ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid (), + domain VARCHAR(255) UNIQUE NOT NULL, + status VARCHAR(50) DEFAULT 'active', -- active, maintenance, archived + config JSONB DEFAULT '{}', -- branding, SEO settings + client_id VARCHAR(255), + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Index for fast domain lookups +CREATE INDEX IF NOT EXISTS idx_sites_domain ON sites (domain); + +-- Insert the Platform/Admin site default +INSERT INTO + sites (domain, status, config) +VALUES ( + 'spark.jumpstartscaling.com', + 'active', + '{"type": "admin"}' + ) ON CONFLICT (domain) DO NOTHING; \ No newline at end of file diff --git a/god-mode/src/components/debug/DebugToolbar.tsx b/god-mode/src/components/debug/DebugToolbar.tsx new file mode 100644 index 0000000..795cc2d --- /dev/null +++ b/god-mode/src/components/debug/DebugToolbar.tsx @@ -0,0 +1,178 @@ +import React, { useEffect, useState } from 'react'; +import { useStore } from '@nanostores/react'; +import { debugIsOpen, activeTab, logs, type LogEntry } from '../../stores/debugStore'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { getDirectusClient } from '@/lib/directus/client'; + +// Create a client for the devtools if one doesn't exist in context +// (Ideally this component is inside the main QueryClientProvider, but we'll see) +const queryClient = new QueryClient(); + +export default function DebugToolbar() { + const isOpen = useStore(debugIsOpen); + const currentTab = useStore(activeTab); + const logEntries = useStore(logs); + const [backendStatus, setBackendStatus] = useState<'checking' | 'online' | 'error'>('checking'); + const [latency, setLatency] = useState(null); + + useEffect(() => { + if (isOpen && currentTab === 'backend') { + checkBackend(); + } + }, [isOpen, currentTab]); + + const checkBackend = async () => { + setBackendStatus('checking'); + const start = performance.now(); + try { + const client = getDirectusClient(); + await client.request(() => ({ + path: '/server/ping', + method: 'GET' + })); + setLatency(Math.round(performance.now() - start)); + setBackendStatus('online'); + } catch (e) { + setBackendStatus('error'); + } + }; + + if (!isOpen) { + return ( + + ); + } + + return ( +
+ {/* Header */} +
+
+ ⚡ Spark Debug +
+ {(['console', 'backend', 'network'] as const).map(tab => ( + + ))} +
+
+ +
+ + {/* Content */} +
+ + {/* Console Tab */} + {currentTab === 'console' && ( +
+ {logEntries.length === 0 && ( +
No logs captured yet...
+ )} + {logEntries.map((log) => ( +
+ [{log.timestamp}] + + {log.type} + + + {log.messages.join(' ')} + +
+ ))} +
+ +
+
+ )} + + {/* Backend Tab */} + {currentTab === 'backend' && ( +
+
+ {backendStatus === 'online' ? '● Online' : + backendStatus === 'error' ? '✖ Error' : '● Checking...'} +
+ +
+

+ Directus URL: {import.meta.env.PUBLIC_DIRECTUS_URL} +

+ {latency && ( +

+ Latency: {latency}ms +

+ )} +
+ + +
+ )} + + {/* Network / React Query Tab */} + {currentTab === 'network' && ( +
+
+ {/* + React Query Devtools needs a QueryClientProvider context. + In Astro, components are islands. If this island doesn't share context with the main app + (which it likely won't if they are separate roots), we might see empty devtools. + However, putting it here is the best attempt. + */} +
+

React Query Devtools

+

+ (If empty, data fetching might be happening Server-Side or in a different Context) +

+
+
+ {/* We force mount devtools panel here if possible */} + + + +
+ )} + +
+
+ ); +} diff --git a/god-mode/src/components/engine/BlockRenderer.tsx b/god-mode/src/components/engine/BlockRenderer.tsx new file mode 100644 index 0000000..46acf81 --- /dev/null +++ b/god-mode/src/components/engine/BlockRenderer.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import Hero from './blocks/Hero'; +import Content from './blocks/Content'; +import Features from './blocks/Features'; + +interface Block { + id: string; + block_type: string; + block_config: any; +} + +interface BlockRendererProps { + blocks: Block[]; +} + +export default function BlockRenderer({ blocks }: BlockRendererProps) { + if (!blocks || !Array.isArray(blocks)) return null; + + return ( +
+ {blocks.map(block => { + switch (block.block_type) { + case 'hero': + return ; + case 'content': + return ; + case 'features': + return ; + case 'cta': + // reuse Hero styled as CTA or simple banner + return ; + default: + console.warn(`Unknown block type: ${block.block_type}`); + return null; + } + })} +
+ ); +} diff --git a/god-mode/src/components/engine/blocks/Content.tsx b/god-mode/src/components/engine/blocks/Content.tsx new file mode 100644 index 0000000..f1816c6 --- /dev/null +++ b/god-mode/src/components/engine/blocks/Content.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +interface ContentProps { + content: string; +} + +export default function Content({ content }: ContentProps) { + return ( +
+
+
+ ); +} diff --git a/god-mode/src/components/engine/blocks/Features.tsx b/god-mode/src/components/engine/blocks/Features.tsx new file mode 100644 index 0000000..257aa5e --- /dev/null +++ b/god-mode/src/components/engine/blocks/Features.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { CheckCircle2 } from 'lucide-react'; + +interface FeatureItem { + title: string; + desc: string; + icon?: string; +} + +interface FeaturesProps { + items: FeatureItem[]; + layout?: 'grid' | 'list'; +} + +export default function Features({ items, layout = 'grid' }: FeaturesProps) { + return ( +
+
+
+ {items?.map((item, i) => ( + + +
+ +
+ {item.title} +
+ +

+ {item.desc} +

+
+
+ ))} +
+
+
+ ); +} diff --git a/god-mode/src/components/engine/blocks/Hero.tsx b/god-mode/src/components/engine/blocks/Hero.tsx new file mode 100644 index 0000000..b1501f7 --- /dev/null +++ b/god-mode/src/components/engine/blocks/Hero.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Button } from '@/components/ui/button'; + +interface HeroProps { + title: string; + subtitle?: string; + bg?: string; + ctaLabel?: string; + ctaUrl?: string; +} + +export default function Hero({ title, subtitle, bg, ctaLabel, ctaUrl }: HeroProps) { + const bgClass = bg === 'dark' ? 'bg-zinc-900 text-white' : + bg === 'image' ? 'bg-zinc-800 text-white' : // Placeholder for image logic + 'bg-white text-zinc-900'; + + return ( +
+
+

+ {title} +

+ {subtitle && ( +

+ {subtitle} +

+ )} + {(ctaLabel && ctaUrl) && ( +
+ +
+ )} +
+
+ ); +} diff --git a/god-mode/src/components/testing/ContentTester.tsx b/god-mode/src/components/testing/ContentTester.tsx new file mode 100644 index 0000000..e69de29 diff --git a/god-mode/src/components/testing/DuplicateDetector.tsx b/god-mode/src/components/testing/DuplicateDetector.tsx new file mode 100644 index 0000000..e69de29 diff --git a/god-mode/src/components/testing/GrammarCheck.tsx b/god-mode/src/components/testing/GrammarCheck.tsx new file mode 100644 index 0000000..e69de29 diff --git a/god-mode/src/components/testing/LinkChecker.tsx b/god-mode/src/components/testing/LinkChecker.tsx new file mode 100644 index 0000000..e69de29 diff --git a/god-mode/src/components/testing/SEOValidator.tsx b/god-mode/src/components/testing/SEOValidator.tsx new file mode 100644 index 0000000..e69de29 diff --git a/god-mode/src/components/testing/SchemaValidator.tsx b/god-mode/src/components/testing/SchemaValidator.tsx new file mode 100644 index 0000000..e69de29 diff --git a/god-mode/src/components/testing/TestRunner.tsx b/god-mode/src/components/testing/TestRunner.tsx new file mode 100644 index 0000000..63fa12c --- /dev/null +++ b/god-mode/src/components/testing/TestRunner.tsx @@ -0,0 +1,109 @@ + +import React, { useState } from 'react'; +import { Card } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Textarea } from "@/components/ui/textarea"; +import { Input } from "@/components/ui/input"; +import { Progress } from "@/components/ui/progress"; +import { CheckCircle2, AlertTriangle, XCircle, Search, FileText } from 'lucide-react'; +// We import the analysis functions directly since this is a client component in Astro/React +import { analyzeSeo, analyzeReadability } from '@/lib/testing/seo'; + +const TestRunner = () => { + const [content, setContent] = useState(''); + const [keyword, setKeyword] = useState(''); + const [results, setResults] = useState(null); + + const runTests = () => { + const seo = analyzeSeo(content, keyword); + const read = analyzeReadability(content); + + setResults({ seo, read }); + }; + + return ( +
+ + {/* Input Column */} +
+ +

+ Content Source +

+
+ setKeyword(e.target.value)} + /> +