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:
@ -241,6 +241,16 @@ pub enum DomainEventDto {
|
||||
/// New optimistic version.
|
||||
version: u64,
|
||||
},
|
||||
/// An issue-backed public ticket was deleted.
|
||||
#[serde(rename_all = "camelCase")]
|
||||
IssueDeleted {
|
||||
/// Project id.
|
||||
project_id: String,
|
||||
/// Deleted public ticket reference (`#N`).
|
||||
issue_ref: String,
|
||||
/// Released sprint id, when any.
|
||||
freed_sprint: Option<String>,
|
||||
},
|
||||
/// A public ticket status changed.
|
||||
#[serde(rename_all = "camelCase")]
|
||||
IssueStatusChanged {
|
||||
@ -781,6 +791,15 @@ impl From<&DomainEvent> for DomainEventDto {
|
||||
issue_ref: issue_ref.to_string(),
|
||||
version: version.get(),
|
||||
},
|
||||
DomainEvent::IssueDeleted {
|
||||
project_id,
|
||||
issue_ref,
|
||||
freed_sprint,
|
||||
} => Self::IssueDeleted {
|
||||
project_id: project_id.to_string(),
|
||||
issue_ref: issue_ref.to_string(),
|
||||
freed_sprint: freed_sprint.map(|sprint| sprint.to_string()),
|
||||
},
|
||||
DomainEvent::IssueStatusChanged {
|
||||
issue_ref,
|
||||
status,
|
||||
@ -1106,6 +1125,22 @@ mod tests {
|
||||
assert_eq!(json["version"], 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_deleted_relays_to_dto_and_wire() {
|
||||
let project_id = domain::ProjectId::from_uuid(uuid::Uuid::from_u128(40));
|
||||
let sprint_id = domain::SprintId::from_uuid(uuid::Uuid::from_u128(42));
|
||||
let dto = DomainEventDto::from(&DomainEvent::IssueDeleted {
|
||||
project_id,
|
||||
issue_ref: domain::IssueRef::from(domain::IssueNumber::new(7).unwrap()),
|
||||
freed_sprint: Some(sprint_id),
|
||||
});
|
||||
let json = serde_json::to_value(&dto).expect("serialisable");
|
||||
assert_eq!(json["type"], "issueDeleted");
|
||||
assert_eq!(json["projectId"], project_id.to_string());
|
||||
assert_eq!(json["issueRef"], "#7");
|
||||
assert_eq!(json["freedSprint"], sprint_id.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ticket_assistant_events_relay_to_dto_and_wire() {
|
||||
let profile_id = domain::ProfileId::from_uuid(uuid::Uuid::from_u128(9));
|
||||
|
||||
Reference in New Issue
Block a user