# L10 — Fenêtres & multi-window

**Binôme :** `dev-windows` / `test-windows`
**Zones :** `application`, `app-tauri`, `frontend/app`
**Dépendances amont :** L0, L1, L2, L4.

## Objectif
Gestion des fenêtres et onglets : un onglet par projet ; **drag d'un onglet hors de la fenêtre → nouvelle fenêtre OS** portant ce projet.

## Périmètre (DEV)
- Entités `Workspace`/`Window`/`Tab` + persistance (`workspace.json`, machine-local).
- Use case `MoveTabToNewWindow` (réaffectation `WindowId`, l'onglet est déplacé, pas dupliqué).
- `app-tauri` : création de `WebviewWindow`, transfert d'état, fermeture de l'onglet source.
- Front : barre d'onglets, drag & drop, restauration de session.

## Périmètre (TEST)
- `MoveTabToNewWindow` : invariants (un projet dans un seul onglet à la fois ; fenêtre ≥ 1 onglet ou fermée).
- Persistance workspace round-trip.
- Front : interactions onglets (mock).

## Definition of Done
- `cargo test` + `vitest` verts ; détacher un onglet en nouvelle fenêtre fonctionne (dev manuel).

## Avancement

### ✅ Backend (vert)
- **Domaine** : opération **pure** `Workspace::move_tab_to_new_window(tab, new_window)` (`layout.rs`) — l'onglet est *déplacé* (jamais dupliqué) ; fenêtre source vidée → supprimée ; onglet actif déplacé → repli sur un onglet restant. Variante d'erreur `LayoutError::TabNotFound`. 4 tests domaine.
- **Application** (`application/window/`) : `MoveTabToNewWindow` (charge le workspace, mint `WindowId`, applique l'op pure, persiste via `ProjectStore`). 2 tests (store mock). La persistance round-trip du workspace est déjà couverte par `FsProjectStore` (L2).
- `cargo test --workspace` : **323 verts, 0 régression** ; clippy clean.

### ✅ IPC `app-tauri` (vert)
- Composition root : use case `MoveTabToNewWindow` injecté. Commande `move_tab_to_new_window(tabId)` : applique la topologie (persistée) **et ouvre une vraie `WebviewWindow`** (primitive de détach résolue). DTO `MoveTabResultDto` + `parse_tab_id`. Test `tests/dto_window.rs` (2). Workspace **325 verts, 0 régression**, clippy clean.

### ⏳ Reste (fait pendant la refonte disposition L11)
- **Front multi-fenêtres** : adopter le modèle `Workspace`/`Window`/`Tab` persistant (aujourd'hui les onglets vivent en state React transitoire), barre d'onglets, **DnD detach** + handoff d'état vers la nouvelle fenêtre. Couplé à la refonte de disposition IDE (L11), donc traité là-bas pour éviter de construire une barre d'onglets jetable.

## Spike (cf. ARCHITECTURE §13)
- DnD inter-fenêtres Tauri (le DnD HTML ne traverse pas les fenêtres OS) → protocole « detach » via store + event.
