@ikatec/digisac-api-sdk 4.4.1 → 4.5.1

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.
Files changed (55) hide show
  1. package/dist/apis/cards/CardsApi.cjs +70 -0
  2. package/dist/apis/cards/CardsApi.cjs.map +1 -1
  3. package/dist/apis/cards/CardsApi.d.ts +53 -1
  4. package/dist/apis/cards/CardsApi.d.ts.map +1 -1
  5. package/dist/apis/cards/CardsApi.mjs +70 -0
  6. package/dist/apis/cards/CardsApi.mjs.map +1 -1
  7. package/dist/apis/cards/types.d.ts +84 -0
  8. package/dist/apis/cards/types.d.ts.map +1 -1
  9. package/dist/apis/kanbanBoards/types.d.ts +33 -4
  10. package/dist/apis/kanbanBoards/types.d.ts.map +1 -1
  11. package/dist/apis/kanbanCards/KanbanCardsApi.cjs +8 -0
  12. package/dist/apis/kanbanCards/KanbanCardsApi.cjs.map +1 -1
  13. package/dist/apis/kanbanCards/KanbanCardsApi.d.ts +7 -1
  14. package/dist/apis/kanbanCards/KanbanCardsApi.d.ts.map +1 -1
  15. package/dist/apis/kanbanCards/KanbanCardsApi.mjs +8 -0
  16. package/dist/apis/kanbanCards/KanbanCardsApi.mjs.map +1 -1
  17. package/dist/apis/kanbanCards/types.d.ts +17 -5
  18. package/dist/apis/kanbanCards/types.d.ts.map +1 -1
  19. package/dist/apis/kanbanColumns/KanbanColumnsApi.cjs +9 -0
  20. package/dist/apis/kanbanColumns/KanbanColumnsApi.cjs.map +1 -1
  21. package/dist/apis/kanbanColumns/KanbanColumnsApi.d.ts +8 -1
  22. package/dist/apis/kanbanColumns/KanbanColumnsApi.d.ts.map +1 -1
  23. package/dist/apis/kanbanColumns/KanbanColumnsApi.mjs +9 -0
  24. package/dist/apis/kanbanColumns/KanbanColumnsApi.mjs.map +1 -1
  25. package/dist/apis/kanbanColumns/types.d.ts +14 -3
  26. package/dist/apis/kanbanColumns/types.d.ts.map +1 -1
  27. package/dist/apis/permissions/types.d.ts +1 -1
  28. package/dist/apis/permissions/types.d.ts.map +1 -1
  29. package/dist/apis/pipeline/PipelineApi.cjs +133 -0
  30. package/dist/apis/pipeline/PipelineApi.cjs.map +1 -1
  31. package/dist/apis/pipeline/PipelineApi.d.ts +102 -1
  32. package/dist/apis/pipeline/PipelineApi.d.ts.map +1 -1
  33. package/dist/apis/pipeline/PipelineApi.mjs +133 -0
  34. package/dist/apis/pipeline/PipelineApi.mjs.map +1 -1
  35. package/dist/apis/pipeline/types.d.ts +164 -0
  36. package/dist/apis/pipeline/types.d.ts.map +1 -1
  37. package/dist/apis/tickets/types.d.ts +37 -1
  38. package/dist/apis/tickets/types.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/apis/cards/CardsApi.test.ts +128 -0
  41. package/src/apis/cards/CardsApi.ts +124 -1
  42. package/src/apis/cards/types.ts +81 -0
  43. package/src/apis/kanbanBoards/types.ts +36 -4
  44. package/src/apis/kanbanCards/KanbanCardsApi.test.ts +46 -0
  45. package/src/apis/kanbanCards/KanbanCardsApi.ts +23 -1
  46. package/src/apis/kanbanCards/types.ts +18 -5
  47. package/src/apis/kanbanColumns/KanbanColumnsApi.test.ts +46 -0
  48. package/src/apis/kanbanColumns/KanbanColumnsApi.ts +24 -1
  49. package/src/apis/kanbanColumns/types.ts +15 -3
  50. package/src/apis/payloads.test-d.ts +53 -1
  51. package/src/apis/permissions/types.ts +10 -4
  52. package/src/apis/pipeline/PipelineApi.test.ts +193 -0
  53. package/src/apis/pipeline/PipelineApi.ts +274 -1
  54. package/src/apis/pipeline/types.ts +162 -0
  55. package/src/apis/tickets/types.ts +40 -1
