-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathwork_items.py
More file actions
592 lines (462 loc) · 17 KB
/
work_items.py
File metadata and controls
592 lines (462 loc) · 17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
from typing import TYPE_CHECKING, Any
from pydantic import BaseModel, ConfigDict, Field
from .enums import AccessEnum, PriorityEnum, WorkItemRelationTypeEnum
from .labels import Label
from .pagination import PaginatedResponse
from .states import StateLite
from .users import UserLite
if TYPE_CHECKING:
from .modules import ModuleLite
class WorkItem(BaseModel):
"""Work item model."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str | None = None
type_id: str | None = None
created_at: str | None = None
updated_at: str | None = None
deleted_at: str | None = None
point: int | None = None
name: str
description_html: str | None = None
description_stripped: str | None = None
description_binary: str | None = None
priority: PriorityEnum | None = None
start_date: str | None = None
target_date: str | None = None
sequence_id: int | None = None
sort_order: float | None = None
completed_at: str | None = None
archived_at: str | None = None
is_draft: bool | None = None
external_source: str | None = None
external_id: str | None = None
created_by: str | None = None
updated_by: str | None = None
project: str | None = None
workspace: str | None = None
parent: str | None = None
state: str | StateLite | None = None
estimate_point: str | None = None
type: str | None = None
class WorkItemDetail(BaseModel):
"""Detailed work item with expanded relationships."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str | None = None
assignees: list[UserLite]
labels: list[Label]
type_id: str | None = None
created_at: str | None = None
updated_at: str | None = None
deleted_at: str | None = None
point: int | None = None
name: str
description_html: str | None = None
description_stripped: str | None = None
description_binary: str | None = None
priority: PriorityEnum | None = None
start_date: str | None = None
target_date: str | None = None
sequence_id: int | None = None
sort_order: float | None = None
completed_at: str | None = None
archived_at: str | None = None
is_draft: bool | None = None
external_source: str | None = None
external_id: str | None = None
created_by: str | None = None
updated_by: str | None = None
project: str | None = None
workspace: str | None = None
parent: str | None = None
state: str | StateLite | None = None
estimate_point: str | None = None
type: str | None = None
class WorkItemExpand(BaseModel):
"""Expanded work item with nested objects."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str | None = None
cycle: Any | None = None # historical placeholder
module: "ModuleLite | None" = None
labels: list[str] | list[Label] | None = None
assignees: list[str] | list[UserLite] | None = None
state: StateLite | None = None
created_at: str | None = None
updated_at: str | None = None
deleted_at: str | None = None
point: int | None = None
name: str
description: Any | None = None
description_html: str | None = None
description_stripped: str | None = None
description_binary: str | None = None
priority: PriorityEnum | None = None
start_date: str | None = None
target_date: str | None = None
sequence_id: int | None = None
sort_order: float | None = None
completed_at: str | None = None
archived_at: str | None = None
is_draft: bool | None = None
external_source: str | None = None
external_id: str | None = None
created_by: str | None = None
updated_by: str | None = None
project: str | None = None
workspace: str | None = None
parent: str | None = None
estimate_point: str | None = None
type: str | None = None
class CreateWorkItem(BaseModel):
"""Request model for creating a work item."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
assignees: list[str] | None = None
labels: list[str] | None = None
type_id: str | None = None
deleted_at: str | None = None
point: int | None = None
name: str
description_html: str | None = None
description_stripped: str | None = None
priority: PriorityEnum | None = None
start_date: str | None = None
target_date: str | None = None
sequence_id: int | None = None
sort_order: float | None = None
completed_at: str | None = None
archived_at: str | None = None
is_draft: bool | None = None
external_source: str | None = None
external_id: str | None = None
created_by: str | None = None
parent: str | None = None
state: str | None = None
estimate_point: str | None = None
type: str | None = None
class UpdateWorkItem(BaseModel):
"""Request model for updating a work item."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
assignees: list[str] | None = None
labels: list[str] | None = None
type_id: str | None = None
deleted_at: str | None = None
point: int | None = None
name: str | None = None
description_html: str | None = None
description_stripped: str | None = None
priority: PriorityEnum | None = None
start_date: str | None = None
target_date: str | None = None
sequence_id: int | None = None
sort_order: float | None = None
completed_at: str | None = None
archived_at: str | None = None
is_draft: bool | None = None
external_source: str | None = None
external_id: str | None = None
created_by: str | None = None
parent: str | None = None
state: str | None = None
estimate_point: str | None = None
type: str | None = None
class WorkItemForIntakeRequest(BaseModel):
"""Work item data for intake requests."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
name: str
description: Any | None = None
description_html: str | None = None
priority: PriorityEnum | None = None
class WorkItemSearchItem(BaseModel):
"""Work item search result item."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str = Field(..., description="Issue ID")
name: str = Field(..., description="Issue name")
sequence_id: str = Field(..., description="Issue sequence ID")
project__identifier: str = Field(..., description="Project identifier")
project_id: str = Field(..., description="Project ID")
workspace__slug: str = Field(..., description="Workspace slug")
class WorkItemSearch(BaseModel):
"""Work item search results."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
issues: list[WorkItemSearchItem]
class AdvancedSearchWorkItem(BaseModel):
"""Request model for advanced work item search with filters.
Filters support recursive AND/OR groups. Each filter condition is a
single key-value dict (e.g. ``{"state_id": "..."}``). Groups are nested
using ``"and"`` / ``"or"`` keys whose values are lists of conditions or
sub-groups.
Example::
AdvancedSearchWorkItem(
query="new",
filters={
"and": [
{"state_id": "abc-123"},
{"or": [
{"priority": "high"},
{"state_id": "def-456"},
]},
]
},
limit=100,
)
"""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
query: str | None = None
filters: dict[str, Any] | None = None
limit: int | None = None
project_id: str | None = None
workspace_search: bool | None = None
class AdvancedSearchResult(BaseModel):
"""Advanced search result item."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str
name: str
sequence_id: int
project_identifier: str
project_id: str
workspace_id: str
type_id: str | None = None
state_id: str | None = None
priority: str | None = None
target_date: str | None = None
start_date: str | None = None
class WorkItemActivity(BaseModel):
"""Work item activity model."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str | None = None
created_at: str | None = None
updated_at: str | None = None
deleted_at: str | None = None
verb: str | None = None
field: str | None = None
old_value: str | None = None
new_value: str | None = None
comment: str | None = None
attachments: list[str] | None = None
old_identifier: str | None = None
new_identifier: str | None = None
epoch: int | None = None
project: str
workspace: str
issue: str | None = None
issue_comment: str | None = None
actor: str | None = None
class WorkItemComment(BaseModel):
"""Work item comment model."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str | None = None
is_member: bool | None = None
created_at: str | None = None
updated_at: str | None = None
deleted_at: str | None = None
comment_stripped: str | None = None
comment_html: str | None = None
attachments: list[str] | None = None
access: AccessEnum | None = None
external_source: str | None = None
external_id: str | None = None
edited_at: str | None = None
created_by: str | None = None
updated_by: str | None = None
project: str | None = None
workspace: str | None = None
issue: str | None = None
actor: str | None = None
class CreateWorkItemComment(BaseModel):
"""Request model for creating a work item comment."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
comment_json: Any | None = None
comment_html: str | None = None
access: AccessEnum | None = None
external_source: str | None = None
external_id: str | None = None
class UpdateWorkItemComment(BaseModel):
"""Request model for updating a work item comment."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
comment_json: Any | None = None
comment_html: str | None = None
access: AccessEnum | None = None
external_source: str | None = None
external_id: str | None = None
class WorkItemLink(BaseModel):
"""Work item link model."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str | None = None
created_at: str | None = None
updated_at: str | None = None
deleted_at: str | None = None
title: str | None = None
url: str
metadata: Any | None = None
created_by: str | None = None
updated_by: str | None = None
project: str | None = None
workspace: str | None = None
issue: str | None = None
class CreateWorkItemLink(BaseModel):
"""Request model for creating a work item link."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
url: str
class UpdateWorkItemLink(BaseModel):
"""Request model for updating a work item link."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
url: str | None = None
class WorkItemAttachment(BaseModel):
"""Work item attachment model."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str | None = None
created_at: str | None = None
updated_at: str | None = None
deleted_at: str | None = None
attributes: Any | None = None
asset: str
entity_type: str | None = None
entity_identifier: str | None = None
is_deleted: bool | None = None
is_archived: bool | None = None
external_id: str | None = None
external_source: str | None = None
size: int | None = None
is_uploaded: bool | None = None
storage_metadata: Any | None = None
created_by: str | None = None
updated_by: str | None = None
user: str | None = None
workspace: str | None = None
draft_issue: str | None = None
project: str | None = None
issue: str | None = None
comment: str | None = None
page: str | None = None
class WorkItemAttachmentUploadRequest(BaseModel):
"""Request model for uploading work item attachments."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
name: str = Field(..., description="Original filename of the asset")
type: str | None = Field(None, description="MIME type of the file")
size: int = Field(..., description="File size in bytes")
external_id: str | None = Field(
None,
description="External identifier for the asset",
)
external_source: str | None = Field(
None,
description="External source system",
)
class UpdateWorkItemAttachment(BaseModel):
"""Request model for updating a work item attachment."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
is_uploaded: bool | None = Field(
None,
description="Mark attachment as uploaded",
)
class WorkItemRelation(BaseModel):
"""Work item relation model."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str | None = None
project_id: str | None = None
sequence_id: int | None = None
relation_type: str | None = None
name: str | None = None
type_id: str | None = None
is_epic: bool | None = None
state_id: str | None = None
priority: str | None = None
created_by: str | None = None
created_at: str | None = None
updated_at: str | None = None
updated_by: str | None = None
class CreateWorkItemRelation(BaseModel):
"""Request model for creating work item relations."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
relation_type: WorkItemRelationTypeEnum = Field(
...,
description="Type of relationship between work items",
)
issues: list[str] = Field(
...,
description="Array of work item IDs to create relations with",
)
class RemoveWorkItemRelation(BaseModel):
"""Request model for removing work item relation."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
related_issue: str = Field(
...,
description="ID of the related work item to remove relation with",
)
class WorkItemRelationResponse(BaseModel):
"""Response model for work item relations."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
blocking: list[str] = Field(
...,
description="List of issue IDs that are blocking this issue",
)
blocked_by: list[str] = Field(
...,
description="List of issue IDs that this issue is blocked by",
)
duplicate: list[str] = Field(
...,
description="List of issue IDs that are duplicates of this issue",
)
relates_to: list[str] = Field(
...,
description="List of issue IDs that relate to this issue",
)
start_after: list[str] = Field(
...,
description="List of issue IDs that start after this issue",
)
start_before: list[str] = Field(
...,
description="List of issue IDs that start before this issue",
)
finish_after: list[str] = Field(
...,
description="List of issue IDs that finish after this issue",
)
finish_before: list[str] = Field(
...,
description="List of issue IDs that finish before this issue",
)
class WorkItemWorkLog(BaseModel):
"""Work item work log model."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
id: str | None = None
created_at: str | None = None
updated_at: str | None = None
description: str | None = None
duration: int | None = None
created_by: str | None = None
updated_by: str | None = None
project_id: str | None = None
workspace_id: str | None = None
logged_by: str | None = None
class CreateWorkItemWorkLog(BaseModel):
"""Request model for creating a work item work log."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
description: str | None = None
duration: int | None = None
created_by: str | None = None
updated_by: str | None = None
class UpdateWorkItemWorkLog(BaseModel):
"""Request model for updating a work item work log."""
model_config = ConfigDict(extra="ignore", populate_by_name=True)
description: str | None = None
duration: int | None = None
created_by: str | None = None
updated_by: str | None = None
class PaginatedWorkItemResponse(PaginatedResponse):
"""Paginated response for work items."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
results: list[WorkItem]
class PaginatedWorkItemActivityResponse(PaginatedResponse):
"""Paginated response for work item activities."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
results: list[WorkItemActivity]
class PaginatedWorkItemCommentResponse(PaginatedResponse):
"""Paginated response for work item comments."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
results: list[WorkItemComment]
class PaginatedWorkItemLinkResponse(PaginatedResponse):
"""Paginated response for work item links."""
model_config = ConfigDict(extra="allow", populate_by_name=True)
results: list[WorkItemLink]