Files
IdeA/.ideai/memory/ui-rework-sprint-scoping-contracts.md
Blomios ed58afa034 docs(memory): nettoie la mémoire projet obsolète (#178)
- MEMORY.md : index des notes recentré
- remaining-work-idea-agent-control-ide.md : réécriture alignée sur l'app actuelle
- ui-rework-sprint-scoping-contracts.md : mise à jour
- supprime 3 notes périmées : cycle-151-167-155-git-topology, develop-realigned-to-cli-ui-baseline-2026-07-02, ticket4-restart-on-develop-ebd992e

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-11 12:29:32 +02:00

2.9 KiB

name, description, metadata
name description metadata
ui-rework-sprint-scoping-contracts Frontières hexagonales et contrats figés du sprint UI rework — les 4 tickets sont frontend-purs, la popup TicketPicker
type
reference

Sprint « UI rework » (order 1), cadré 2026-07-06. Les 4 tickets sont frontend-purs : aucun nouveau port/read-model/endpoint.

Fait clé : filtrage/recherche tickets déjà backend-driven via TicketGateway.list(projectId, TicketListQuery{statuses[],priorities[],assignedAgentId,text,limit,cursor}) (ports/index.ts:717) → adapter transmet à ticket_list. Client ne fait que le groupement par sprint. #18 réutilise ce contrat, pas d'endpoint dédié.

G4 (contrat ticket_list) levé pour B après revue DevBackend : statuses/priorities OK (OR intra / AND inter). Deux écarts en DETTE BASSE : (a) text ne matche pas #ref (tickets.rs:681, issues.rs:322/326/465) ; (b) cursor = offset numérique non opaque/non stable inter-pages (tickets.rs:1231). Acceptable pour picker single-select court.

G3-bis (garde non-breaking) : TicketPicker/useTicketSearch traitent cursor comme token OPAQUE — ne jamais le construire/incrémenter, ne relayer que le cursor de la page précédente. Migration curseur opaque backend = zéro changement frontend.

Base de code : pas de routeur ni store global (navigation = useState local App.tsx + ProjectsView.tsx, sidebar inline ProjectsView.tsx:224). Aucune primitive Modal/Portal partagée ; ~7 features hand-roll fixed inset-0 role=dialog z-50/z-[60]. Pas de createPortal. #16 introduit shared/ui/FloatingWindow (focus-trap, monté niveau chrome) + shared/ui/zIndex.ts.

Contrat #18 figé — TicketPicker props {open, projectId, title?, confirmLabel?, selectionMode?:"single"|"multi" (défaut single), excludeRefs?: TicketRef[] (filtré client-side), initialQuery?: TicketListQuery, onSelect(TicketPickerResult|[]), onClose}. TicketPickerResult={ref,id,number,title,status,priority}. Extraire TicketFacetsBar (fieldsets statut/priorité + recherche depuis TicketsPanel.tsx) + hook useTicketSearch (ne PAS réutiliser useTickets, trop lourd). #17 et #19 consomment en single.

Échelle z-index figée (G2) : in-cell inchangé (chrome 2-5, F3 z-20, write-portal z-4) ; chrome full-window menuDropdown=40, floatingWindow=50, floatingWindowNested=60, toast=70.

Règle intégration (G5) : fenêtres flottantes/menus montées niveau chrome (ProjectsView/App), JAMAIS dans LayoutGrid/LeafView. Ne pas toucher shouldShowWritePortalVeil ni exclusion write-portal↔F3 (cf. ticket4-overlay-composition-leafview). Focus-trap obligatoire (xterm garde le focus clavier).

Ordre : A(#16) ∥ B(#18) racines → prioriser B (chemin critique #17+#19) ; D(#19) après B ; C(#17) après A+B. Tout DevFrontend ; DevBackend = ticket dette basse (matching #ref + curseur opaque/stable).