@@ -1,6 +1,28 @@
1
1
  import type { ApiClient } from '../../core/ApiClient'
2
2
  import { BaseCrudApi } from '../../core/BaseCrudApi'
3
- import type { Pipeline, CreatePipelinePayload, UpdatePipelinePayload } from './types'
3
+ import type {
4
+ CreatePipelineAutomationPayload,
5
+ CreatePipelinePayload,
6
+ CreatePipelineStagePayload,
7
+ DeletePipelineStagePayload,
8
+ DeletePipelineStageResult,
9
+ DeletePipelineStatusPayload,
10
+ ExportPipelinePayload,
11
+ Pipeline,
12
+ PipelineAutomation,
13
+ PipelineRecord,
14
+ PipelineStage,
15
+ PipelineStageRefusal,
16
+ PipelineStageStatusWithCount,
17
+ PipelineStageTotals,
18
+ PipelineStageTotalsFilters,
19
+ PipelineStatusRef,
20
+ PipelinesWithTotals,
21
+ PipelinesWithTotalsQuery,
22
+ UpdatePipelineAutomationPayload,
23
+ UpdatePipelinePayload,
24
+ UpdatePipelineStagePayload,
25
+ } from './types'
4
26
 
5
27
  export class PipelineApi extends BaseCrudApi<
6
28
  Pipeline,
@@ -10,4 +32,255 @@ export class PipelineApi extends BaseCrudApi<
10
32
  constructor(client: ApiClient) {
11
33
  super(client, '/pipelines')
12
34
  }
