diff --git a/docs/superpowers/plans/2026-05-04-bovine-info-saisie.md b/docs/superpowers/plans/2026-05-04-bovine-info-saisie.md
new file mode 100644
index 0000000..e566c08
--- /dev/null
+++ b/docs/superpowers/plans/2026-05-04-bovine-info-saisie.md
@@ -0,0 +1,598 @@
+# Saisie information bovin (post-EDNOTIF) — Plan d'implémentation
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+>
+> **Mode utilisateur :** L'utilisateur souhaite valider chaque étape avant exécution (cf. memory `feedback_step_by_step_validation`). Avant chaque task, présenter ce qui va être fait et attendre OK explicite.
+
+**Goal:** Ajouter un écran de saisie post-EDNOTIF (poids, prix/kg, bâtiment, case) accessible depuis le tableau "Entrées validées", structuré en accordéons-par-bovin.
+
+**Architecture:** Un nouveau composant `UiAccordion` réutilisable. Une nouvelle page Nuxt `entry-exit/bovine-info/[id].vue` qui charge la réception et ses bovins, instancie un accordéon par bovin et délègue la saisie à un sous-composant `bovine-info-form.vue`. Pas de nouvel endpoint, pas de migration : on PATCH les `Bovine` existants (`receivedWeight`, `pricePerKg`, `buildingCase`). Mini ajustement backend : exposer les ids de `BuildingCase` et `Building` dans le groupe de sérialisation `bovine:read`, sinon on n'a pas de quoi pré-remplir les selectors.
+
+**Tech Stack:** Symfony 8 + API Platform 4 (annotations Groups) ; Nuxt 4 + Vue 3 + Tailwind ; pas de tests automatisés (cohérent avec le reste de la feature entry-exit, cf. spec).
+
+**Spec source:** `docs/superpowers/specs/2026-05-04-bovine-info-saisie-design.md`
+
+**Branche de travail:** `feat/entree-sortie` (déjà créée).
+
+---
+
+## Synthèse du file-mapping
+
+| Fichier | Type | Responsabilité |
+| --- | --- | --- |
+| `src/Entity/BuildingCase.php` | Modify | Ajouter `bovine:read` au groupe de `id` |
+| `src/Entity/Building.php` | Modify | Ajouter `bovine:read` au groupe de `id` |
+| `frontend/services/dto/bovine-data.ts` | Modify | Ajouter `id` à `BovineBuildingRef` et `BovineBuildingCaseRef` |
+| `frontend/components/ui/UiAccordion.vue` | Create | Composant réutilisable, header en slot, body en slot, v-model boolean |
+| `frontend/components/entry-exit/bovine-info-form.vue` | Create | Sous-composant : 4 champs + bouton Valider, émet `saved` |
+| `frontend/pages/entry-exit/bovine-info/[id].vue` | Create | Page : header, fetch, tri, état d'ouverture, rendu liste d'accordéons |
+| `frontend/pages/entry-exit/index.vue` | Modify | Ajouter `row-clickable` + `@row-click` au tableau "Entrées validées" |
+
+---
+
+## Task 1 : Exposer les ids `BuildingCase` et `Building` dans `bovine:read`
+
+**Contexte :** Quand l'API normalise un `Bovine` avec le groupe `bovine:read`, l'embedded `buildingCase` ne contient que `caseNumber` et `building.label`. Pas d'ids → pas de pré-remplissage possible. On ajoute le groupe `bovine:read` aux deux propriétés `id` concernées (zéro changement de schéma, juste un attribut PHP).
+
+**Files:**
+- Modify: `src/Entity/BuildingCase.php:42`
+- Modify: `src/Entity/Building.php:36`
+
+- [ ] **Step 1 : Patch `BuildingCase.id`**
+
+```php
+// src/Entity/BuildingCase.php — remplacer
+#[Groups(['building:read', 'building_case:read'])]
+private ?int $id = null;
+
+// par
+#[Groups(['building:read', 'building_case:read', 'bovine:read'])]
+private ?int $id = null;
+```
+
+- [ ] **Step 2 : Patch `Building.id`**
+
+```php
+// src/Entity/Building.php — remplacer
+#[Groups(['building:read', 'building:summary', 'reception:read'])]
+private ?int $id = null;
+
+// par
+#[Groups(['building:read', 'building:summary', 'reception:read', 'bovine:read'])]
+private ?int $id = null;
+```
+
+- [ ] **Step 3 : Vider le cache (les groupes sont compilés)**
+
+```bash
+make cache-clear
+```
+
+- [ ] **Step 4 : Vérifier que les tests existants passent**
+
+```bash
+make test
+```
+
+Attendu : 9/9 tests OK (aucun changement de comportement, juste une exposition supplémentaire).
+
+- [ ] **Step 5 : Vérification manuelle rapide**
+
+```bash
+curl -s -H "Authorization: Bearer $TOKEN" \
+ 'http://localhost:8080/api/bovines/1' | jq '.buildingCase'
+```
+
+Attendu : la réponse contient `id` (numérique) en plus de `caseNumber`, et `buildingCase.building` contient `id` en plus de `label`. Si le bovin n'a pas de buildingCase, ce sera `null` — prendre un id de bovin qui en a un (sinon ignorer cette étape).
+
+- [ ] **Step 6 : Commit**
+
+```bash
+git add src/Entity/BuildingCase.php src/Entity/Building.php
+git commit -m "feat(api) : exposer BuildingCase.id et Building.id dans bovine:read"
+```
+
+---
+
+## Task 2 : Compléter le DTO frontend `BovineData`
+
+**Files:**
+- Modify: `frontend/services/dto/bovine-data.ts`
+
+- [ ] **Step 1 : Ajouter `id` aux deux interfaces de référence**
+
+Remplacer le bloc en haut du fichier :
+
+```ts
+export interface BovineBuildingRef {
+ id: number
+ label: string
+}
+
+export interface BovineBuildingCaseRef {
+ id: number
+ caseNumber: number | null
+ building: BovineBuildingRef | null
+}
+```
+
+- [ ] **Step 2 : Vérifier que TypeScript ne casse pas**
+
+```bash
+cd frontend && npx vue-tsc --noEmit 2>&1 | head -40
+```
+
+Attendu : pas d'erreur (les autres pages qui consomment `BovineData` ne lisaient pas l'`id` depuis ces sous-objets ; ajouter un champ ne casse rien).
+
+Si erreurs inattendues, les corriger en touchant seulement les call-sites pointés par tsc.
+
+- [ ] **Step 3 : Commit**
+
+```bash
+git add frontend/services/dto/bovine-data.ts
+git commit -m "feat(front) : id dans BovineBuildingRef et BovineBuildingCaseRef"
+```
+
+---
+
+## Task 3 : Créer `UiAccordion`
+
+**Files:**
+- Create: `frontend/components/ui/UiAccordion.vue`
+
+- [ ] **Step 1 : Écrire le composant**
+
+```vue
+
+
+
+
+
+
+
+
+
+
+```
+
+- [ ] **Step 2 : Vérifier l'auto-import**
+
+Nuxt auto-importe les composants de `components/ui/` avec le préfixe `Ui` (cf. CLAUDE.md). Donc `` sera utilisable sans import explicite. Pas d'action ici, juste validation mentale.
+
+- [ ] **Step 3 : Commit**
+
+```bash
+git add frontend/components/ui/UiAccordion.vue
+git commit -m "feat(front) : composant UiAccordion réutilisable"
+```
+
+---
+
+## Task 4 : Créer `bovine-info-form.vue` (sous-composant)
+
+**Contexte :** Encapsule l'état local et le formulaire d'un bovin. Reçoit le bovin et la liste de bâtiments, émet `saved` avec le bovin mis à jour. Permet à la page parent de rester lisible.
+
+**Files:**
+- Create: `frontend/components/entry-exit/bovine-info-form.vue`
+
+- [ ] **Step 1 : Écrire le composant**
+
+```vue
+
+
+
+
+
+```
+
+> Note : on utilise `application/merge-patch+json` comme content-type côté API Platform pour les PATCH (la convention par défaut). `useApi.patch` a déjà ce content-type par défaut — la ligne `headers` est ici **à supprimer** si `useApi.patch` le pose déjà. Vérifier dans `composables/useApi.ts` à l'étape suivante.
+
+- [ ] **Step 2 : Vérifier le content-type par défaut de `useApi.patch`**
+
+```bash
+grep -n "patch" frontend/composables/useApi.ts | head -10
+```
+
+- Si `useApi.patch` injecte déjà `application/merge-patch+json`, **retirer** le bloc `headers` du composant ci-dessus.
+- Sinon, le garder.
+
+- [ ] **Step 3 : Commit**
+
+```bash
+git add frontend/components/entry-exit/bovine-info-form.vue
+git commit -m "feat(front) : sous-composant bovine-info-form (4 champs + valider)"
+```
+
+---
+
+## Task 5 : Créer la page `bovine-info/[id].vue`
+
+**Files:**
+- Create: `frontend/pages/entry-exit/bovine-info/[id].vue`
+
+- [ ] **Step 1 : Écrire la page**
+
+```vue
+
+
+
+
+
+ Saisie information bovin {{ reception?.identificationNumber ?? '' }}
+
+
+
+
+```
+
+> Note de style : `BovineInfoForm` est référencé sans import — Nuxt auto-importe les composants `components/entry-exit/*.vue` avec un PascalCase basé sur le nom de fichier (à confirmer ; sinon, ajouter `import BovineInfoForm from '~/components/entry-exit/bovine-info-form.vue'`).
+
+- [ ] **Step 2 : Vérifier l'auto-import**
+
+```bash
+cd frontend && npm run dev
+```
+
+Aller sur `http://localhost:3000/entry-exit/bovine-info/` (id d'une réception validée). Si erreur "BovineInfoForm is not defined", ajouter l'import explicite. Si rendu OK, continuer.
+
+- [ ] **Step 3 : Commit**
+
+```bash
+git add frontend/pages/entry-exit/bovine-info/'[id].vue'
+git commit -m "feat(front) : page saisie information bovin (accordéons)"
+```
+
+---
+
+## Task 6 : Câbler la navigation depuis le tableau "Entrées validées"
+
+**Files:**
+- Modify: `frontend/pages/entry-exit/index.vue`
+
+- [ ] **Step 1 : Ajouter la fonction de navigation**
+
+Dans le `