Remove static JSON files and seed step; migrate site settings to Postgres

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>
This commit is contained in:
2026-06-18 09:53:39 +02:00
co-authored by Claude Sonnet 4.6
parent 792cbe18c1
commit 86fbd8e4bb
20 changed files with 154 additions and 512 deletions
-43
View File
@@ -1,43 +0,0 @@
<?php
/**
* Einmaliger Import aus data/recipes.json in die relationale DB.
* Die Website liest zur Laufzeit nur noch aus Postgres.
*
* php scripts/db-seed.php
*/
require_once dirname(__DIR__) . '/helpers.php';
$seedPath = dirname(__DIR__) . '/data/recipes.json';
if (!file_exists($seedPath)) {
fwrite(STDERR, "Seed-Datei fehlt: data/recipes.json\n");
exit(1);
}
$raw = file_get_contents($seedPath);
$recipes = json_decode($raw, true);
if (!is_array($recipes)) {
fwrite(STDERR, "Ungültiges JSON in data/recipes.json\n");
exit(1);
}
try {
$pdo = require_database();
} catch (DatabaseUnavailableException $e) {
fwrite(STDERR, $e->getMessage() . "\n");
exit(1);
}
$count = 0;
foreach ($recipes as $recipe) {
if (!is_array($recipe) || empty($recipe['slug'])) {
continue;
}
if (save_recipe($recipe, $pdo)) {
$count++;
echo " + {$recipe['slug']}\n";
} else {
fwrite(STDERR, " ! Fehler bei {$recipe['slug']}\n");
}
}
echo "\nImport abgeschlossen: {$count} Rezepte.\n";
+11
View File
@@ -68,3 +68,14 @@ CREATE TABLE IF NOT EXISTS recipe_steps (
);
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);