feat(tickets): suppression d'un ticket (backend + frontend)

Ajoute la suppression complète d'un ticket (#6).

Backend Rust :
- port IssueStore::delete (NotFound si absent) + event IssueDeleted{freed_sprint}
- FsIssueStore::delete : supprime .ideai/tickets/<N>/ et l'index sous lock
- use case DeleteIssue + adaptations des tests sprint/ticket_assistant au port
- commande Tauri ticket_delete + câblage events/state/lib

Frontend :
- gateway delete (ports, adapter ticket + mock, domain)
- useTicketDetail : retrait de la liste et fermeture du détail via event issueDeleted
- intégration TicketDetail + tests

Tests verts : application/issue_usecases (6), infrastructure/issue_store (7),
app-tauri --lib (56), frontend vitest (503), npm run build (exit 0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 06:27:09 +02:00
parent d25e340b44
commit 5417bd756b
20 changed files with 689 additions and 95 deletions

View File

@ -764,6 +764,14 @@ export interface TicketGateway {
ref: string,
input: UpdateTicketInput,
): Promise<Ticket>;
/**
* Deletes a ticket (ticket #6). Rejects with a `notFound` {@link GatewayError}
* when the ref does not exist. On success the backend emits an `issueDeleted`
* domain event (payload `{ projectId, issueRef, freedSprint }`) — the single
* source of truth that drives the ticket's removal from lists and the closing
* of an open detail view. Callers must not mutate local state imperatively.
*/
delete(projectId: string, ref: string): Promise<void>;
/** Reads the ticket-scoped Markdown carnet. */
readCarnet(projectId: string, ref: string): Promise<TicketCarnet>;
/** Replaces (not appends) the ticket-scoped carnet body. */