feat(seo): Add SEO tables to migration and ingress config
- Add seo_pages and seo_page_contents tables to migrate.ts for automatic creation on deployment - Update Home.tsx with minor formatting - Add ingress configuration updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -372,6 +372,51 @@ async function runMigrations() {
|
|||||||
ON CONFLICT (key) DO NOTHING;
|
ON CONFLICT (key) DO NOTHING;
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
// SEO Pages table
|
||||||
|
await client.query(`
|
||||||
|
CREATE TABLE IF NOT EXISTS seo_pages (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
type VARCHAR(50) NOT NULL,
|
||||||
|
slug VARCHAR(255) NOT NULL UNIQUE,
|
||||||
|
page_key VARCHAR(255) NOT NULL,
|
||||||
|
primary_keyword VARCHAR(255),
|
||||||
|
status VARCHAR(50) DEFAULT 'pending_generation',
|
||||||
|
data_source VARCHAR(100),
|
||||||
|
meta_title VARCHAR(255),
|
||||||
|
meta_description TEXT,
|
||||||
|
last_generated_at TIMESTAMPTZ,
|
||||||
|
last_reviewed_at TIMESTAMPTZ,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_seo_pages_type ON seo_pages(type);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_seo_pages_status ON seo_pages(status);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_seo_pages_slug ON seo_pages(slug);
|
||||||
|
`);
|
||||||
|
|
||||||
|
// SEO Page Contents table
|
||||||
|
await client.query(`
|
||||||
|
CREATE TABLE IF NOT EXISTS seo_page_contents (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
page_id INTEGER NOT NULL REFERENCES seo_pages(id) ON DELETE CASCADE,
|
||||||
|
version INTEGER DEFAULT 1,
|
||||||
|
blocks JSONB NOT NULL DEFAULT '[]',
|
||||||
|
meta JSONB NOT NULL DEFAULT '{}',
|
||||||
|
meta_title VARCHAR(255),
|
||||||
|
meta_description TEXT,
|
||||||
|
h1 VARCHAR(255),
|
||||||
|
canonical_url TEXT,
|
||||||
|
og_title VARCHAR(255),
|
||||||
|
og_description TEXT,
|
||||||
|
og_image_url TEXT,
|
||||||
|
generated_by VARCHAR(50) DEFAULT 'claude',
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
UNIQUE(page_id, version)
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_seo_page_contents_page ON seo_page_contents(page_id);
|
||||||
|
`);
|
||||||
|
|
||||||
await client.query('COMMIT');
|
await client.query('COMMIT');
|
||||||
console.log('✅ Migrations completed successfully');
|
console.log('✅ Migrations completed successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ import {
|
|||||||
ShoppingBag,
|
ShoppingBag,
|
||||||
LineChart
|
LineChart
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
|
const API_URL = import.meta.env.VITE_API_URL || '';
|
||||||
|
const PLUGIN_DOWNLOAD_URL = `${API_URL}/downloads/cannaiq-menus-1.5.3.zip`;
|
||||||
import { api } from '../lib/api';
|
import { api } from '../lib/api';
|
||||||
|
|
||||||
interface VersionInfo {
|
interface VersionInfo {
|
||||||
@@ -440,8 +443,9 @@ export function Home() {
|
|||||||
Go to /admin
|
Go to /admin
|
||||||
</Link>
|
</Link>
|
||||||
<a
|
<a
|
||||||
href="/downloads/cannaiq-menus-1.5.3.zip"
|
href={PLUGIN_DOWNLOAD_URL}
|
||||||
className="flex items-center justify-center gap-2 border-2 border-emerald-600 text-emerald-700 font-semibold py-3 px-6 rounded-lg hover:bg-emerald-50 transition-colors"
|
className="flex items-center justify-center gap-2 border-2 border-emerald-600 text-emerald-700 font-semibold py-3 px-6 rounded-lg hover:bg-emerald-50 transition-colors"
|
||||||
|
download
|
||||||
>
|
>
|
||||||
<Code className="w-5 h-5" />
|
<Code className="w-5 h-5" />
|
||||||
Download WordPress Plugin
|
Download WordPress Plugin
|
||||||
@@ -497,7 +501,7 @@ export function Home() {
|
|||||||
<div className="flex items-center gap-6 text-gray-400 text-sm">
|
<div className="flex items-center gap-6 text-gray-400 text-sm">
|
||||||
<Link to="/login" className="hover:text-white transition-colors">Sign in</Link>
|
<Link to="/login" className="hover:text-white transition-colors">Sign in</Link>
|
||||||
<a href="mailto:hello@cannaiq.co" className="hover:text-white transition-colors">Contact</a>
|
<a href="mailto:hello@cannaiq.co" className="hover:text-white transition-colors">Contact</a>
|
||||||
<a href="/downloads/cannaiq-menus-1.5.3.zip" className="hover:text-white transition-colors">WordPress Plugin</a>
|
<a href={PLUGIN_DOWNLOAD_URL} className="hover:text-white transition-colors" download>WordPress Plugin</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,13 @@ spec:
|
|||||||
name: scraper
|
name: scraper
|
||||||
port:
|
port:
|
||||||
number: 80
|
number: 80
|
||||||
|
- path: /downloads
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: scraper
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
- path: /
|
- path: /
|
||||||
pathType: Prefix
|
pathType: Prefix
|
||||||
backend:
|
backend:
|
||||||
@@ -119,6 +126,13 @@ spec:
|
|||||||
name: scraper
|
name: scraper
|
||||||
port:
|
port:
|
||||||
number: 80
|
number: 80
|
||||||
|
- path: /downloads
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: scraper
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
- path: /
|
- path: /
|
||||||
pathType: Prefix
|
pathType: Prefix
|
||||||
backend:
|
backend:
|
||||||
|
|||||||
Reference in New Issue
Block a user