diff --git a/DATABASE_SCHEMA_ACTUAL.md b/DATABASE_SCHEMA_ACTUAL.md new file mode 100644 index 0000000..d6b8d41 --- /dev/null +++ b/DATABASE_SCHEMA_ACTUAL.md @@ -0,0 +1,241 @@ +# God Mode Database - Actual Schema & Data Inventory +**Database:** arc-net +**Last Updated:** 2025-12-16 +**Connection:** postgres://spark-god-mode:***@ykgkos00co4k48480ccs8sow:5432/arc-net + +## 📊 Current Data Inventory + +| Table | Count | Purpose | +|-------|-------|---------| +| **content_fragments** | 6 | ✅ **HAS DATA** - Content building blocks | +| **article_templates** | 1 | ✅ **HAS DATA** - Template structure | +| **campaign_masters** | 1 | ✅ **HAS DATA** - Campaign config | +| **sites** | 1 | ✅ **HAS DATA** - Site record | +| avatars | 0 | Empty | +| content_blocks | 0 | Empty | +| geo_locations | 0 | Empty | +| pages | 0 | Empty (can be created via UI) | +| posts | 0 | Empty (can be created via UI) | + +--- + +## 🎯 Key Content Found + +### Content Fragments (6 items) +These are the **2000-word article building blocks** you mentioned! + +**Fragment Types:** +1. `intro_hook` - Opening hook for aesthetic practice CEO +2. `sales_letter_core_1` - Core sales message +3. `feature_benefit_meaning` - Conversion Architecture System features +4. `brunson_bullets` - Russell Brunson-style bullet points +5. `bio_section` - Expert bio/credibility +6. `offer_stack` - CTA and offer + +**Sample Content (intro_hook):** +```html +

The $50,000 Mistake: Why Your City Practice is Vulnerable

+

Attention Aesthetic Practice CEO, if you operate in City, Alabama, +and worry about wasting $50,000 on Google Ads, this report is essential...

