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:
@ -2012,6 +2012,22 @@ export class MockTicketGateway implements TicketGateway {
|
||||
return structuredClone(ticket);
|
||||
}
|
||||
|
||||
async delete(projectId: string, ref: string): Promise<void> {
|
||||
// NotFound if absent (mirrors the backend `AppError::NotFound`).
|
||||
const ticket = this.require(projectId, ref);
|
||||
const freedSprint = ticket.sprintId ?? null;
|
||||
this.projectTickets(projectId).delete(ref);
|
||||
this.projectCarnets(projectId).delete(ref);
|
||||
// Releasing the ticket updates its former sprint's count.
|
||||
if (freedSprint) this.recountSprints(projectId);
|
||||
this.system?.emit({
|
||||
type: "issueDeleted",
|
||||
projectId,
|
||||
issueRef: ref,
|
||||
freedSprint,
|
||||
});
|
||||
}
|
||||
|
||||
async readCarnet(projectId: string, ref: string): Promise<TicketCarnet> {
|
||||
const ticket = this.require(projectId, ref);
|
||||
return {
|
||||
|
||||
@ -73,6 +73,15 @@ export class TauriTicketGateway implements TicketGateway {
|
||||
});
|
||||
}
|
||||
|
||||
async delete(projectId: string, ref: string): Promise<void> {
|
||||
// `ticket_delete` takes the shared `{ request }` envelope like every other
|
||||
// ticket command; a missing ref surfaces as a `NOT_FOUND` GatewayError from
|
||||
// the backend, propagated as-is.
|
||||
await invoke<void>("ticket_delete", {
|
||||
request: { projectId, ref },
|
||||
});
|
||||
}
|
||||
|
||||
async readCarnet(projectId: string, ref: string): Promise<TicketCarnet> {
|
||||
return invoke<TicketCarnet>("ticket_read_carnet", {
|
||||
request: { projectId, ref },
|
||||
|
||||
Reference in New Issue
Block a user