# סכמת מסד הנתונים — Recipe Manager

‏PostgreSQL 15+ עם ההרחבות: `pgcrypto`, `citext`, `pg_trgm`, `vector` (pgvector).
המיגרציה המלאה: [`db/migrations/0001_init.sql`](../db/migrations/0001_init.sql).

## החלטות מרכזיות

| החלטה | נימוק |
|---|---|
| `uuid` כמפתח ראשי | מזהים לא ניתנים לניחוש (פרטיות מתכונים), נוח לשילוב עם S3 ולקוחות |
| `citext` לאימייל/handle/שם מרכיב | ייחודיות case-insensitive בלי אינדקסי lower() |
| Soft-delete ‏(`deleted_at`) | על users, recipes, comments, collections — שחזור ומחיקה רכה לפני סופית |
| `share_token` על recipe | פרטיות `link` — שיתוף בקישור בלי חשיפה ציבורית |
| `allergens text[]` + GIN | סינון קשיח ומהיר של אלרגנים בחיפוש (`NOT allergens && $1`) |
| מילון `ingredients` קנוני + `aliases` | נרמול מרכיבים, זיהוי אלרגנים אוטומטי, סינון "עם/בלי מרכיב" |
| `recipe_ingredients.group_label` | קבוצות כמו "לרוטב" / "לבצק" |
| תגובות מקוננות `parent_id` + ‏`kind` | שאלה / טיפ / הכנתי / ביקורת; `is_author_reply` לתשובת המחבר |
| Triggers לדירוג | `rating_avg`/`rating_count` מוחזקים על השורה — קריאה זולה בדפי רשימה |
| אינדקס trigram על title | השלמה לחיפוש הסמנטי במונחים מדויקים |

## חיפוש סמנטי — `recipe_embeddings`

- `vector(1536)` — המימד של `openai/text-embedding-3-small`, המודל שמוגש דרך **שכבת ה-BRAIN** (ראה [semantic-search.md](semantic-search.md)).
- אינדקס **HNSW** עם `vector_cosine_ops` ‏(m=16, ef_construction=64) — חיפוש ANN מהיר.
- `unified_text` נשמר לצד הווקטור — דיבוג, re-embed בהחלפת מודל, והפקת "סיבת התאמה".
- עדכון מתכון ⇐ ג'וב בתור (pg-boss) מרכיב טקסט מאוחד ומחשב embedding מחדש.

## ERD מקוצר

```
users ─┬─< recipes ─┬─< recipe_ingredients >─ ingredients
       │            ├─< recipe_steps
       │            ├─< recipe_images
       │            ├─< comments (self-ref parent_id)
       │            ├─── recipe_embeddings (1:1)
       │            ├─< ratings, favorites, cook_history
       │            └─< collection_recipes >─ collections
       ├─< notifications
       └─< reports
```