+``` + +**Word Counts:** +- intro_hook: 250 words +- sales_letter_core_1: 200 words +- feature_benefit_meaning: 400 words +- brunson_bullets: 300 words +- bio_section: 200 words +- offer_stack: 300 words + +**Total Content:** ~1,650 words of pre-written content! 🎉 + +--- + +### Article Template (1 item) +**Name:** "98765432_Aesthetic Practice CEO" + +**Structure (12 sections):** +```json +[ + "intro_hook", + "sales_letter_core_1", + "feature_benefit_meaning", + "brunson_bullets", + "bio_section", + "deep_dive_data_protocol", // ❌ Missing fragment + "deep_dive_logic_core", // ❌ Missing fragment + "infrastructure_vs_website", // ❌ Missing fragment + "compliance_protocol", // ❌ Missing fragment + "technical_debt_trap", // ❌ Missing fragment + "local_dominance", // ❌ Missing fragment + "offer_stack" +] +``` + +**Status:** Template defines 12 sections but only 6 content fragments exist. +**Actionable:** Can generate a partial page with existing 6 fragments! + +--- + +### Campaign (1 item) +**Name:** "Chrisamaya.work batch 1" +**Type:** PSEO (Programmatic SEO) +**Status:** Active + +--- + +## 📋 Complete Schema Reference + +### content_fragments +```sql +id UUID PRIMARY KEY +campaign_id UUID → campaign_masters(id) +fragment_type VARCHAR -- Type identifier (intro_hook, etc.) +content_body TEXT -- HTML content +word_count INTEGER -- Target word count +status VARCHAR -- Status flag +date_created TIMESTAMP +content_hash VARCHAR(64) -- Unique content hash +use_count INTEGER -- Usage tracking +``` + +### article_templates +```sql +id UUID PRIMARY KEY +name VARCHAR +structure_json JSONB -- Array of fragment_type names +date_created TIMESTAMP +``` + +### campaign_masters +```sql +id UUID PRIMARY KEY +name VARCHAR +campaign_type VARCHAR -- 'pseo', etc. +config JSONB +status VARCHAR +created_at TIMESTAMP +updated_at TIMESTAMP +site_id UUID → sites(id) +``` + +### sites +```sql +id UUID PRIMARY KEY +name VARCHAR +domain VARCHAR UNIQUE +config JSONB +created_at TIMESTAMP +updated_at TIMESTAMP +status VARCHAR +site_url TEXT +site_wpjson TEXT +client_id UUID +``` + +### pages (Empty - Ready for Use) +```sql +id UUID PRIMARY KEY +site_id UUID → sites(id) +name VARCHAR +route VARCHAR -- URL route (/about, /services) +html_content TEXT +meta_title VARCHAR(255) +meta_description VARCHAR(512) +status VARCHAR(50) -- draft, published, archived +published_at TIMESTAMPTZ +created_at TIMESTAMPTZ +updated_at TIMESTAMPTZ +UNIQUE(site_id, route) +``` + +### posts (Empty - Ready for Use) +```sql +id UUID PRIMARY KEY +site_id UUID → sites(id) +title VARCHAR(512) +slug VARCHAR(512) +content TEXT +excerpt TEXT +status VARCHAR(50) +meta_title VARCHAR(255) +meta_description VARCHAR(512) +published_at TIMESTAMPTZ +created_at TIMESTAMPTZ +updated_at TIMESTAMPTZ +UNIQUE(site_id, slug) +``` + +--- + +## 🎨 What Can Be Built NOW + +### 1. **Auto-Generated Sales Page** +**Using:** 6 existing content fragments + template structure +**Route:** `/aesthetic-practice-ceo-report` +**Content:** ~1,650 words of professional sales copy +**Niche:** Aesthetic practice marketing + +### 2. **Custom Pages** +**Using:** Page editor UI (`/admin/pages/new`) +**Capability:** Create any HTML page with SEO metadata + +### 3. **Blog Posts** +**Using:** Post editor UI (`/admin/posts/new`) +**Capability:** Create blog articles with slug-based URLs + +--- + +## 🔧 Schema Sync Status + +### ✅ Matches Documentation +- `sites` table schema ✓ +- `pages` table schema ✓ +- `posts` table schema ✓ +- `campaign_masters` table schema ✓ + +### ⚠️ Documentation Updates Needed +- `content_fragments`: Uses `content_body` not `content` ✓ (now documented) +- `geo_locations`: Uses `country` not `county` ✓ (now documented) +- `article_templates`: Uses `structure_json` ✓ (now documented) + +### 📋 Missing from Schema Docs (Need to add) +- `content_fragments` table +- `article_templates` table +- `avatars` table +- `content_blocks` table +- `spintax_*` tables +- `headline_inventory` table +- `block_usage_stats` table +- `variation_registry` table + +--- + +## 🚀 Next Actions + +1. ✅ **Create demo page using real content fragments** +2. ✅ **Test page/post creation UI** +3. ⏳ **Populate missing content fragments** (6 more sections needed) +4. ⏳ **Create avatars** (for different personas) +5. ⏳ **Add geo_locations** (for local SEO campaigns) + +--- + +## 💾 Connection Info (Synced with Coolify) +``` +Username: spark-god-mode +Password: eEQme6YUWIMYP20bUjf6ZE75BX1HrVMXv9Z5TBsWr8NP94JxjsdnW0NB8vvczHlC +Database: arc-net +Host: ykgkos00co4k48480ccs8sow:5432 +Internal URL: postgres://spark-god-mode:***@ykgkos00co4k48480ccs8sow:5432/arc-net +``` + +**Port Mapping:** 3000:5432 (External: 3000, Internal: 5432) + +--- + +## ✨ Summary + +You have **6 content fragments** totaling ~1,650 words of professional sales copy for aesthetic practice CEOs! The template defines the structure, and we can generate a complete sales page from this data right now. + +The schema is solid and ready for production use. All CRUD operations work via the shim layer (pages, posts, sites). diff --git a/src/pages/admin/pages/demo-generator.astro b/src/pages/admin/pages/demo-generator.astro index a373d73..b367f59 100644 --- a/src/pages/admin/pages/demo-generator.astro +++ b/src/pages/admin/pages/demo-generator.astro @@ -1,5 +1,5 @@ --- -// Demo Page Generator - Uses Real Database Content +// Real Content Demo Generator - Uses actual content fragments from database import AdminLayout from '@/layouts/AdminLayout.astro'; import { pool } from '@/lib/db'; @@ -11,125 +11,165 @@ if (!site) { return Astro.redirect('/admin/sites'); } -// Get content fragments if they exist -const { rows: fragments } = await pool.query<{fragment_type: string; content: any}>( - 'SELECT fragment_type, content FROM content_fragments LIMIT 10' +// Get ALL content fragments +const { rows: fragments } = await pool.query<{fragment_type: string; content_body: string; word_count: number}>( + 'SELECT fragment_type, content_body, word_count FROM content_fragments ORDER BY date_created' ); -// Get article templates if they exist -const { rows: templates } = await pool.query<{name: string; template: any}>( - 'SELECT name, template FROM article_templates ORDER BY created_at DESC LIMIT 5' +// Get article template +const { rows: templates } = await pool.query<{name: string; structure_json: string[]}>( + 'SELECT name, structure_json FROM article_templates LIMIT 1' ); -// Build demo page HTML -let demoHTML = ` -
-
-

- Welcome to ${site.domain} -

-

- This page was auto-generated using content from your database -

-
+const template = templates[0]; -
-

About Your Platform

-

- You have ${fragments.length} content fragments and ${templates.length} article templates in your database. - This demonstrates the direct database integration working perfectly! -

-
-`; +// Build complete sales page from fragments +let salesPageHTML = ''; -// Add content fragments section if exist -if (fragments.length > 0) { - demoHTML += ` -
-

📦 Your Content Fragments

-
- `; - - fragments.slice(0, 6).forEach(frag => { - demoHTML += ` -
-

- ${frag.fragment_type || 'Content Block'} -

-

- ${JSON.stringify(frag.content).substring(0, 100)}... -

-
- `; +if (template && fragments.length > 0) { + // Create a map of fragments by type + const fragmentMap = new Map(); + fragments.forEach(frag => { + fragmentMap.set(frag.fragment_type, frag.content_body); }); - demoHTML += ` -
-
- `; -} - -// Add templates section if exist -if (templates.length > 0) { - demoHTML += ` -
-

📄 Your Article Templates

-
- `; - - templates.forEach(tmpl => { - demoHTML += ` -
-

- ✨ ${tmpl.name} -

-
- ${JSON.stringify(tmpl.template, null, 2).substring(0, 300)}... -
-
- `; - }); - - demoHTML += ` -
-
- `; -} - -demoHTML += ` -
-

🚀 Ready to Build More?

-

- This page demonstrates that your database content is accessible and renders perfectly. -

-
- - Create Custom Page - - - Create Blog Post - -
-
- - -
+ // Build page following template structure + salesPageHTML = ` + + + + + + Aesthetic Practice CEO Report - Stop Wasting $50,000 on Google Ads + + + + +
`; -// Create the page using the API + // Add each section from template + template.structure_json.forEach((fragmentType: string) => { + const content = fragmentMap.get(fragmentType); + if (content) { + // Wrap offer_stack in special styling + if (fragmentType === 'offer_stack') { + salesPageHTML += `
${content}
`; + } else { + salesPageHTML += `
${content}
`; + } + } + }); + + salesPageHTML += ` +
+ + +
+

✨ Auto-generated from database content | ${site.domain}

+
+ + +`; +} + +// Create the page const pageData = { site_id: site.id, - name: "Database Demo Page", - route: "/demo", - html_content: demoHTML, - meta_title: `${site.domain} - Database Integration Demo`, - meta_description: "Auto-generated demo page showing content from the database", + name: "Aesthetic Practice CEO Sales Letter", + route: "/aesthetic-practice-report", + html_content: salesPageHTML, + meta_title: "Stop Wasting $50,000 on Google Ads | Aesthetic Practice CEO Report", + meta_description: "Essential report for aesthetic practice CEOs. Discover the critical flaw in standard agency funnels and the Conversion Architecture system that delivers results.", status: "published" }; let createdPage = null; +let error = null; + try { const response = await fetch(`${Astro.url.origin}/api/shim/pages/create`, { method: 'POST', @@ -142,77 +182,121 @@ try { if (response.ok) { createdPage = await response.json(); + } else { + const err = await response.json(); + error = err.message || 'Failed to create page'; } -} catch (error) { - console.error('Failed to create demo page:', error); +} catch (err: any) { + error = err.message; + console.error('Failed to create page:', err); } --- - +
-

📊 Database Demo Page

-

Auto-generated page using your database content

+

🎯 Real Content Sales Page

+

Generated from your {fragments.length} content fragments

- - ← Back to Admin + + ← Back
{createdPage ? (
-

✅ Demo Page Created!

-

- Your demo page has been successfully created from database content. +

✅ Sales Page Created!

+

+ Your {fragments.length}-section sales letter has been generated from real database content.

-
+ -
-

- ID: {createdPage.id}
- Route: {createdPage.route}
- Status: {createdPage.status} -

+
+
+
Page ID
+
{createdPage.id}
+
+
+
Route
+
{createdPage.route}
+
+
+
Status
+
{createdPage.status}
+
+
+
Word Count
+
~{fragments.reduce((sum, f) => sum + f.word_count, 0)} words
+
+ ) : error ? ( +
+

❌ Error

+

{error}

+
) : (
-

⚠️ Page Creation

-

- Generating demo page... refresh if needed. -

+

⏳ Generating...

+

Creating sales page from fragments...

)}
-

Database Content Found:

-
-
-
{fragments.length}
-
Content Fragments
-
-
-
{templates.length}
-
Article Templates
-
+

📦 Content Fragments Found:

+
+ {fragments.map(frag => ( +
+
+ {frag.fragment_type} + {frag.word_count} words +
+
+ {frag.content_body.replace(/<[^>]*>/g, '').substring(0, 150)}... +
+
+ ))}
+ {template && ( +
+

📋 Template Structure: {template.name}

+
+ {template.structure_json.map((section: string) => { + const hasContent = fragments.some(f => f.fragment_type === section); + return ( + + {section} {hasContent ? '✓' : '✗'} + + ); + })} +
+

+ {fragments.length} of {template.structure_json.length} sections have content +

+
+ )} +