All content (recipes + imprint/privacy settings) now lives exclusively in Postgres. The app no longer requires a seed step on first deploy. Changes: - helpers.php: load_site_settings() returns defaults when site_settings table is empty instead of throwing DatabaseUnavailableException; removes legacy JSONB migration path - data/recipes.json, data/site.json: deleted (content already in DB) - scripts/db-seed.php: deleted (no longer needed) - docker-compose.yml: remove RUN_DB_SEED env var and data/ volume mount - docker/entrypoint.sh: remove RUN_DB_SEED seed block - docs/COOLIFY.md: update deployment guide to reflect seedless workflow - .claude/launch.json: add dev server configurations for preview tool Fresh deploys now start with placeholder legal pages and an empty recipe list; the admin fills in real content via /admin.php without any CLI step. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
82 lines
3.0 KiB
SQL
82 lines
3.0 KiB
SQL
-- FlixCooks relational recipe schema (PostgreSQL)
|
|
|
|
CREATE TABLE IF NOT EXISTS recipes (
|
|
slug VARCHAR(255) PRIMARY KEY,
|
|
hero TEXT NOT NULL DEFAULT '',
|
|
prep_time INTEGER NOT NULL DEFAULT 0,
|
|
cook_time INTEGER NOT NULL DEFAULT 0,
|
|
total_time INTEGER NOT NULL DEFAULT 0,
|
|
servings INTEGER NOT NULL DEFAULT 2,
|
|
featured BOOLEAN NOT NULL DEFAULT FALSE,
|
|
coming_soon BOOLEAN NOT NULL DEFAULT FALSE,
|
|
calories INTEGER NOT NULL DEFAULT 0,
|
|
protein INTEGER NOT NULL DEFAULT 0,
|
|
carbs INTEGER NOT NULL DEFAULT 0,
|
|
fat INTEGER NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS recipe_translations (
|
|
recipe_slug VARCHAR(255) NOT NULL REFERENCES recipes(slug) ON DELETE CASCADE,
|
|
lang CHAR(2) NOT NULL CHECK (lang IN ('en', 'de')),
|
|
title TEXT NOT NULL DEFAULT '',
|
|
description TEXT NOT NULL DEFAULT '',
|
|
category TEXT NOT NULL DEFAULT '',
|
|
difficulty TEXT NOT NULL DEFAULT '',
|
|
PRIMARY KEY (recipe_slug, lang)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS recipe_tags (
|
|
id SERIAL PRIMARY KEY,
|
|
recipe_slug VARCHAR(255) NOT NULL REFERENCES recipes(slug) ON DELETE CASCADE,
|
|
lang CHAR(2) NOT NULL CHECK (lang IN ('en', 'de')),
|
|
tag TEXT NOT NULL,
|
|
sort_order INTEGER NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_recipe_tags_slug_lang ON recipe_tags (recipe_slug, lang);
|
|
|
|
CREATE TABLE IF NOT EXISTS recipe_ingredients (
|
|
id SERIAL PRIMARY KEY,
|
|
recipe_slug VARCHAR(255) NOT NULL REFERENCES recipes(slug) ON DELETE CASCADE,
|
|
lang CHAR(2) NOT NULL CHECK (lang IN ('en', 'de')),
|
|
content TEXT NOT NULL,
|
|
sort_order INTEGER NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_recipe_ingredients_slug_lang ON recipe_ingredients (recipe_slug, lang);
|
|
|
|
CREATE TABLE IF NOT EXISTS recipe_utensils (
|
|
id SERIAL PRIMARY KEY,
|
|
recipe_slug VARCHAR(255) NOT NULL REFERENCES recipes(slug) ON DELETE CASCADE,
|
|
lang CHAR(2) NOT NULL CHECK (lang IN ('en', 'de')),
|
|
content TEXT NOT NULL,
|
|
sort_order INTEGER NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_recipe_utensils_slug_lang ON recipe_utensils (recipe_slug, lang);
|
|
|
|
CREATE TABLE IF NOT EXISTS recipe_steps (
|
|
id SERIAL PRIMARY KEY,
|
|
recipe_slug VARCHAR(255) NOT NULL REFERENCES recipes(slug) ON DELETE CASCADE,
|
|
lang CHAR(2) NOT NULL CHECK (lang IN ('en', 'de')),
|
|
content TEXT NOT NULL DEFAULT '',
|
|
video_url TEXT NOT NULL DEFAULT '',
|
|
timer_minutes INTEGER,
|
|
sort_order INTEGER NOT NULL DEFAULT 0
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_recipe_steps_slug_lang ON recipe_steps (recipe_slug, lang);
|
|
|
|
CREATE TABLE IF NOT EXISTS site_settings (
|
|
section VARCHAR(32) NOT NULL CHECK (section IN ('imprint', 'privacy')),
|
|
lang CHAR(2) NOT NULL CHECK (lang IN ('en', 'de')),
|
|
setting_key VARCHAR(64) NOT NULL,
|
|
setting_value TEXT NOT NULL DEFAULT '',
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
PRIMARY KEY (section, lang, setting_key)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_site_settings_section_lang ON site_settings (section, lang);
|