feat(tickets): ajoute les pièces jointes sur tickets (#108)
Stockage flat côté ticket + métadonnées d'attachments, lecture exposée côté backend/MCP, et UI minimale de liste/ajout dans TicketDetail. Traverse le domaine (Issue, ports), l'application (usecases + assistant de ticket), les adaptateurs infra/MCP (issues store, orchestrateur), les DTO backend/web- server/app-tauri, et le frontend (domain/ports/adapters/hooks/UI). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -40,7 +40,8 @@ use crate::ids::{
|
||||
AgentId, LocalModelServerId, NodeId, ProjectId, ScheduleId, SessionId, SprintId, TaskId,
|
||||
};
|
||||
use crate::issue::{
|
||||
Issue, IssueCarnet, IssueIndexEntry, IssueListFilter, IssueNumber, IssueRef, IssueVersion,
|
||||
Issue, IssueAttachment, IssueAttachmentId, IssueCarnet, IssueIndexEntry, IssueListFilter,
|
||||
IssueNumber, IssueRef, IssueVersion,
|
||||
};
|
||||
use crate::markdown::MarkdownDoc;
|
||||
use crate::mcp_tool_permissions::ProjectMcpToolPermissions;
|
||||
@ -980,6 +981,15 @@ pub enum IssueStoreError {
|
||||
Store(String),
|
||||
}
|
||||
|
||||
/// Raw ticket attachment content.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct IssueAttachmentContent {
|
||||
/// Attachment metadata.
|
||||
pub attachment: IssueAttachment,
|
||||
/// Raw bytes.
|
||||
pub bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
/// Errors from the sprint store.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Error)]
|
||||
pub enum SprintStoreError {
|
||||
@ -2360,6 +2370,40 @@ pub trait IssueStore: Send + Sync {
|
||||
now_ms: u64,
|
||||
expected_version: IssueVersion,
|
||||
) -> Result<IssueCarnet, IssueStoreError>;
|
||||
|
||||
/// Copies a local file into the ticket attachment folder and updates issue
|
||||
/// metadata after checking the issue version.
|
||||
async fn add_attachment_from_path(
|
||||
&self,
|
||||
root: &ProjectPath,
|
||||
issue_ref: IssueRef,
|
||||
source: &LocalPath,
|
||||
attachment_id: IssueAttachmentId,
|
||||
filename: String,
|
||||
mime: String,
|
||||
actor: crate::issue::IssueActor,
|
||||
now_ms: u64,
|
||||
expected_version: IssueVersion,
|
||||
) -> Result<Issue, IssueStoreError>;
|
||||
|
||||
/// Reads an attachment's raw bytes.
|
||||
async fn read_attachment(
|
||||
&self,
|
||||
root: &ProjectPath,
|
||||
issue_ref: IssueRef,
|
||||
attachment_id: &IssueAttachmentId,
|
||||
) -> Result<IssueAttachmentContent, IssueStoreError>;
|
||||
|
||||
/// Marks an attachment as summarized in the ticket carnet.
|
||||
async fn mark_attachment_summarized(
|
||||
&self,
|
||||
root: &ProjectPath,
|
||||
issue_ref: IssueRef,
|
||||
attachment_id: &IssueAttachmentId,
|
||||
actor: crate::issue::IssueActor,
|
||||
now_ms: u64,
|
||||
expected_version: IssueVersion,
|
||||
) -> Result<Issue, IssueStoreError>;
|
||||
}
|
||||
|
||||
/// Persistence port for project-scoped sprints.
|
||||
|
||||
Reference in New Issue
Block a user