مواد پر جائیں

ٹکٹ لائف سائیکل

اسٹیٹس اسٹوریج اسٹرنگ تفصیل
backlog backlog محفوظ، ابھی فعال قطار میں ٹرائیج نہیں ہوا
open open ٹرائیج شدہ اور کام کے لیے تیار، شروع نہیں ہوا
inProgress inProgress فعال طور پر کام جاری
blocked blocked شروع ہوا مگر کسی بیرونی چیز پر بلاک
inReview inReview کام ہو گیا، ریویو کا انتظار
done done کامیابی سے مکمل (ٹرمینل)
failed failed خرابی کے ساتھ مکمل (ٹرمینل)
cancelled cancelled ترک کر دیا گیا (ٹرمینل)

اسٹیٹس ویلیوز camelCase میں محفوظ ہوتی ہیں (inProgress، inReview)، کبھی in_progress نہیں۔ null محفوظ ویلیو open کے طور پر پارس ہوتی ہے؛ نامعلوم ویلیو کوسٹ کرنے کے بجائے استثنا پھینکتی ہے۔

tryParseLoose ایجنٹ کی فراہم کردہ عرفیات قبول کرتا ہے، اور کیس نیز - / _ / اسپیس نظر انداز کرتا ہے:

اسٹیٹس قبول شدہ عرفیات
open todo, ready, pending, new
inProgress doing, started, active, wip
blocked stuck
inReview review, reviewing
done closed, complete, completed, finished
failed error, errored
cancelled canceled, abandoned, dropped
backlog ──→ open ──→ inProgress ──→ inReview ──→ done
│ │ │
│ └──→ failed ┘
└──→ blocked ──→ inProgress
Any non-terminal status ──→ cancelled; inReview ──→ failed

یہ گراف صرف ایجنٹس اور آٹومیشن کو باندھتا ہے۔ TicketWorkflowService.transitionStatus اسے اُس وقت چیک کرتا ہے جب force false ہو — یعنی MCP ٹولز اور ری کنسائلرز۔ وہاں غیر قانونی منتقلی لاگ ہو کر نظر انداز کر دی جاتی ہے۔ UI میں صارف کے ہر عمل سے ہونے والی تبدیلی force: true بھیجتی ہے اور گراف کو مکمل طور پر نظر انداز کر دیتی ہے، اس لیے کوئی انسان ٹکٹ کو پکر کی فہرست میں موجود کسی بھی اسٹیٹس پر لے جا سکتا ہے (failed کے سوا ہر اسٹیٹس)، بشمول کسی ٹرمینل اسٹیٹس کو دوبارہ کھولنا۔ ایجنٹس failed کو fail_ticket سے نشان زد کرتے ہیں۔

کوئی اسٹیٹس ہمیشہ اپنے آپ میں منتقل ہو سکتا ہے۔ ٹرمینل حالتوں سے باہر جانے والا کوئی کنارہ نہیں ہوتا۔

سے اجازت یافتہ اہداف
backlog open, cancelled
open inProgress, blocked, cancelled
inProgress blocked, inReview, done, failed, cancelled
blocked inProgress, cancelled
inReview inProgress, done, failed, cancelled
done — (ٹرمینل)
failed — (ٹرمینل)
cancelled — (ٹرمینل)

Linear کے مقامی 0–4 پیمانے پر ایک انٹیجر کے طور پر محفوظ ہوتی ہے۔ نامعلوم ویلیو none کے طور پر پارس ہوتی ہے۔

ترجیح محفوظ بطور
none 0
urgent 1
high 2
medium 3
low 4

نامعلوم یا null محفوظ ویلیو local کے طور پر پارس ہوتی ہے۔

فراہم کنندہ اسٹیٹس
local مکمل طور پر ورک اسپیس ڈیٹا بیس میں محفوظ؛ ڈیفالٹ
linear ریموٹ کی ملکیت، مقامی طور پر آئینہ شدہ

سنک اڈاپٹرز packages/cc_infra/lib/src/tickets/sync/ کے تحت Linear، GitHub Issues، Jira Cloud اور ClickUp کے لیے رہتے ہیں۔ GitHub Issues صرف ایک سنک-اڈاپٹر وینڈر (vendorId: github) ہے — یہ کوئی TicketProvider ویلیو نہیں، اس لیے GitHub سے کھینچا گیا ایشو originKind: externalSync اور ڈیفالٹ provider: local کے ساتھ محفوظ ہوتا ہے۔ وینڈر میپنگ ticket_sync_links پر رہتی ہے۔

