@breign/db-schemas 0.1.75 → 0.1.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,7 @@
1
1
  import { ChatMessageRoleUio } from '@breign/client';
2
2
  import type { ToolCallApprovalScope } from './pending-tool-call';
3
+ import type { AgentTicketCreation } from './project';
4
+ import type { TicketProposalPayload, TicketProposalStatus } from './ticket';
3
5
  import type { ToolAction, ToolResult } from './tool-result';
4
6
  export type ConversationMessageReaction = 'positive' | 'negative';
5
7
  export type ConversationAttachmentStatus = 'TO_UPLOAD' | 'PROCESSING' | 'PROCESSED' | 'ERROR';
@@ -112,6 +114,20 @@ export type ConversationHumanRequest = {
112
114
  answeredAt?: string;
113
115
  expiresAt?: string;
114
116
  };
117
+ /**
118
+ * Un ticket qu'un agent propose depuis cette conversation (outil `Ticket_create`). La carte affichée
119
+ * sous le message se met à jour quand la proposition est acceptée, écartée ou annulée.
120
+ */
121
+ export type ConversationTicketProposal = {
122
+ proposalId: string;
123
+ status: TicketProposalStatus;
124
+ mode: AgentTicketCreation;
125
+ /** Projet proposé par l'agent ; null = l'humain doit en choisir un. */
126
+ projectId: string | null;
127
+ payload: TicketProposalPayload;
128
+ ticketId: string | null;
129
+ ticketKey: string | null;
130
+ };
115
131
  export type ConversationMessage = {
116
132
  id: string;
117
133
  role: ChatMessageRoleUio;
@@ -133,6 +149,8 @@ export type ConversationMessage = {
133
149
  approvals?: ConversationMessageApproval[];
134
150
  /** Question posée à l'humain par une tâche. Voir ConversationHumanRequest. */
135
151
  humanRequest?: ConversationHumanRequest;
152
+ /** Ticket proposé par l'agent dans ce message. Voir ConversationTicketProposal. */
153
+ ticketProposal?: ConversationTicketProposal;
136
154
  suggestions?: {
137
155
  id: string;
138
156
  text: string;
@@ -175,6 +193,11 @@ export type ConversationContext = {
175
193
  lastActivityAt?: string;
176
194
  /** Tâche ouverte par un agent local via le serveur MCP de Breign. */
177
195
  externalCaller?: ConversationExternalCaller;
196
+ /** Ticket auquel cette conversation est liée (proposition acceptée, session de travail). */
197
+ ticket?: {
198
+ ticketId: string;
199
+ projectId: string;
200
+ };
178
201
  };
179
202
  export type ConversationExternalCaller = {
180
203
  kind: 'local_agent';
@@ -0,0 +1,27 @@
1
+ import type { ActorRef } from './project';
2
+ /**
3
+ * `question`, `ticket_proposal`, `review` et `go_ahead` sont des actions (onglet « À traiter ») ;
4
+ * `mention` a son propre onglet.
5
+ */
6
+ export type InboxItemKind = 'question' | 'ticket_proposal' | 'review' | 'go_ahead' | 'mention';
7
+ /** Ce qui attend un humain : écrit quand l'action naît, résolu quand elle est faite. */
8
+ export type InboxItem = {
9
+ id: string;
10
+ organizationId: string;
11
+ userId: string;
12
+ kind: InboxItemKind;
13
+ requestedBy: ActorRef;
14
+ projectId: string | null;
15
+ ticketId: string | null;
16
+ /**
17
+ * Objet visé : `callId` d'une question, `proposalId` d'une proposition, événement d'une mention,
18
+ * ticket d'une relecture, ticket d'un feu vert (avec l'agent dans `data.agentId`).
19
+ */
20
+ refId: string;
21
+ summary: string;
22
+ data: Record<string, unknown>;
23
+ status: 'pending' | 'done';
24
+ resolution: Record<string, unknown> | null;
25
+ createdAt: string;
26
+ resolvedAt: string | null;
27
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -8,16 +8,19 @@ export * from './engine';
8
8
  export * from './file';
9
9
  export * from './flow';
10
10
  export * from './flow-editor';
11
+ export * from './inbox';
11
12
  export * from './knowledge';
12
13
  export * from './ocr';
13
14
  export * from './organization';
14
15
  export * from './pending-tool-call';
16
+ export * from './project';
15
17
  export * from './permissions';
16
18
  export * from './role';
17
19
  export * from './scheduled-task';
18
20
  export * from './scheduled-task-run';
19
21
  export * from './skill';
20
22
  export * from './speech-to-text';
23
+ export * from './ticket';
21
24
  export * from './tool';
22
25
  export * from './tool-approval';
23
26
  export * from './tool-result';
@@ -24,16 +24,19 @@ __exportStar(require("./engine"), exports);
24
24
  __exportStar(require("./file"), exports);
25
25
  __exportStar(require("./flow"), exports);
26
26
  __exportStar(require("./flow-editor"), exports);
27
+ __exportStar(require("./inbox"), exports);
27
28
  __exportStar(require("./knowledge"), exports);
28
29
  __exportStar(require("./ocr"), exports);
29
30
  __exportStar(require("./organization"), exports);
30
31
  __exportStar(require("./pending-tool-call"), exports);
32
+ __exportStar(require("./project"), exports);
31
33
  __exportStar(require("./permissions"), exports);
32
34
  __exportStar(require("./role"), exports);
33
35
  __exportStar(require("./scheduled-task"), exports);
34
36
  __exportStar(require("./scheduled-task-run"), exports);
35
37
  __exportStar(require("./skill"), exports);
36
38
  __exportStar(require("./speech-to-text"), exports);
39
+ __exportStar(require("./ticket"), exports);
37
40
  __exportStar(require("./tool"), exports);
38
41
  __exportStar(require("./tool-approval"), exports);
39
42
  __exportStar(require("./tool-result"), exports);
@@ -0,0 +1,56 @@
1
+ /** Auteur ou destinataire d'une action : un humain, un agent ou le système. */
2
+ export type ActorType = 'user' | 'agent' | 'system';
3
+ /** Membre d'un projet ou assigné d'un ticket : un humain ou un agent. */
4
+ export type MemberType = 'user' | 'agent';
5
+ export type ActorRef = {
6
+ type: ActorType;
7
+ /** Identifiant de l'utilisateur ou de l'agent ; null pour le système. */
8
+ id: string | null;
9
+ };
10
+ export type MemberRef = {
11
+ type: MemberType;
12
+ id: string;
13
+ };
14
+ /**
15
+ * Ce qui se passe quand un agent crée un ticket : `confirm`, l'agent propose et un humain confirme ;
16
+ * `direct`, le ticket est créé tout de suite et la création reste annulable.
17
+ */
18
+ export type AgentTicketCreation = 'confirm' | 'direct';
19
+ /** `now` : les agents assignés commencent dès l'assignation ; `hold` : ils attendent un feu vert. */
20
+ export type TicketStartMode = 'now' | 'hold';
21
+ export type ProjectSettings = {
22
+ agentTicketCreation: AgentTicketCreation;
23
+ defaultStartMode: TicketStartMode;
24
+ /**
25
+ * Les agents assignés se mettent au travail d'eux-mêmes quand on leur confie le ticket ou qu'on
26
+ * leur parle. Absent = activé.
27
+ */
28
+ agentsAutoWork?: boolean;
29
+ };
30
+ export type Project = {
31
+ id: string;
32
+ organizationId: string;
33
+ /** Préfixe des identifiants de tickets (BRN donne BRN-142), unique dans l'organisation. */
34
+ key: string;
35
+ name: string;
36
+ description: string | null;
37
+ color: string | null;
38
+ dueDate: string | null;
39
+ settings: ProjectSettings;
40
+ /** Dernier numéro de ticket attribué ; incrémenté à chaque création. */
41
+ ticketSeq: number;
42
+ archivedAt: string | null;
43
+ createdBy: ActorRef;
44
+ createdAt: string;
45
+ updatedAt: string;
46
+ };
47
+ export type ProjectMemberRole = 'owner' | 'member';
48
+ export type ProjectMember = {
49
+ projectId: string;
50
+ type: MemberType;
51
+ id: string;
52
+ role: ProjectMemberRole;
53
+ /** Pour un agent, surcharge `ProjectSettings.agentTicketCreation` ; null = réglage du projet. */
54
+ agentTicketCreation: AgentTicketCreation | null;
55
+ createdAt: string;
56
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,192 @@
1
+ import type { ActorRef, AgentTicketCreation, MemberRef, MemberType, TicketStartMode } from './project';
2
+ export type TicketStatus = 'backlog' | 'todo' | 'doing' | 'review' | 'done';
3
+ export type TicketPriority = 'low' | 'medium' | 'high';
4
+ export type Ticket = {
5
+ id: string;
6
+ organizationId: string;
7
+ projectId: string;
8
+ number: number;
9
+ /** Clé du projet suivie du numéro (BRN-142), unique dans l'organisation. */
10
+ key: string;
11
+ title: string;
12
+ description: string | null;
13
+ status: TicketStatus;
14
+ priority: TicketPriority;
15
+ labels: string[];
16
+ dueDate: string | null;
17
+ /** Relecteur optionnel : avec lui, le ticket passe par `review` avant `done`. */
18
+ reviewer: MemberRef | null;
19
+ createdBy: ActorRef;
20
+ /** Conversation dont le ticket est issu, quand un agent l'a proposé. */
21
+ sourceConversationId: string | null;
22
+ /** Ordre dans la colonne, croissant. */
23
+ position: number;
24
+ /** Compteurs entretenus à l'écriture, pour ne pas compter à chaque lecture du board. */
25
+ commentCount: number;
26
+ artifactCount: number;
27
+ doneAt: string | null;
28
+ /** Dernier commentaire, changement de statut ou d'assignation ; sert au tri de la liste. */
29
+ lastActivityAt: string;
30
+ createdAt: string;
31
+ updatedAt: string;
32
+ };
33
+ /**
34
+ * Où en est un assigné : `assigned` (pas commencé), `held` (attend le feu vert), `working`,
35
+ * `waiting` (attend une réponse humaine), `blocked`, `done`.
36
+ */
37
+ export type TicketAssigneeState = 'assigned' | 'held' | 'working' | 'waiting' | 'blocked' | 'done';
38
+ export type TicketAssignee = {
39
+ ticketId: string;
40
+ type: MemberType;
41
+ id: string;
42
+ state: TicketAssigneeState;
43
+ stateNote: string | null;
44
+ updatedAt: string;
45
+ };
46
+ /**
47
+ * `comment` et `report` sont écrits par un humain ou un agent, `question` porte une question
48
+ * d'agent à un humain, `event` est une trace (création, statut, assignation…).
49
+ */
50
+ export type TicketEventKind = 'comment' | 'report' | 'question' | 'event';
51
+ export type TicketEvent = {
52
+ id: string;
53
+ ticketId: string;
54
+ organizationId: string;
55
+ author: ActorRef;
56
+ kind: TicketEventKind;
57
+ body: string | null;
58
+ /**
59
+ * Selon le type : `event` → `{ action, from?, to?, member? }`, `report` → `{ title }`,
60
+ * `question` → `{ humanRequest: TicketQuestion }` ; les mentions dans `{ mentions: MemberRef[] }`.
61
+ */
62
+ data: Record<string, unknown>;
63
+ artifactIds: string[];
64
+ createdAt: string;
65
+ };
66
+ export type TicketArtifact = {
67
+ id: string;
68
+ ticketId: string;
69
+ organizationId: string;
70
+ name: string;
71
+ mimeType: string;
72
+ size: number | null;
73
+ /** `file` : téléversé dans le stockage de fichiers ; `workspace` : fichier du workspace d'un agent. */
74
+ source: 'file' | 'workspace';
75
+ status: 'uploading' | 'ready';
76
+ /**
77
+ * Clé dans le stockage de fichiers. Un fichier du workspace d'un agent y est recopié au moment
78
+ * où il est joint : l'artefact reste tel qu'il était, même si l'agent réécrit le fichier ensuite.
79
+ */
80
+ fileKey: string;
81
+ /** D'où vient un artefact `workspace` : la conversation de l'agent et le chemin du fichier. */
82
+ workspaceRef: {
83
+ conversationId: string | null;
84
+ path: string;
85
+ } | null;
86
+ addedBy: ActorRef;
87
+ createdAt: string;
88
+ };
89
+ export type TicketProposalStatus = 'pending' | 'accepted' | 'rejected' | 'cancelled';
90
+ export type TicketProposalPayload = {
91
+ title: string;
92
+ description: string | null;
93
+ assignees: MemberRef[];
94
+ reviewer: MemberRef | null;
95
+ priority: TicketPriority;
96
+ startMode: TicketStartMode;
97
+ /** Fichiers du workspace de la session à joindre comme artefacts. */
98
+ workspacePaths: string[];
99
+ };
100
+ /** Un ticket qu'un agent propose (ou crée directement) depuis une conversation. */
101
+ export type TicketProposal = {
102
+ id: string;
103
+ organizationId: string;
104
+ conversationId: string;
105
+ messageId: string;
106
+ agentId: string;
107
+ /** Projet proposé par l'agent ; null = l'humain doit en choisir un. */
108
+ projectId: string | null;
109
+ mode: AgentTicketCreation;
110
+ payload: TicketProposalPayload;
111
+ status: TicketProposalStatus;
112
+ ticketId: string | null;
113
+ decidedBy: string | null;
114
+ decidedAt: string | null;
115
+ createdAt: string;
116
+ };
117
+ export type TicketQuestionStatus = 'pending' | 'answered' | 'declined' | 'expired';
118
+ /** Question posée par un agent pendant son travail sur un ticket (Human_ask), dans `data.humanRequest`. */
119
+ export type TicketQuestion = {
120
+ callId: string;
121
+ status: TicketQuestionStatus;
122
+ /** L'humain à qui la question est posée ; lui seul y répond. */
123
+ targetUserId: string;
124
+ options?: string[];
125
+ context?: string | null;
126
+ expiresAt?: string | null;
127
+ answer?: string | null;
128
+ /** Nom ou adresse de qui a tranché, tel qu'il était à ce moment. */
129
+ answeredBy?: string | null;
130
+ answeredAt?: string | null;
131
+ };
132
+ export type TicketPlanStepStatus = 'todo' | 'doing' | 'done';
133
+ export type TicketAgentPlan = {
134
+ steps: {
135
+ title: string;
136
+ status: TicketPlanStepStatus;
137
+ }[];
138
+ updatedAt: string;
139
+ };
140
+ /**
141
+ * La session de travail d'un agent sur un ticket : une conversation de type `task`, reprise à
142
+ * chaque réveil. Une seule par ticket et par agent.
143
+ */
144
+ export type TicketAgentSession = {
145
+ ticketId: string;
146
+ agentId: string;
147
+ organizationId: string;
148
+ projectId: string;
149
+ conversationId: string;
150
+ /** L'humain au nom duquel l'agent travaille : celui qui a lancé le travail. */
151
+ userId: string | null;
152
+ plan: TicketAgentPlan | null;
153
+ /** Date du dernier événement du ticket transmis à l'agent : les suivants sont nouveaux pour lui. */
154
+ eventCursor: string | null;
155
+ /**
156
+ * Réponse de l'agent au dernier réveil : une question y suspend le tour, et la réponse de
157
+ * l'humain le reprend sur ce même message. Son statut dit si l'agent travaille encore.
158
+ */
159
+ lastMessageId: string | null;
160
+ /** Taille du prompt au dernier réveil, pour l'occupation du contexte sans relire la conversation. */
161
+ lastPromptTokens: number | null;
162
+ createdAt: string;
163
+ lastRunAt: string | null;
164
+ };
165
+ export type TicketWakeupReasonKind = 'assigned' | 'go_ahead' | 'reopened' | 'changes_requested' | 'comment' | 'mention';
166
+ export type TicketWakeupReason = {
167
+ kind: TicketWakeupReasonKind;
168
+ eventId?: string | null;
169
+ by: ActorRef;
170
+ at: string;
171
+ };
172
+ export type TicketWakeupStatus = 'pending' | 'running' | 'done' | 'skipped' | 'error';
173
+ /** Un réveil d'agent : les raisons de se remettre au travail, regroupées tant qu'il attend. */
174
+ export type TicketWakeup = {
175
+ id: string;
176
+ organizationId: string;
177
+ projectId: string;
178
+ ticketId: string;
179
+ agentId: string;
180
+ /** L'humain qui a lancé le travail ; il devient l'utilisateur d'une nouvelle session. */
181
+ userId: string | null;
182
+ reasons: TicketWakeupReason[];
183
+ status: TicketWakeupStatus;
184
+ /** Pas avant cette date : le délai de regroupement, puis les reports. */
185
+ queuedAt: string;
186
+ attempts: number;
187
+ claimedAt: string | null;
188
+ claimedBy: string | null;
189
+ error: string | null;
190
+ createdAt: string;
191
+ updatedAt: string;
192
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@breign/db-schemas",
3
- "version": "0.1.75",
3
+ "version": "0.1.77",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -1,5 +1,7 @@
1
1
  import { ChatMessageRoleUio } from '@breign/client';
2
2
  import type { ToolCallApprovalScope } from './pending-tool-call';
3
+ import type { AgentTicketCreation } from './project';
4
+ import type { TicketProposalPayload, TicketProposalStatus } from './ticket';
3
5
  import type { ToolAction, ToolResult } from './tool-result';
4
6
 
5
7
  export type ConversationMessageReaction = 'positive' | 'negative';
@@ -120,6 +122,21 @@ export type ConversationHumanRequest = {
120
122
  expiresAt?: string;
121
123
  };
122
124
 
125
+ /**
126
+ * Un ticket qu'un agent propose depuis cette conversation (outil `Ticket_create`). La carte affichée
127
+ * sous le message se met à jour quand la proposition est acceptée, écartée ou annulée.
128
+ */
129
+ export type ConversationTicketProposal = {
130
+ proposalId: string;
131
+ status: TicketProposalStatus;
132
+ mode: AgentTicketCreation;
133
+ /** Projet proposé par l'agent ; null = l'humain doit en choisir un. */
134
+ projectId: string | null;
135
+ payload: TicketProposalPayload;
136
+ ticketId: string | null;
137
+ ticketKey: string | null;
138
+ };
139
+
123
140
  export type ConversationMessage = {
124
141
  id: string;
125
142
  role: ChatMessageRoleUio;
@@ -136,6 +153,8 @@ export type ConversationMessage = {
136
153
  approvals?: ConversationMessageApproval[];
137
154
  /** Question posée à l'humain par une tâche. Voir ConversationHumanRequest. */
138
155
  humanRequest?: ConversationHumanRequest;
156
+ /** Ticket proposé par l'agent dans ce message. Voir ConversationTicketProposal. */
157
+ ticketProposal?: ConversationTicketProposal;
139
158
  suggestions?: {
140
159
  id: string;
141
160
  text: string;
@@ -176,6 +195,8 @@ export type ConversationContext = {
176
195
  lastActivityAt?: string;
177
196
  /** Tâche ouverte par un agent local via le serveur MCP de Breign. */
178
197
  externalCaller?: ConversationExternalCaller;
198
+ /** Ticket auquel cette conversation est liée (proposition acceptée, session de travail). */
199
+ ticket?: { ticketId: string; projectId: string };
179
200
  };
180
201
 
181
202
  export type ConversationExternalCaller = {
@@ -0,0 +1,29 @@
1
+ import type { ActorRef } from './project';
2
+
3
+ /**
4
+ * `question`, `ticket_proposal`, `review` et `go_ahead` sont des actions (onglet « À traiter ») ;
5
+ * `mention` a son propre onglet.
6
+ */
7
+ export type InboxItemKind = 'question' | 'ticket_proposal' | 'review' | 'go_ahead' | 'mention';
8
+
9
+ /** Ce qui attend un humain : écrit quand l'action naît, résolu quand elle est faite. */
10
+ export type InboxItem = {
11
+ id: string;
12
+ organizationId: string;
13
+ userId: string;
14
+ kind: InboxItemKind;
15
+ requestedBy: ActorRef;
16
+ projectId: string | null;
17
+ ticketId: string | null;
18
+ /**
19
+ * Objet visé : `callId` d'une question, `proposalId` d'une proposition, événement d'une mention,
20
+ * ticket d'une relecture, ticket d'un feu vert (avec l'agent dans `data.agentId`).
21
+ */
22
+ refId: string;
23
+ summary: string;
24
+ data: Record<string, unknown>;
25
+ status: 'pending' | 'done';
26
+ resolution: Record<string, unknown> | null;
27
+ createdAt: string;
28
+ resolvedAt: string | null;
29
+ };
@@ -8,16 +8,19 @@ export * from './engine';
8
8
  export * from './file';
9
9
  export * from './flow';
10
10
  export * from './flow-editor';
11
+ export * from './inbox';
11
12
  export * from './knowledge';
12
13
  export * from './ocr';
13
14
  export * from './organization';
14
15
  export * from './pending-tool-call';
16
+ export * from './project';
15
17
  export * from './permissions';
16
18
  export * from './role';
17
19
  export * from './scheduled-task';
18
20
  export * from './scheduled-task-run';
19
21
  export * from './skill';
20
22
  export * from './speech-to-text';
23
+ export * from './ticket';
21
24
  export * from './tool';
22
25
  export * from './tool-approval';
23
26
  export * from './tool-result';
@@ -0,0 +1,65 @@
1
+ /** Auteur ou destinataire d'une action : un humain, un agent ou le système. */
2
+ export type ActorType = 'user' | 'agent' | 'system';
3
+
4
+ /** Membre d'un projet ou assigné d'un ticket : un humain ou un agent. */
5
+ export type MemberType = 'user' | 'agent';
6
+
7
+ export type ActorRef = {
8
+ type: ActorType;
9
+ /** Identifiant de l'utilisateur ou de l'agent ; null pour le système. */
10
+ id: string | null;
11
+ };
12
+
13
+ export type MemberRef = {
14
+ type: MemberType;
15
+ id: string;
16
+ };
17
+
18
+ /**
19
+ * Ce qui se passe quand un agent crée un ticket : `confirm`, l'agent propose et un humain confirme ;
20
+ * `direct`, le ticket est créé tout de suite et la création reste annulable.
21
+ */
22
+ export type AgentTicketCreation = 'confirm' | 'direct';
23
+
24
+ /** `now` : les agents assignés commencent dès l'assignation ; `hold` : ils attendent un feu vert. */
25
+ export type TicketStartMode = 'now' | 'hold';
26
+
27
+ export type ProjectSettings = {
28
+ agentTicketCreation: AgentTicketCreation;
29
+ defaultStartMode: TicketStartMode;
30
+ /**
31
+ * Les agents assignés se mettent au travail d'eux-mêmes quand on leur confie le ticket ou qu'on
32
+ * leur parle. Absent = activé.
33
+ */
34
+ agentsAutoWork?: boolean;
35
+ };
36
+
37
+ export type Project = {
38
+ id: string;
39
+ organizationId: string;
40
+ /** Préfixe des identifiants de tickets (BRN donne BRN-142), unique dans l'organisation. */
41
+ key: string;
42
+ name: string;
43
+ description: string | null;
44
+ color: string | null;
45
+ dueDate: string | null;
46
+ settings: ProjectSettings;
47
+ /** Dernier numéro de ticket attribué ; incrémenté à chaque création. */
48
+ ticketSeq: number;
49
+ archivedAt: string | null;
50
+ createdBy: ActorRef;
51
+ createdAt: string;
52
+ updatedAt: string;
53
+ };
54
+
55
+ export type ProjectMemberRole = 'owner' | 'member';
56
+
57
+ export type ProjectMember = {
58
+ projectId: string;
59
+ type: MemberType;
60
+ id: string;
61
+ role: ProjectMemberRole;
62
+ /** Pour un agent, surcharge `ProjectSettings.agentTicketCreation` ; null = réglage du projet. */
63
+ agentTicketCreation: AgentTicketCreation | null;
64
+ createdAt: string;
65
+ };
@@ -0,0 +1,218 @@
1
+ import type {
2
+ ActorRef,
3
+ AgentTicketCreation,
4
+ MemberRef,
5
+ MemberType,
6
+ TicketStartMode,
7
+ } from './project';
8
+
9
+ export type TicketStatus = 'backlog' | 'todo' | 'doing' | 'review' | 'done';
10
+
11
+ export type TicketPriority = 'low' | 'medium' | 'high';
12
+
13
+ export type Ticket = {
14
+ id: string;
15
+ organizationId: string;
16
+ projectId: string;
17
+ number: number;
18
+ /** Clé du projet suivie du numéro (BRN-142), unique dans l'organisation. */
19
+ key: string;
20
+ title: string;
21
+ description: string | null;
22
+ status: TicketStatus;
23
+ priority: TicketPriority;
24
+ labels: string[];
25
+ dueDate: string | null;
26
+ /** Relecteur optionnel : avec lui, le ticket passe par `review` avant `done`. */
27
+ reviewer: MemberRef | null;
28
+ createdBy: ActorRef;
29
+ /** Conversation dont le ticket est issu, quand un agent l'a proposé. */
30
+ sourceConversationId: string | null;
31
+ /** Ordre dans la colonne, croissant. */
32
+ position: number;
33
+ /** Compteurs entretenus à l'écriture, pour ne pas compter à chaque lecture du board. */
34
+ commentCount: number;
35
+ artifactCount: number;
36
+ doneAt: string | null;
37
+ /** Dernier commentaire, changement de statut ou d'assignation ; sert au tri de la liste. */
38
+ lastActivityAt: string;
39
+ createdAt: string;
40
+ updatedAt: string;
41
+ };
42
+
43
+ /**
44
+ * Où en est un assigné : `assigned` (pas commencé), `held` (attend le feu vert), `working`,
45
+ * `waiting` (attend une réponse humaine), `blocked`, `done`.
46
+ */
47
+ export type TicketAssigneeState = 'assigned' | 'held' | 'working' | 'waiting' | 'blocked' | 'done';
48
+
49
+ export type TicketAssignee = {
50
+ ticketId: string;
51
+ type: MemberType;
52
+ id: string;
53
+ state: TicketAssigneeState;
54
+ stateNote: string | null;
55
+ updatedAt: string;
56
+ };
57
+
58
+ /**
59
+ * `comment` et `report` sont écrits par un humain ou un agent, `question` porte une question
60
+ * d'agent à un humain, `event` est une trace (création, statut, assignation…).
61
+ */
62
+ export type TicketEventKind = 'comment' | 'report' | 'question' | 'event';
63
+
64
+ export type TicketEvent = {
65
+ id: string;
66
+ ticketId: string;
67
+ organizationId: string;
68
+ author: ActorRef;
69
+ kind: TicketEventKind;
70
+ body: string | null;
71
+ /**
72
+ * Selon le type : `event` → `{ action, from?, to?, member? }`, `report` → `{ title }`,
73
+ * `question` → `{ humanRequest: TicketQuestion }` ; les mentions dans `{ mentions: MemberRef[] }`.
74
+ */
75
+ data: Record<string, unknown>;
76
+ artifactIds: string[];
77
+ createdAt: string;
78
+ };
79
+
80
+ export type TicketArtifact = {
81
+ id: string;
82
+ ticketId: string;
83
+ organizationId: string;
84
+ name: string;
85
+ mimeType: string;
86
+ size: number | null;
87
+ /** `file` : téléversé dans le stockage de fichiers ; `workspace` : fichier du workspace d'un agent. */
88
+ source: 'file' | 'workspace';
89
+ status: 'uploading' | 'ready';
90
+ /**
91
+ * Clé dans le stockage de fichiers. Un fichier du workspace d'un agent y est recopié au moment
92
+ * où il est joint : l'artefact reste tel qu'il était, même si l'agent réécrit le fichier ensuite.
93
+ */
94
+ fileKey: string;
95
+ /** D'où vient un artefact `workspace` : la conversation de l'agent et le chemin du fichier. */
96
+ workspaceRef: { conversationId: string | null; path: string } | null;
97
+ addedBy: ActorRef;
98
+ createdAt: string;
99
+ };
100
+
101
+ export type TicketProposalStatus = 'pending' | 'accepted' | 'rejected' | 'cancelled';
102
+
103
+ export type TicketProposalPayload = {
104
+ title: string;
105
+ description: string | null;
106
+ assignees: MemberRef[];
107
+ reviewer: MemberRef | null;
108
+ priority: TicketPriority;
109
+ startMode: TicketStartMode;
110
+ /** Fichiers du workspace de la session à joindre comme artefacts. */
111
+ workspacePaths: string[];
112
+ };
113
+
114
+ /** Un ticket qu'un agent propose (ou crée directement) depuis une conversation. */
115
+ export type TicketProposal = {
116
+ id: string;
117
+ organizationId: string;
118
+ conversationId: string;
119
+ messageId: string;
120
+ agentId: string;
121
+ /** Projet proposé par l'agent ; null = l'humain doit en choisir un. */
122
+ projectId: string | null;
123
+ mode: AgentTicketCreation;
124
+ payload: TicketProposalPayload;
125
+ status: TicketProposalStatus;
126
+ ticketId: string | null;
127
+ decidedBy: string | null;
128
+ decidedAt: string | null;
129
+ createdAt: string;
130
+ };
131
+
132
+ export type TicketQuestionStatus = 'pending' | 'answered' | 'declined' | 'expired';
133
+
134
+ /** Question posée par un agent pendant son travail sur un ticket (Human_ask), dans `data.humanRequest`. */
135
+ export type TicketQuestion = {
136
+ callId: string;
137
+ status: TicketQuestionStatus;
138
+ /** L'humain à qui la question est posée ; lui seul y répond. */
139
+ targetUserId: string;
140
+ options?: string[];
141
+ context?: string | null;
142
+ expiresAt?: string | null;
143
+ answer?: string | null;
144
+ /** Nom ou adresse de qui a tranché, tel qu'il était à ce moment. */
145
+ answeredBy?: string | null;
146
+ answeredAt?: string | null;
147
+ };
148
+
149
+ export type TicketPlanStepStatus = 'todo' | 'doing' | 'done';
150
+
151
+ export type TicketAgentPlan = {
152
+ steps: { title: string; status: TicketPlanStepStatus }[];
153
+ updatedAt: string;
154
+ };
155
+
156
+ /**
157
+ * La session de travail d'un agent sur un ticket : une conversation de type `task`, reprise à
158
+ * chaque réveil. Une seule par ticket et par agent.
159
+ */
160
+ export type TicketAgentSession = {
161
+ ticketId: string;
162
+ agentId: string;
163
+ organizationId: string;
164
+ projectId: string;
165
+ conversationId: string;
166
+ /** L'humain au nom duquel l'agent travaille : celui qui a lancé le travail. */
167
+ userId: string | null;
168
+ plan: TicketAgentPlan | null;
169
+ /** Date du dernier événement du ticket transmis à l'agent : les suivants sont nouveaux pour lui. */
170
+ eventCursor: string | null;
171
+ /**
172
+ * Réponse de l'agent au dernier réveil : une question y suspend le tour, et la réponse de
173
+ * l'humain le reprend sur ce même message. Son statut dit si l'agent travaille encore.
174
+ */
175
+ lastMessageId: string | null;
176
+ /** Taille du prompt au dernier réveil, pour l'occupation du contexte sans relire la conversation. */
177
+ lastPromptTokens: number | null;
178
+ createdAt: string;
179
+ lastRunAt: string | null;
180
+ };
181
+
182
+ export type TicketWakeupReasonKind =
183
+ | 'assigned'
184
+ | 'go_ahead'
185
+ | 'reopened'
186
+ | 'changes_requested'
187
+ | 'comment'
188
+ | 'mention';
189
+
190
+ export type TicketWakeupReason = {
191
+ kind: TicketWakeupReasonKind;
192
+ eventId?: string | null;
193
+ by: ActorRef;
194
+ at: string;
195
+ };
196
+
197
+ export type TicketWakeupStatus = 'pending' | 'running' | 'done' | 'skipped' | 'error';
198
+
199
+ /** Un réveil d'agent : les raisons de se remettre au travail, regroupées tant qu'il attend. */
200
+ export type TicketWakeup = {
201
+ id: string;
202
+ organizationId: string;
203
+ projectId: string;
204
+ ticketId: string;
205
+ agentId: string;
206
+ /** L'humain qui a lancé le travail ; il devient l'utilisateur d'une nouvelle session. */
207
+ userId: string | null;
208
+ reasons: TicketWakeupReason[];
209
+ status: TicketWakeupStatus;
210
+ /** Pas avant cette date : le délai de regroupement, puis les reports. */
211
+ queuedAt: string;
212
+ attempts: number;
213
+ claimedAt: string | null;
214
+ claimedBy: string | null;
215
+ error: string | null;
216
+ createdAt: string;
217
+ updatedAt: string;
218
+ };