35
+
36
+ /**
37
+ * Adds a stage (with its statuses and reasons) to a pipeline. Resolves to the stage as stored,
38
+ * without the statuses/reasons, or to a refusal code with 200: `'STAGES_LIMIT'` (the pipeline
39
+ * already has 10 stages) or `'STAGE_ALREADY_EXIST'` (same name).
40
+ * @permissions pipelines.update
41
+ */
42
+ createStage(
43
+ body: CreatePipelineStagePayload,
44
+ headers?: Record<string, string>,
45
+ ): Promise<PipelineStage | PipelineStageRefusal> {
46
+ return this.client.post<PipelineStage | PipelineStageRefusal, CreatePipelineStagePayload>(
47
+ `${this.basePath}/stage`,
48
+ body,
49
+ headers,
50
+ )
51
+ }
52
+
53
+ /**
54
+ * Updates a stage. `statuses` and `reasons` replace the whole set: items with `id` are kept
55
+ * and updated, items without it are created and the missing ones are deleted — omitting the
56
+ * lists deletes every status and reason of the stage. Resolves to the stage as stored, or to
57
+ * `'STAGE_ALREADY_EXIST'`.
58
+ * @permissions pipelines.update
59
+ */
60
+ updateStage(
61
+ id: string,
62
+ body: UpdatePipelineStagePayload,
63
+ headers?: Record<string, string>,
64
+ ): Promise<PipelineStage | 'STAGE_ALREADY_EXIST'> {
65
+ return this.client.put<PipelineStage | 'STAGE_ALREADY_EXIST', UpdatePipelineStagePayload>(
66
+ `${this.basePath}/stage/${id}`,
67
+ body,
68
+ headers,
69
+ )
70
+ }
71
+
72
+ /**
73
+ * Deletes a stage and moves its cards (see {@link DeletePipelineStagePayload}). Resolves to
74
+ * `'MESSAGE_STAGE_DELETED'`, or to `'PIPELINES_MIN_STAGES'` (nothing deleted) when the pipeline
75
+ * has only 2 stages. The backend also serves this under `PUT /pipelines/delete-stage/{id}`.
76
+ * @permissions pipelines.update
77
+ */
78
+ deleteStage(
79
+ id: string,
80
+ body: DeletePipelineStagePayload = {},
81
+ headers?: Record<string, string>,
82
+ ): Promise<DeletePipelineStageResult> {
83
+ return this.client.request<DeletePipelineStageResult, DeletePipelineStagePayload>(
84
+ 'DELETE',
85
+ `${this.basePath}/stage/${id}`,
86
+ body,
87
+ headers,
88
+ )
89
+ }
90
+
91
+ /**
92
+ * Lists the statuses of every stage of a pipeline (`[]` for an unknown pipeline).
93
+ * @permissions pipelines.view
94
+ */
95
+ getStatuses(pipelineId: string, headers?: Record<string, string>): Promise<PipelineStatusRef[]> {
96
+ return this.client.get<PipelineStatusRef[]>(`${this.basePath}/statuses/${pipelineId}`, headers)
97
+ }
98
+
99
+ /**
100
+ * Gets a stage status with the number of cards using it. An unknown id resolves to
101
+ * `{ cardsCount: 0 }` with 200, not to an error.
102
+ * @permissions pipelines.view
103
+ */
104
+ getStatus(
105
+ id: string,
106
+ headers?: Record<string, string>,
107
+ ): Promise<PipelineStageStatusWithCount | { cardsCount: 0 }> {
108
+ return this.client.get<PipelineStageStatusWithCount | { cardsCount: 0 }>(
109
+ `${this.basePath}/status/${id}`,
110
+ headers,
111
+ )
112
+ }
113
+
114
+ /**
115
+ * Deletes a stage status, keeping its cards without status or moving them to another one.
116
+ * Resolves to `'MESSAGE_STATUS_DELETED'`.
117
+ * @permissions pipelines.view
118
+ */
119
+ deleteStatus(
120
+ id: string,
121
+ body: DeletePipelineStatusPayload,
122
+ headers?: Record<string, string>,
123
+ ): Promise<'MESSAGE_STATUS_DELETED'> {
124
+ return this.client.post<'MESSAGE_STATUS_DELETED', DeletePipelineStatusPayload>(
125
+ `${this.basePath}/delete-status/${id}`,
126
+ body,
127
+ headers,
128
+ )
129
+ }
130
+
131
+ /**
132
+ * Renames a stage status — same route as {@link deleteStatus}, without an `action`.
133
+ * Resolves to `'MESSAGE_STATUS_RENAMED'`; an empty name fails with 500.
134
+ * @permissions pipelines.view
135
+ */
136
+ renameStatus(
137
+ id: string,
138
+ newStatusName: string,
139
+ headers?: Record<string, string>,
140
+ ): Promise<'MESSAGE_STATUS_RENAMED'> {
141
+ return this.client.post<'MESSAGE_STATUS_RENAMED', { newStatusName: string }>(
142
+ `${this.basePath}/delete-status/${id}`,
143
+ { newStatusName },
144
+ headers,
145
+ )
146
+ }
147
+
148
+ /**
149
+ * Creates an automation of a pipeline. Resolves to the automation as stored.
150
+ * @permissions pipelines.update
151
+ */
152
+ createAutomation(
153
+ body: CreatePipelineAutomationPayload,
154
+ headers?: Record<string, string>,
155
+ ): Promise<PipelineAutomation> {
156
+ return this.client.post<PipelineAutomation, CreatePipelineAutomationPayload>(
157
+ `${this.basePath}/automations`,
158
+ body,
159
+ headers,
160
+ )
161
+ }
162
+
163
+ /**
164
+ * Updates an automation. Resolves to the automation as stored.
165
+ * @permissions pipelines.update
166
+ */
167
+ updateAutomation(
168
+ id: string,
169
+ body: UpdatePipelineAutomationPayload,
170
+ headers?: Record<string, string>,
171
+ ): Promise<PipelineAutomation> {
172
+ return this.client.put<PipelineAutomation, UpdatePipelineAutomationPayload>(
173
+ `${this.basePath}/automations/${id}`,
174
+ body,
175
+ headers,
176
+ )
177
+ }
178
+
179
+ /**
180
+ * Deletes an automation. Resolves with no content; an unknown id fails with 500.
181
+ * @permissions pipelines.update
182
+ */
183
+ deleteAutomation(id: string, headers?: Record<string, string>): Promise<void> {
184
+ return this.client.delete<void>(`${this.basePath}/automations/${id}`, headers)
185
+ }
186
+
187
+ /**
188
+ * Gets the automation of a pipeline — a single object (the first one found), or `[]` when
189
+ * the pipeline has none.
190
+ * @permissions pipelines.view
191
+ */
192
+ getAutomation(
193
+ pipelineId: string,
194
+ headers?: Record<string, string>,
195
+ ): Promise<PipelineAutomation | []> {
196
+ return this.client.get<PipelineAutomation | []>(
197
+ `${this.basePath}/automations/${pipelineId}`,
198
+ headers,
199
+ )
200
+ }
201
+
202
+ /**
203
+ * Copies a pipeline as `"<name> (copy)"`, with its stages, statuses, reasons and automations
204
+ * (not its departments). Resolves to the new pipeline as stored, without the stages.
205
+ * @permissions pipelines.view
206
+ */
207
+ duplicate(pipelineId: string, headers?: Record<string, string>): Promise<PipelineRecord> {
208
+ return this.client.post<PipelineRecord>(
209
+ `${this.basePath}/duplicate/${pipelineId}`,
210
+ undefined,
211
+ headers,
212
+ )
213
+ }
214
+
215
+ /**
216
+ * Archives a pipeline. Resolves to the pipeline with its stages and their card totals.
217
+ * @permissions pipelines.update
218
+ */
219
+ archive(id: string, headers?: Record<string, string>): Promise<Pipeline> {
220
+ return this.client.post<Pipeline, { archive: boolean }>(
221
+ `${this.basePath}/${id}/archive`,
222
+ { archive: true },
223
+ headers,
224
+ )
225
+ }
226
+
227
+ /**
228
+ * Restores an archived pipeline. Resolves to the pipeline with its stages and their totals.
229
+ * @permissions pipelines.update
230
+ */
231
+ unarchive(id: string, headers?: Record<string, string>): Promise<Pipeline> {
232
+ return this.client.post<Pipeline, { archive: boolean }>(
233
+ `${this.basePath}/${id}/archive`,
234
+ { archive: false },
235
+ headers,
236
+ )
237
+ }
238
+
239
+ /**
240
+ * Exports the cards of a pipeline as CSV text (`;` as the delimiter): a summary block
241
+ * followed by one row per card.
242
+ * @permissions pipelines.view
243
+ */
244
+ exportCsv(
245
+ id: string,
246
+ body: ExportPipelinePayload = {},
247
+ headers?: Record<string, string>,
248
+ ): Promise<string> {
249
+ return this.client.post<string, ExportPipelinePayload>(
250
+ `${this.basePath}/${id}/export`,
251
+ body,
252
+ headers,
253
+ )
254
+ }
255
+
256
+ /**
257
+ * Lists the pipelines of the account with their stages and card totals. Not paginated.
258
+ * @permissions pipelines.view
259
+ */
260
+ getManyWithTotals(
261
+ query?: PipelinesWithTotalsQuery,
262
+ headers?: Record<string, string>,
263
+ ): Promise<PipelinesWithTotals> {
264
+ return this.client.get<PipelinesWithTotals>(
265
+ `${this.basePath}/withTotals${this.toQueryString(query)}`,
266
+ headers,
267
+ )
268
+ }
269
+
270
+ /**
271
+ * Gets the card totals of a stage, optionally filtered like the board. Resolves to `null`
272
+ * for an unknown stage.
273
+ * @permissions pipelines.update OR pipelines.opportunity.update
274
+ */
275
+ getStageTotals(
276
+ stageId: string,
277
+ filters: PipelineStageTotalsFilters = {},
278
+ headers?: Record<string, string>,
279
+ ): Promise<PipelineStageTotals | null> {
280
+ return this.client.post<PipelineStageTotals | null, PipelineStageTotalsFilters>(
281
+ `${this.basePath}/stage-totals/${stageId}`,
282
+ filters,
283
+ headers,
284
+ )
285
+ }
13
286
  }