createTicket manual لکھتا ہے۔ وینڈر سے آنے والا پل externalSync لکھتا ہے۔ تفویض شدہ ذیلی ٹکٹس manual رہتے ہیں۔

ویلیو مطلب
manual createTicket پر ڈیفالٹ (انسانی، ایجنٹ اور تفویض شدہ قطاریں)
externalSync وینڈر پل پر TicketSyncEngine کی طرف سے سیٹ

یہ ایگریگیٹ ایک ہی قطار پر دو معاملات سمیٹتا ہے۔ آئینہ (فراہم کنندہ، کلیدیں، عنوان، تفصیل، ترجیح، لیبلز، اسٹیٹس، ٹائم سٹیمپس) ریموٹ فراہم کنندہ کے لیے ایک کیش ہے اور ریفریش اسے مکمل طور پر دوبارہ لکھ دیتی ہے۔ اضافی تہہ (اسائنمنٹ، تفویض، اسپیس، والد، پروجیکٹ، لنک شدہ PRs) صرف Control Center میں ہوتی ہے اور ریفریش اسے کبھی نہیں چھوتی۔

فیلڈ قسم تفصیل
id String UUID v4
workspaceId String مالک ورک اسپیس
provider TicketProvider کینونیکل ڈیٹا کا مالک بیک اینڈ (ڈیفالٹ local)
externalKey String? فراہم کنندہ کا مقامی کلید (مثلاً LIN-123)۔ مقامی createTicket یہاں ایک الگ UUID لکھتا ہے، قطار کی id نہیں
url String? ریموٹ فراہم کنندہ پر ویب URL
title String مختصر خلاصہ؛ خالی نہیں ہو سکتا
description String? طویل Markdown باڈی
priority TicketPriority ڈیفالٹ none
labels List<String> آزادانہ لیبلز
status TicketStatus کینونیکل نارملائزڈ اسٹیٹس
rawStatus String? ریموٹ فراہم کنندہ کی مقامی حالت کا نام، بلا نقصان نمائش کے لیے رکھا جاتا ہے
externalSyncedAt DateTime? آخری ملٹی وینڈر سنک؛ پہلے تک null۔ فی وینڈر میپنگ ticket_sync_links میں رہتی ہے
parentTicketId String? تفویض / تقسیم کے درخت میں والد
projectId String? مالک پروجیکٹ؛ کبھی ریموٹ پر پش نہیں ہوتا
assignedAgentId String? اسائن شدہ پرنسپل کی id (صرف میٹا ڈیٹا — اسائن کرنا کچھ ڈسپیچ نہیں کرتا)
assigneeType PrincipalType assignedAgentId کس قسم کے پرنسپل کی نشان دہی کرتا ہے — user یا agent (ڈیفالٹ agent)
createdByType PrincipalType? ٹکٹ بنانے والے پرنسپل کی قسم (user یا agent)؛ پرانی/سسٹم قطاروں کے لیے null
createdById String? بنانے والے پرنسپل کی id
assignedTeamId String? اسائن شدہ ٹیم (صرف میٹا ڈیٹا)
delegatedByAgentId String? وہ ایجنٹ جس نے یہ ٹکٹ تفویض کیا
delegationDepth int تفویض کی زنجیر میں گہرائی؛ جڑ 0 ہے، زیادہ سے زیادہ گہرائی کی حد کے خلاف چیک ہوتی ہے
delegationRootTicketId String? تفویض کی زنجیر کی جڑ؛ جڑ ٹکٹ کے لیے null
spaceId String? وہ گفتگو جس سے ٹکٹ نکالا گیا، یا تفویض کرنے والے ایجنٹ کا اسپیس
errorMessage String? اُس وقت سیٹ ہوتا ہے جب status failed ہو
linkedPrIds List<String> PR نوڈ ids جن سے یہ ٹکٹ لنک ہے
metadata Map<String, dynamic> آزادانہ بیگ
createdAt DateTime بننے کا وقت
startedAt DateTime? جب کام شروع ہوا
blockedAt DateTime? جب ٹکٹ بلاک ہوا
cancelledAt DateTime? جب ٹکٹ منسوخ ہوا
completedAt DateTime? جب ٹکٹ کامیابی سے مکمل ہوا
finishedAt DateTime? جب ٹکٹ کسی ٹرمینل حالت میں پہنچا
updatedAt DateTime آخری میوٹیشن (آئینہ ریفریش یا اضافی تہہ کی تبدیلی)
version int آپٹیمسٹک-کنکرنسی کاؤنٹر، ہر میوٹیشن پر بڑھتا ہے
originKind TicketOriginKind ٹکٹ کیسے بنایا گیا (ڈیفالٹ manual)
collaborators List<TicketCollaborator> مانگ پر ریپوزٹری کی طرف سے بھرے جاتے ہیں

