diff --git a/.gitignore b/.gitignore
index 872d5f6..c2e1081 100644
--- a/.gitignore
+++ b/.gitignore
@@ -141,3 +141,6 @@ dist
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.vite/
+
+# Project docs not meant to be committed
+Projet batch cooking.pdf
diff --git a/specs/batch-cooking-architecture.md b/specs/batch-cooking-architecture.md
new file mode 100644
index 0000000..9332a8a
--- /dev/null
+++ b/specs/batch-cooking-architecture.md
@@ -0,0 +1,72 @@
+# Architecture technique — Projet Batch-cooking
+
+> Documentation de l'architecture serveur/client de l'application.
+
+---
+
+## Vue d'ensemble
+
+L'application repose sur une architecture **client-serveur** classique :
+
+- Un **serveur** exposant une **API** (échanges standards) et un canal **websocket** (communication temps réel)
+- Plusieurs **clients** (Client 1, Client 2, Client 3...) connectés simultanément au serveur
+- Une base de données **PostgreSQL**
+
+```mermaid
+flowchart TB
+ subgraph SERVER["Server"]
+ WS["Web socket"]
+ API["API"]
+ CALC["Calcul batch-cooking
(TODO)"]
+ IMPORT["Import d'une recette"]
+ IMP1["Import depuis source"]
+ IMP2["Traduction en étapes"]
+ IMP3["Sauvegarde"]
+ DB[("Database
PostgreSQL")]
+
+ IMPORT --> IMP1 --> IMP2 --> IMP3 --> DB
+ CALC --> WS
+ end
+
+ C1["Client 1"]
+ C2["Client 2"]
+ C3["Client 3"]
+
+ API <--> C1
+ API <--> C2
+ API <--> C3
+ WS --> C1
+ WS --> C2
+ WS --> C3
+
+ style SERVER fill:none,stroke:#888,stroke-width:1px
+```
+
+---
+
+## Composants
+
+### API
+Point d'entrée principal pour les échanges entre les clients et le serveur (requêtes classiques).
+
+### Web socket
+Canal de communication temps réel entre le serveur et les clients connectés.
+
+### Module « Calcul batch-cooking »
+Logique de calcul du batch-cooking (optimisation du planning/des recettes selon le planning). **Statut : TODO — reste à développer.**
+
+### Module « Import d'une recette »
+Pipeline d'ajout d'une recette, en trois étapes :
+1. **Import depuis source** — récupération de la recette (via `sources`)
+2. **Traduction en étapes** — découpage en `step` / `tech_step`
+3. **Sauvegarde** — persistance en base de données
+
+### Database (PostgreSQL)
+Stockage de l'ensemble des données de l'application (voir le modèle de données pour le détail des tables).
+
+---
+
+## Notes
+
+- Le module de calcul batch-cooking est le principal chantier restant côté serveur (TODO).
+- Le websocket est utilisé pour la communication temps réel, en complément de l'API.
diff --git a/specs/batch-cooking-modele.md b/specs/batch-cooking-modele.md
new file mode 100644
index 0000000..32804f2
--- /dev/null
+++ b/specs/batch-cooking-modele.md
@@ -0,0 +1,251 @@
+# Modèle de données — Projet Batch-cooking
+
+> Documentation du schéma de données de l'application de planification de batch-cooking.
+
+---
+
+## Vue d'ensemble
+
+Le modèle s'articule autour de trois grands pôles :
+
+- **Utilisateurs & foyer** — `user_profiles`, `house`, `diet`, `allergy`, `category`
+- **Planification** — `planning`, `planning_item`
+- **Recettes** — `recipe`, `ingredients`, `step`, `tech_step`, `tech_step_mapping`, `sources`
+
+---
+
+## Schéma entité-relation
+
+```mermaid
+erDiagram
+ USER_PROFILES }o--|| HOUSE : "vit dans"
+ USER_PROFILES }o--|| DIET : "suit"
+ HOUSE ||--o{ PLANNING : "planifie"
+ PLANNING ||--o{ PLANNING_ITEM : "contient"
+ PLANNING_ITEM }o--|| RECIPE : "utilise"
+ RECIPE }o--|| SOURCES : "vient de"
+ CATEGORY ||--o{ ALLERGY : "classe"
+ USER_PROFILES }o--o{ ALLERGY : "a"
+ RECIPE }o--o{ INGREDIENTS : "compose de"
+ RECIPE }o--o{ STEP : "compose de"
+ STEP }o--|| TECH_STEP : "utilise"
+ TECH_STEP ||--o{ TECH_STEP_MAPPING : "mappe"
+ INGREDIENTS }o--|| RECIPE : "recette alternative"
+
+ USER_PROFILES {
+ int id PK
+ string first_name
+ string last_name
+ string email
+ int house_id FK
+ int diet_id FK
+ }
+ HOUSE {
+ int id PK
+ string name
+ }
+ PLANNING {
+ int id PK
+ date start_date
+ date finish_date
+ int house_id FK
+ }
+ PLANNING_ITEM {
+ int id PK
+ int planning_id FK
+ string week_day
+ string meal
+ int recipe_id FK
+ }
+ DIET {
+ int id PK
+ string name
+ }
+ ALLERGY {
+ int id PK
+ int cat_id FK
+ }
+ CATEGORY {
+ int id PK
+ string name
+ }
+ INGREDIENTS {
+ int id PK
+ string name
+ string icon
+ int alternate_recipe FK
+ }
+ RECIPE {
+ int id PK
+ string name
+ int source_id FK
+ string description
+ string picture
+ }
+ STEP {
+ int id PK
+ string description
+ string picture
+ int order
+ int tech_step_id FK
+ }
+ TECH_STEP {
+ int id PK
+ }
+ TECH_STEP_MAPPING {
+ int id PK
+ int tech_step_id FK
+ string expression
+ int weight
+ }
+ SOURCES {
+ int id PK
+ string name
+ string url
+ }
+```
+
+*(Rendu sur les visualiseurs markdown compatibles mermaid — GitHub, VS Code, Obsidian, etc.)*
+
+---
+
+## Tables
+
+### `user_profiles`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `first_name` | Prénom |
+| `last_name` | Nom |
+| `email` | Email |
+| `house_id` | FK → `house` |
+| `diet_id` | FK → `diet` |
+
+### `house`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `name` | Nom du foyer |
+
+### `diet`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `name` | Nom du régime alimentaire |
+
+### `allergy`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `cat_id` | FK → `category` |
+
+Associée à `user_profiles` en many-to-many (table de jointure simple, sans champ additionnel).
+
+### `category`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `name` | Nom de la catégorie |
+
+Table d'énumération, destinée à grandir au fil du projet (portera notamment les nuances liées aux allergies).
+
+### `planning`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `start_date` | Date de début |
+| `finish_date` | Date de fin |
+| `house_id` | FK → `house` |
+
+### `planning_item`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `planning_id` | FK → `planning` |
+| `week_day` | Jour de la semaine |
+| `meal` | Repas concerné |
+| `recipe_id` | FK → `recipe` |
+
+### `recipe`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `name` | Nom de la recette |
+| `source_id` | FK → `sources` |
+| `description` | Description |
+| `picture` | Image |
+
+Associée à `ingredients` en many-to-many.
+
+### `ingredients`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `name` | Nom |
+| `icon` | Icône |
+| `alternate_recipe` | FK → `recipe` (recette alternative) |
+
+### `step`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `description` | Description de l'étape |
+| `picture` | Image |
+| `order` | Ordre dans la recette |
+| `tech_step_id` | FK → `tech_step` |
+
+Associée à `recipe` en many-to-many.
+
+### `tech_step`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+
+### `tech_step_mapping`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `tech_step_id` | FK → `tech_step` |
+| `expression` | Expression |
+| `weight` | Poids |
+
+### `sources`
+| Champ | Description |
+|---|---|
+| `id` | Identifiant |
+| `name` | Nom de la source |
+| `url` | URL |
+
+---
+
+## Relations
+
+### Many-to-one (clés étrangères)
+
+| Table source | Champ FK | Table cible |
+|---|---|---|
+| `user_profiles` | `house_id` | `house` |
+| `user_profiles` | `diet_id` | `diet` |
+| `planning` | `house_id` | `house` |
+| `planning_item` | `planning_id` | `planning` |
+| `planning_item` | `recipe_id` | `recipe` |
+| `allergy` | `cat_id` | `category` |
+| `ingredients` | `alternate_recipe` | `recipe` |
+| `recipe` | `source_id` | `sources` |
+| `step` | `tech_step_id` | `tech_step` |
+| `tech_step_mapping` | `tech_step_id` | `tech_step` |
+
+### Many-to-many (associations)
+
+| Table A | Table B | Détail |
+|---|---|---|
+| `user_profiles` | `allergy` | Table de jointure simple |
+| `recipe` | `ingredients` | Composition d'une recette |
+| `step` | `recipe` | Étapes d'une recette |
+
+---
+
+## Règles de modélisation
+
+- Toute relation qualifiée d'**« association »** entre deux tables est une relation **many-to-many**.
+- `category` est une table d'énumération, amenée à grandir au fur et à mesure du projet.