2026-05-21 14:55:10 +02:00
# FlixCooks Project Brain
2026-05-23 10:13:00 +02:00
This document summarizes architectural knowledge, conventions, and learnings for humans and AI agents working on this repo.
2026-05-21 14:55:10 +02:00
## 1. Project Architecture & Stack
2026-05-23 10:13:00 +02:00
- **Backend:** Vanilla PHP. No heavy frameworks.
2026-06-18 09:53:39 +02:00
- **Database:** PostgreSQL required (`DATABASE_URL` in `.env` ). Normalized tables in `scripts/schema.sql` ; `load_recipes()` / `save_recipe()` and `load_site_settings()` / `save_site_settings()` in `helpers.php` . No runtime JSON files. One-time import: `php scripts/db-seed.php` from `scripts/seed-data.php` .
- **Site settings (legal pages):** Stored in Postgres table `site_settings` ; no flat-file fallback.
2026-05-23 10:13:00 +02:00
- **Admin Panel (`admin.php` ):** Lightweight CMS. Textareas use one line per array element (`ingredients` , `steps` , `step_videos` , `step_timers` ).
2026-05-23 10:23:28 +02:00
- **Frontend:** Server-rendered PHP (`index.php` , `recipe.php` , …), Vanilla JS/CSS. Profile/favorites via `assets/fc-local.js` .
- **Config:** `config.php` loads `.env` , `get_db_connection()` . Never commit `.env` (see `.gitignore` ).
2026-05-21 14:55:10 +02:00
## 2. Design & Aesthetics
2026-05-23 10:13:00 +02:00
- **CSS:** Custom properties (`var(--ease-out-expo)` , `var(--surface-1)` ), glassmorphism, `FloemaLayoutGrid` .
- **Lenis:** Call `lenis.stop()` when opening fullscreen overlays (e.g. Cooking Mode); `lenis.start()` on close.
- **Preloader:** `CapitoliumPreloader` on homepage; once per session via `sessionStorage('flixcooks_preloader_seen')` .
2026-05-21 14:55:10 +02:00
## 3. Antigravity Agent Configuration
2026-05-23 10:13:00 +02:00
- **Workspace Rules:** `.agents/rules/` with `always_on: true` and `glob: "*"` in frontmatter.
- **Custom Skills:** `.agents/skills/` (e.g. `close_feature.json` for Git merge workflow).
2026-05-21 14:55:10 +02:00
2026-05-21 15:48:41 +02:00
## 4. GitHub Actions & CI/CD
2026-05-23 10:13:00 +02:00
- **Gemini PR review:** `petarzarkov/gemini-code-review-action` ; secrets via `env:` not `with:` ; pin action versions; use full model names (e.g. `gemini-2.0-flash-lite` ).
2026-05-21 15:48:41 +02:00
2026-05-23 10:13:00 +02:00
---
2026-05-21 14:55:10 +02:00
2026-05-23 10:13:00 +02:00
## 5. PostgreSQL — Schema & Data Flow
2026-05-23 10:23:28 +02:00
### Relational schema (`scripts/schema.sql`)
2026-06-18 09:53:39 +02:00
Created by `ensure_recipe_schema()` on first DB use. Legacy JSONB/file fallbacks are not supported.
2026-05-23 10:13:00 +02:00
2026-05-23 10:23:28 +02:00
| Table | Role |
|-------|------|
| `recipes` | slug, hero, times, servings, nutrition columns, featured, coming_soon |
| `recipe_translations` | title, description, category, difficulty (en/de) |
| `recipe_tags` , `recipe_ingredients` , `recipe_utensils` , `recipe_steps` | Ordered lists per language |
2026-06-18 09:53:39 +02:00
| `site_settings` | imprint/privacy fields per language |
2026-05-23 10:13:00 +02:00
2026-05-23 10:23:28 +02:00
PHP still exposes the same nested arrays (`i18n` , `nutrition` , …) via `hydrate_recipes_from_db()` .
2026-05-23 10:13:00 +02:00
### Runtime flow
2026-05-23 10:23:28 +02:00
1. `DATABASE_URL` required → `require_database()` or HTTP 503 (`maintenance/db-unavailable.php` ).
2. `load_recipes()` → SQL → PHP arrays for templates.
3. Admin: `save_recipe()` , `delete_recipe()` , `clear_featured_recipes()` .
2026-06-18 09:53:39 +02:00
4. One-time import: `php scripts/db-seed.php` from `scripts/seed-data.php` .
2026-05-23 10:13:00 +02:00
### `config.php` functions
2026-05-23 10:23:28 +02:00
- `load_env()` — parses `.env` .
- `get_db_connection()` — PDO or `null` .
- `DatabaseUnavailableException` — thrown when DB is required but missing.
2026-05-23 10:13:00 +02:00
---
## 6. Local Development — Docker Postgres
### Files
- `docker-compose.dev.yml` — Postgres 16 Alpine, container `flixcooks-postgres-dev` , port `5432` .
- `.env.example` — template including local `DATABASE_URL` .
- `scripts/db-check.php` — CLI: connect, `init_db()` , print recipe count + sample slugs/titles.
### Docker credentials (dev only)
```
POSTGRES_USER=flixcooks
POSTGRES_PASSWORD=flixcooks_dev
POSTGRES_DB=flixcooks_dev
DATABASE_URL="postgresql://flixcooks:flixcooks_dev@127.0.0.1:5432/flixcooks_dev"
```
### Commands
```bash
docker compose -f docker-compose.dev.yml up -d # start
docker compose -f docker-compose.dev.yml ps # health
docker compose -f docker-compose.dev.yml down # stop (data kept)
docker compose -f docker-compose.dev.yml down -v # stop + wipe volume → re-seed on next hit
docker exec -it flixcooks-postgres-dev psql -U flixcooks -d flixcooks_dev
# psql: \dt , \d recipes , SELECT slug FROM recipes; , \q
```
### PHP requirements (WSL/Linux)
2026-05-23 10:23:28 +02:00
- Extension ** `php-pgsql` ** (or `php8.5-pgsql` ) required; without it the site cannot connect.
2026-05-23 10:13:00 +02:00
- Install interactively: `sudo apt install php8.5-pgsql` (sudo in non-interactive agent shells may timeout).
- Verify: `php -m | grep pgsql` → expect `pdo_pgsql` , `pgsql` .
### App server
```bash
php -S localhost:8000
php scripts/db-check.php # after .env + pgsql OK
```
### `.env` rules for agents
- Copy from `.env.example` ; never commit `.env` .
- **Local:** use `127.0.0.1` Docker URL above.
2026-05-23 10:23:28 +02:00
- **`DATABASE_URL` is mandatory** for recipe pages; omitting it shows the DB unavailable page.
2026-05-23 10:13:00 +02:00
### Environment separation (important)
- One database per environment (local Docker / staging / production).
- Never point a dev branch `.env` at production Postgres.
2026-05-23 10:23:28 +02:00
- Export/import between envs: `pg_dump` / `psql` when needed; document URLs in hosting secrets, not in repo.
2026-05-23 10:13:00 +02:00
---
## 7. Troubleshooting (known issues)
| Symptom | Cause | Fix |
|--------|--------|-----|
2026-05-23 10:23:28 +02:00
| HTTP 503, database unavailable | No `DATABASE_URL` or Postgres down | Fix `.env` , start Docker, `php scripts/db-check.php` |
2026-05-23 10:13:00 +02:00
| Log: `could not find driver` | `php-pgsql` not installed | `sudo apt install php8.5-pgsql` |
2026-05-23 10:23:28 +02:00
| DB OK but 0 recipes | Empty tables | `php scripts/db-seed.php` |
2026-05-23 10:13:00 +02:00
---
## 8. Completed Milestones
- **Phase 3 (Nutrition):** `calories` , `protein` , `carbs` , `fat` on recipes; admin + UI.
- **Phase 4 (Cooking Mode):** `step_videos` , `step_timers` ; fullscreen overlay.
2026-05-23 10:23:28 +02:00
- **Phase 6 (Postgres):** Normalized SQL tables; `db-seed.php` ; no runtime JSON recipes.
2026-05-23 10:13:00 +02:00
- **Local dev Postgres:** `docker-compose.dev.yml` , README section, `scripts/db-check.php` , `.env.example` with `DATABASE_URL` .
2026-05-23 10:23:28 +02:00
- **Local profile data:** Favorites/goals via `assets/fc-local.js` (`localStorage` ). Newsletter via `mailto:` .
2026-05-23 10:13:00 +02:00
## 9. Next Steps
See `.agents/TODO.md` (e.g. PWA & offline support). README `Local Postgres (Docker)` and `Postgres in diesem Projekt` sections mirror setup for humans.
## 10. Key file map (data layer)
| File | Purpose |
|------|---------|
| `config.php` | `.env` , Firebase config, PDO |
2026-06-18 09:53:39 +02:00
| `helpers.php` | `init_db` , `load_recipes` , `save_recipe` , site settings |
| `scripts/seed-data.php` | Seed arrays for recipes and site settings |
2026-05-23 10:13:00 +02:00
| `docker-compose.dev.yml` | Local Postgres |
| `scripts/db-check.php` | Connection + seed smoke test |
| `partials/head.php` | Firebase init via `get_firebase_config()` |