اخذ شدہ: isTerminal، isRemote (provider != local)، isAssignedToUser اور displayKey (externalKey ?? id — چنانچہ مقامی ٹکٹس بننے کے وقت کا الگ UUID دکھاتے ہیں، قطار کی id نہیں)۔

محفوظ کنارے ticket_links میں سمتی قطاریں ہیں:

قسم اسٹوریج اسٹرنگ مطلب
blocks blocks ماخذ ہدف کو بلاک کرتا ہے
relatesTo relates_to دوطرفہ تعلق
duplicateOf duplicate_of ماخذ ہدف کی نقل ہے

جو الفاظ UI اور ticket_relation استعمال کرتے ہیں وہ TicketRelationKind ہے، جو ایک محفوظ کنارے اور اِس بات سے اخذ ہوتا ہے کہ موضوع کس سرے پر بیٹھا ہے:

قسم ماخوذ از
blockedBy ایک blocks قطار جہاں موضوع ہدف ہے
blocking ایک blocks قطار جہاں موضوع ماخذ ہے
relatedTo ایک relates_to قطار (دوطرفہ)
duplicateOf ایک duplicate_of قطار جہاں موضوع ماخذ ہے
duplicatedBy ایک duplicate_of قطار جہاں موضوع ہدف ہے
subIssueOf موضوع پر tickets.parent_ticket_id
parentOf دوسرے ٹکٹ پر tickets.parent_ticket_id

والد اور ذیلی ایشو کے لنکس ticket_links قطاریں نہیں ہیں — وہ tickets.parent_ticket_id پر رہتے ہیں۔

یہ آٹھ کلاسز packages/cc_domain/lib/core/domain/events/ticketing_events.dart میں رہتی ہیں۔ کوئی TicketStarted، TicketDelegated، TicketCollaboratorAdded یا ExternalTicketWebhookReceived نہیں ہے۔

ایونٹ کب فائر ہوتا ہے
TicketCreated ٹکٹ بنتا ہے
TicketAssigned ٹکٹ کسی پرنسپل یا ٹیم کو اسائن ہوتا ہے
TicketCompleted کام کامیابی سے مکمل ہوتا ہے
TicketFailed کام ناکام ہوتا ہے
TicketCancelled ٹکٹ منسوخ ہوتا ہے
TicketStatusChanged کوئی بھی اسٹیٹس تبدیلی
TicketReassigned ٹکٹ دوبارہ اسائن ہوتا ہے
TicketDetailsUpdated عنوان، تفصیل، ترجیح یا لیبلز بدلتے ہیں

TicketAssigned ایک آڈٹ اور اطلاعاتی سگنل اور ایک پائپ لائن ٹریگر ہے۔ کسی ایجنٹ کو اسائن کرنے سے کوئی رن شروع نہیں ہوتا — کوئی ٹکٹ ڈسپیچر ایسا نہیں جو assignedAgentId پر نظر رکھے۔ ٹیم کو اسائن کرنا استثنا ہے: TeamRoutingService ٹیم لیڈر کو ڈسپیچ کرتا ہے۔ کوئی تعاون کنندہ شامل کرنا ایک قطار لکھتا ہے اور کچھ شائع نہیں کرتا۔ وینڈر ویب ہک کسی ڈومین ایونٹ کے بغیر TicketSyncEngine کے ذریعے لاگو ہوتا ہے۔

TicketWorkflowService ہر میوٹیشن کی مالک ہے۔

میکانزم تفصیل
واحد چوک پوائنٹ تمام میوٹیشنز _mutate سے گزرتی ہیں، جو لاگو کرنے سے پہلے قطار لوڈ کرتا ہے اور _assertWorkspace کال کرتا ہے
ورک اسپیس کی تنہائی _assertWorkspace WorkspaceMismatchException پھینکتا ہے جب لوڈ شدہ قطار کا workspaceId کالر سے میل نہ کھائے
آپٹیمسٹک کنکرنسی _mutate لکھتے وقت expectedVersion کو اُس version پر سیٹ کرتا ہے جو اُس نے ابھی پڑھا، اور تازہ حالت دوبارہ پڑھ کر ConcurrencyConflictException پر دوبارہ کوشش کرتا ہے
خصوصی کلیم tryCheckout / releaseCheckout؛ چیک آؤٹ شدہ ٹکٹ کا دعویٰ کرنے والے دوسرے ایجنٹ کو CheckoutConflictException ملتا ہے
منتقلی گارڈ canTransitionTo، صرف اُس وقت لاگو جب force false ہو