@@ -1,4 +1,5 @@
1
1
  import type { Department } from '../departments/types'
2
+ import type { WhereClause } from '../../core/types'
2
3
 
3
4
  export type PipelineStageStatus = {
4
5
  id: string
@@ -95,3 +96,164 @@ export type UpdatePipelinePayload = {
95
96
  goBack?: boolean
96
97
  permissionToViewCard?: boolean | null
97
98
  }
99
+
100
+ /** Codes the stage routes answer (as a JSON string, with 200) instead of the stage. */
101
+ export type PipelineStageRefusal = 'STAGES_LIMIT' | 'STAGE_ALREADY_EXIST'
102
+
103
+ export type PipelineStageStatusInput = {
104
+ /** Send the `id` of an existing status to keep it on update; omit it to create one. */
105
+ id?: string
106
+ name: string
107
+ position: number
108
+ }
109
+
110
+ export type PipelineStageReasonInput = {
111
+ /** Send the `id` of an existing reason to keep it on update; omit it to create one. */
112
+ id?: string
113
+ name: string
114
+ position: number
115
+ isWon?: boolean
116
+ }
117
+
118
+ export type CreatePipelineStagePayload = {
119
+ /** Up to 255 characters; must not repeat the name of another stage of the pipeline. */
120
+ name: string
121
+ pipelineId: string
122
+ /** Must be truthy — the backend `required` rule refuses `0`. */
123
+ position: number
124
+ /** Up to 10. */
125
+ statuses?: PipelineStageStatusInput[]
126
+ /** Up to 20. */
127
+ reasons?: PipelineStageReasonInput[]
128
+ }
129
+
130
+ export type UpdatePipelineStagePayload = CreatePipelineStagePayload & {
131
+ /**
132
+ * The stage id. Send it: the duplicate-name check compares against the `id` of the body,
133
+ * so without it keeping the current name answers `'STAGE_ALREADY_EXIST'`.
134
+ */
135
+ id?: string
136
+ }
137
+
138
+ /**
139
+ * Where the cards of a deleted stage go:
140
+ * - `typeAction: 'move'` moves them to `idNewStage` (a stage of the same pipeline), clearing
141
+ * status, reason and result;
142
+ * - without `typeAction`, they are archived and moved to the first stage of the pipeline.
143
+ */
144
+ export type DeletePipelineStagePayload = {
145
+ typeAction?: 'move'
146
+ idNewStage?: string
147
+ /**
148
+ * Author of the card movements written by `'move'` — the backend reads it from the body, not
149
+ * from the token (the UI sends the logged user). Without it, moving a stage that has cards
150
+ * fails with 500 (`CardMovement.userId cannot be null`) after the cards were already moved,
151
+ * and the stage is kept.
152
+ */
153
+ user?: { id: string }
154
+ }
155
+
156
+ /** Answer of the stage deletion; `'PIPELINES_MIN_STAGES'` = refused, the pipeline keeps 2 stages. */
157
+ export type DeletePipelineStageResult = 'MESSAGE_STAGE_DELETED' | 'PIPELINES_MIN_STAGES'
158
+
159
+ export type PipelineStatusRef = { id: string; name: string }
160
+
161
+ /** `GET /pipelines/status/{id}`: the status plus how many cards use it. */
162
+ export type PipelineStageStatusWithCount = PipelineStageStatus & { cardsCount: number }
163
+
164
+ /**
165
+ * What happens to the cards of a deleted status: `'keep-without-status'` clears their status,
166
+ * `'move-to-another'` sets `newStatusId` (not validated by the backend).
167
+ */
168
+ export type DeletePipelineStatusPayload =
169
+ | { action: 'keep-without-status' }
170
+ | { action: 'move-to-another'; newStatusId: string }
171
+
172
+ export type PipelineAutomationType = 'notification'
173
+
174
+ export type PipelineAutomationConfig = {
175
+ notify?: 'high' | 'medium' | 'medium-high'
176
+ frequency?: 'daily' | 'weekly' | 'biweekly' | 'monthly'
177
+ day?: string
178
+ from?: { high?: string; medium?: string }
179
+ recipient?: 'admin' | 'owner' | 'both'
180
+ }
181
+
182
+ export type PipelineAutomation = {
183
+ id: string
184
+ pipelineId: string
185
+ type: PipelineAutomationType
186
+ isArchived: boolean | null
187
+ archivedAt: string | null
188
+ config: PipelineAutomationConfig
189
+ createdAt: string
190
+ updatedAt: string
191
+ }
192
+
193
+ export type CreatePipelineAutomationPayload = {
194
+ pipelineId: string
195
+ /** The backend does not validate it (any string is stored); `'notification'` is the only one used. */
196
+ type: PipelineAutomationType
197
+ config?: PipelineAutomationConfig
198
+ isArchived?: boolean
199
+ }
200
+
201
+ /** The backend validator requires `pipelineId` and `type` on update too. */
202
+ export type UpdatePipelineAutomationPayload = CreatePipelineAutomationPayload
203
+
204
+ /** Card date filters of the CSV export; the UI sends `'YYYY-MM-DD HH:mm:ss'`. */
205
+ export type ExportPipelinePayload = {
206
+ /** Without both `createdAt*`, the range defaults to now (empty export). */
207
+ createdAtInit?: string
208
+ createdAtFinal?: string
209
+ /** With both `wonAt*`, only won cards are exported. */
210
+ wonAtInit?: string
211
+ wonAtFinal?: string
212
+ }
213
+
214
+ export type PipelinesWithTotalsQuery = {
215
+ /** `accountId` is always injected by the backend. `$and[].createdAt` filters the cards. */
216
+ where?: WhereClause<PipelineRecord>
217
+ order?: [string, 'ASC' | 'DESC'][]
218
+ limit?: number
219
+ /** `true` lists only the pipelines that are not archived. */
220
+ archive?: boolean
221
+ }
222
+
223
+ export type PipelineTotals = {
224
+ id: string
225
+ name: string
226
+ total: number | null
227
+ totalSuccess: number | null
228
+ totalFailed: number | null
229
+ /** A bigint, sent as a string. */
230
+ totalCards: string
231
+ }
232
+
233
+ /**
234
+ * Pipelines without stages are left out; there is no pagination. With a `createdAt` filter, only
235
+ * the stages that have matching cards are listed, but `totals` still has every stage.
236
+ */
237
+ export type PipelinesWithTotals = {
238
+ data: (PipelineRecord & { stages: PipelineStage[]; totals: PipelineTotals[] })[]
239
+ }
240
+
241
+ /** Card filters of the stage totals (same as the board filters of the UI). */
242
+ export type PipelineStageTotalsFilters = {
243
+ status?: { value: string }
244
+ service?: { id: string }
245
+ nameTitle?: string
246
+ /** `DD/MM/YYYY`. */
247
+ createdFrom?: string
248
+ createdUntil?: string
249
+ owner?: { id: string; value?: string }
250
+ wonFrom?: string
251
+ wonUntil?: string
252
+ }
253
+
254
+ export type PipelineStageTotals = PipelineStage & {
255
+ totalCards: number
256
+ totalCardsValue: number
257
+ totalWonCardsValue: number
258
+ totalLostCardsValue: number
259
+ }
@@ -1,5 +1,6 @@
1
1
  import type { Contact } from '../contacts/types'
2
2
  import type { Department } from '../departments/types'
3
+ import type { Message } from '../messages/types'
3
4
  import type { Service } from '../services/types'
4
5
  import type { User } from '../users/types'
5
6
 
@@ -23,6 +24,43 @@ export type TicketMetrics = {
23
24
  isActiveTicket?: boolean
24
25
  }
25
26
 
27
+ export type TicketTransferAction = 'opened' | 'transferred' | 'closed'
28
+
29
+ /**
30
+ * A step of the history of a ticket (opening, transfer, closing), as the `ticketTransfers` include of
31
+ * `GET /tickets/{id}` answers it. `byUserId` is who performed the step (null when there is no user, e.g. a bot).
32
+ *
33
+ * Inside `ticketTransfers`, the route whitelist only accepts `byUser`, `fromUser`, `toUser`, `fromDepartment` and
34
+ * `toDepartment`: `transferredMessage`, `firstMessage` and `lastMessage` are dropped in silence and come as `null`.
35
+ */
36
+ export type TicketTransfer = {
37
+ id: string
38
+ action: TicketTransferAction | null
39
+ comments: string | null
40
+ fromDistribution: boolean
41
+ accountId: string
42
+ ticketId: string
43
+ byUserId: string | null
44
+ fromUserId: string | null
45
+ toUserId: string | null
46
+ fromDepartmentId: string | null
47
+ toDepartmentId: string | null
48
+ transferredMessageId: string | null
49
+ firstMessageId: string | null
50
+ lastMessageId: string | null
51
+ createdAt: string
52
+ updatedAt: string
53
+ // relationships
54
+ byUser?: User | null
55
+ fromUser?: User | null
56
+ toUser?: User | null
57
+ fromDepartment?: Department | null
58
+ toDepartment?: Department | null
59
+ transferredMessage?: Message | null
60
+ firstMessage?: Message | null
61
+ lastMessage?: Message | null
62
+ }
63
+
26
64
  export type Ticket = {
27
65
  id: string
28
66
  isOpen: boolean
@@ -49,9 +87,10 @@ export type Ticket = {
49
87
  department?: Department
50
88
  user?: User | null
51
89
  service?: Service | null
90
+ ticketTransfers?: TicketTransfer[]
52
91
  }
53
92
 
54
- export type TicketRelationships = 'contact' | 'department' | 'user' | 'service'
93
+ export type TicketRelationships = 'contact' | 'department' | 'user' | 'service' | 'ticketTransfers'
55
94
 
56
95
  export type CreateTicketPayload = {
57
96
  contactId: string