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
-264
View File
@@ -1,264 +0,0 @@
[
{
"slug": "frische-tagliatelle-mit-cremiger-tomatensauce",
"hero": "/assets/pasta-tomato.jpg",
"prep_time": 50,
"cook_time": 10,
"total_time": 60,
"servings": 2,
"featured": false,
"coming_soon": false,
"nutrition": {
"calories": 0,
"protein": 0,
"carbs": 0,
"fat": 0
},
"i18n": {
"en": {
"title": "Tagliatelle with tomato sauce",
"description": "Simple but tasty, short cooking time but self made. The root dish to start in a cozy evening and satisfy the carbs cravings without any hidden additives. Noodles with Tomato Sauce, more hearty isnt possible.",
"category": "Pasta",
"difficulty": "Easy",
"tags": [
"Pasta",
"Fast",
"Vegetarian"
],
"ingredients": [
"300 g flour",
"3 eggs",
"10 cherry tomatoes",
"1/2 clove garlic",
"1 tbsp olive oil",
"80 ml cream",
"Fresh basil",
"Parmesan",
"Salt and pepper"
],
"utensils": [
"Rolling pin",
"Optional: Pasta machine",
"Optional: Blender"
],
"steps": [
"Pile the flour on your counter, press a well in the center, crack in the eggs. Gradually pull flour into the eggs, then knead 510 minutes until smooth.",
"Roll the dough to 12 mm thickness (rolling pin or pasta machine) and cut into tagliatelle.",
"Bring salted water to a boil. Meanwhile, halve tomatoes and sear in olive oil with a pinch of salt until lightly charred.",
"Toast the garlic briefly, then blend tomatoes with cream (or crush in the pan) and simmer to thicken slightly.",
"Boil tagliatelle for 23 minutes, drain, toss with the sauce, and finish with basil and Parmesan."
]
},
"de": {
"title": "Tagliatelle mit Tomatensauce",
"description": "Einfach, aber richtig lecker; kurze Kochzeit und trotzdem hausgemacht. Das Basisgericht für einen gemütlichen Abend, stillt den Kohlenhydrat-Hunger ohne versteckte Zusätze. Nudeln mit Tomatensauce herzhafter geht es kaum.",
"category": "Pasta",
"difficulty": "Einfach",
"tags": [
"Pasta",
"Schnell",
"Vegetarisch"
],
"ingredients": [
"300 g Mehl",
"3 Eier",
"10 Cherry-Tomaten",
"1/2 Knoblauchzehe",
"1 EL Olivenöl",
"80 ml Sahne",
"Frischer Basilikum",
"Parmesan",
"Salz und Pfeffer"
],
"utensils": [
"Nudelholz",
"Optional: Nudelmaschine",
"Optional: Mixer"
],
"steps": [
"Mehl auf der Arbeitsfläche anhäufen, eine Kuhle drücken, Eier hineingeben. Mehl nach und nach einarbeiten, dann 510 Minuten kneten, bis der Teig glatt ist.",
"Teig auf 12 mm ausrollen (mit Nudelholz oder Nudelmaschine) und in Tagliatelle schneiden.",
"Gesalzenes Wasser aufsetzen; währenddessen Tomaten halbieren und mit Olivenöl und einer Prise Salz in der Pfanne anrösten, bis Röstnoten entstehen.",
"Knoblauch kurz mitrösten, dann Tomaten mit Sahne pürieren (Mixer) oder in der Pfanne zerdrücken und kurz einkochen lassen.",
"Tagliatelle 23 Minuten kochen, abgießen und mit der Sauce vermengen. Mit Basilikum und Parmesan anrichten."
]
}
}
},
{
"slug": "oat-pancakes",
"hero": "/assets/pancakes.jpg",
"prep_time": 0,
"cook_time": 0,
"total_time": 0,
"servings": 2,
"featured": false,
"coming_soon": true,
"nutrition": {
"calories": 0,
"protein": 0,
"carbs": 0,
"fat": 0
},
"i18n": {
"en": {
"title": "Oat-Pancakes",
"description": "",
"category": "",
"difficulty": "Easy",
"tags": [],
"ingredients": [],
"utensils": [],
"steps": []
},
"de": {
"title": "Hafer-Pfannkuchen",
"description": "",
"category": "",
"difficulty": "Einfach",
"tags": [],
"ingredients": [],
"utensils": [],
"steps": []
}
}
},
{
"slug": "steak-with-onion-jam",
"hero": "/assets/steak.JPEG",
"prep_time": 15,
"cook_time": 15,
"total_time": 30,
"servings": 2,
"featured": true,
"coming_soon": false,
"nutrition": {
"calories": 0,
"protein": 0,
"carbs": 0,
"fat": 0
},
"i18n": {
"en": {
"title": "Steak with onion jam",
"description": "A hearty meal after a long day, best enjoyed with a glass of red wine and in good company—because the onion jam still isnt satisfied on its own.",
"category": "",
"difficulty": "Easy",
"tags": [
"meat",
"dinner"
],
"ingredients": [
"2 x 250g rump steak",
"300g potatoes",
"1 large red onion",
"1/2 clove garlic",
"50ml cream",
"50ml red wine",
"4 carrots (yellow and purple)",
"parmesan",
"Sicilian orange salt",
"thyme",
"1 tbsp butter"
],
"utensils": [
"knife",
"cutting board",
"pan",
"pot",
"oven"
],
"steps": [
"Take the steak out 30 minutes before cooking",
"Halve the potatoes",
"Halve the carrots",
"Dice the onion",
"Cook the potatoes and carrots until al dente",
"Sear the steak with butter",
"Once both sides are golden brown, bake for 6 minutes at 160°C (medium); for medium rare, let it rest after searing both sides for 3 minutes",
"Sauté the onion in the steak butter, deglaze with red wine, and add cream once the alcohol has evaporated",
"Plate and serve!"
]
},
"de": {
"title": "Steak mit Zwiebelmarmelade",
"description": "Eine schwere Mahlzeit nach einem langen Tag, am besten zu einem Schluck Rotwein und in Gesellschaft genießen, da die Zwiebelmarmelade noch nicht genug davon hat.",
"category": "",
"difficulty": "Einfach",
"tags": [
"Fleisch",
"Abendessen"
],
"ingredients": [
"2 x 250g Rumpsteak",
"300gr Kartoffeln",
"1 Große Rote Zwiebel",
"1/2 Knoblauch-Zehe",
"50ml Sahne",
"50ml Rotwein",
"4 Karotten (Geld und Lila)",
"Parmesan",
"Sizilianisches Orangensalz",
"Thymian",
"1 EL Butter"
],
"utensils": [
"Messer",
"Brett",
"Pfanne",
"Topf",
"Ofen"
],
"steps": [
"Steak 30 Minuten vor dem anbraten raus legen",
"Kartoffeln halbieren",
"Karotten halbieren",
"Zwiebel würfeln",
"Kartoffeln und Karotten al dente kochen",
"Steak anbraten mit Butter",
"sobald beide seiten goldbraun sind für 6 Minuten bei 160grad backen (Medium) für Medium Rare nur ruhen lassen nachdem es von beiden Seiten für 3 Minuten angebraten wurde",
"Zwiebel in Steak-Butter anschwitzen, mit Rotwein ablöschen und Sahne dazu geben nachdem er Alkohol verdünstet ist",
"Anrichten!"
]
}
}
},
{
"slug": "oat-cake",
"hero": "/assets/haferkuchen.JPEG",
"prep_time": 0,
"cook_time": 0,
"total_time": 0,
"servings": 2,
"featured": false,
"coming_soon": true,
"nutrition": {
"calories": 0,
"protein": 0,
"carbs": 0,
"fat": 0
},
"i18n": {
"en": {
"title": "Oat cake",
"description": "",
"category": "",
"difficulty": "Easy",
"tags": [],
"ingredients": [],
"utensils": [],
"steps": []
},
"de": {
"title": "Haferkuchen",
"description": "",
"category": "",
"difficulty": "Einfach",
"tags": [],
"ingredients": [],
"utensils": [],
"steps": []
}
}
}
]
-54
View File
@@ -1,54 +0,0 @@
{
"imprint": {
"de": {
"owner_name": "Felix Brockers",
"address": "N.A",
"email": "contact@flixcooks.at",
"phone": "N.A",
"legal_form": "Kleines Impressum; kein Firmenbucheintrag/UID hinterlegt.",
"business_purpose": "Foodblog & Rezeptmarketing.",
"wko_membership": "",
"authority": "",
"uid": "",
"odr": "https://consumer-redress.ec.europa.eu/",
"last_updated": "2026-03-23"
},
"en": {
"owner_name": "Felix Brockers",
"address": "N.A",
"email": "contact@flixcooks.at",
"phone": "N.A",
"legal_form": "Small website notice; no commercial register/UID provided.",
"business_purpose": "Food blog & recipe marketing.",
"wko_membership": "",
"authority": "",
"uid": "",
"odr": "https://consumer-redress.ec.europa.eu/",
"last_updated": "2026-03-23"
}
},
"privacy": {
"de": {
"controller": "Felix Brockers",
"contact_email": "contact@flixcooks.at",
"contact_phone": "N.A",
"address": "N.A",
"hosting_provider": "Hetzner Online GmbH, Industriestr. 25, 91710 Gunzenhausen, Deutschland",
"log_retention_days": 30,
"cookie_statement": "Keine Tracking- oder Marketing-Cookies; nur technisch notwendige.",
"purposes": "Betrieb und Bereitstellung der Website, Beantwortung von Kontaktanfragen.",
"last_updated": "2026-03-23"
},
"en": {
"controller": "Felix Brockers",
"contact_email": "contact@flixcooks.at",
"contact_phone": "N.A",
"address": "N.A",
"hosting_provider": "Hetzner Online GmbH, Industriestr. 25, 91710 Gunzenhausen, Germany",
"log_retention_days": 30,
"cookie_statement": "No tracking or marketing cookies; only technically necessary cookies.",
"purposes": "Operating and providing the website, responding to contact requests.",
"last_updated": "2026-03-23"
}
}
}