import { NotificationKind, IssueLinkType, IssuePriority, ProjectRole, ReleaseStatus, SprintStatus, StatusCategory, } from './enums'; import { ProjectSettings } from './workflow'; export interface UserRef { id: string; name: string; } export interface ProjectMember { user: UserRef; role: ProjectRole; } export interface Project { id: string; key: string; name: string; description: string | null; /** Anyone can read it, also without signing in. */ isPublic: boolean; owner: UserRef; members: ProjectMember[]; settings: ProjectSettings; updatedAt: string; version: number; } export interface IssueLink { type: IssueLinkType; /** OUTWARD: this issue → other. INWARD: other → this issue. */ direction: 'OUTWARD' | 'INWARD'; issueId: string; issueKey: string; } /** The ticket another one hangs from. */ export interface IssueParent { id: string; key: string; title: string; } /** A step inside a ticket that does not deserve a ticket of its own. */ export interface ChecklistItem { id: string; text: string; done: boolean; } /** How far the tickets hanging from one have got. */ export interface ChildProgress { total: number; /** Done or cancelled. */ finished: number; percent: number; storyPoints: number; finishedStoryPoints: number; } /** A top-level ticket that groups others. */ export interface Epic { issue: IssueSummary; progress: ChildProgress; } /** What a saved view narrows the board to; empty: everything. */ export interface SavedFilterCriteria { types?: string[] | null; areas?: string[] | null; priorities?: IssuePriority[] | null; assigneeId?: string | null; unassigned?: boolean | null; releaseId?: string | null; labels?: string[] | null; search?: string | null; } /** A named view of the board: private, or shared with the project. */ export interface SavedFilter { id: string; projectId: string; owner: UserRef; name: string; shared: boolean; criteria: SavedFilterCriteria; createdAt: string; } /** What boards and lists show. */ export interface IssueSummary { id: string; projectId: string; key: string; /** Ids of the project's settings. */ type: string; area: string | null; title: string; status: string; statusCategory: StatusCategory; priority: IssuePriority; assignee: UserRef | null; release: { id: string; name: string } | null; sprint: { id: string; name: string } | null; labels: string[]; /** The epic or ticket this one breaks down. */ parent: IssueParent | null; /** Place in the backlog and in its board column (ascending, as text). */ rank: string; /** Estimate; null when nobody estimated it. */ storyPoints: number | null; /** Planned start and end (`YYYY-MM-DD`), for the roadmap. */ startDate: string | null; dueDate: string | null; commentCount: number; updatedAt: string; version: number; } /** A page of tickets: the ones returned and how many match in total. */ export interface IssuePage { items: IssueSummary[]; total: number; } /** A file on a ticket (or under one of its comments). */ export interface Attachment { id: string; fileName: string; mimeType: string; /** Bytes. */ size: number; uploadedBy: UserRef; uploadedAt: string; commentId: string | null; } export interface Issue extends IssueSummary { description: string | null; reporter: UserRef; figmaUrl: string | null; links: IssueLink[]; attachments: Attachment[]; /** People following the ticket. */ watchers: UserRef[]; checklist: ChecklistItem[]; /** Commits, branches and pull requests that mention it. */ devLinks: DevLink[]; allowedTransitions: string[]; createdAt: string; } /** A commit, branch or pull request that mentions a ticket. */ export interface DevLink { kind: 'COMMIT' | 'BRANCH' | 'PULL_REQUEST'; url: string; title: string; /** Short SHA, branch or PR number. */ ref: string; state: 'OPEN' | 'MERGED' | 'CLOSED' | null; provider: string; author: string | null; at: string; } export interface WebhookDelivery { at: string; event: string; /** HTTP status, null when it never answered. */ status: number | null; ok: boolean; error: string | null; } /** Where the project tells another system what happened. */ export interface Webhook { id: string; url: string; /** Event names, `family.*` or `*`. */ events: string[]; active: boolean; createdBy: UserRef; createdAt: string; lastDelivery: WebhookDelivery | null; } /** What an import did (or, as a preview, would do). */ export interface ImportReport { format: 'taskstream' | 'jira'; dryRun: boolean; rows: number; created: number; keys: string[]; skipped: { line: number; reason?: string }[]; warnings: { line: number; message?: string }[]; } /** The project's webhook for GitHub, Gitea or GitLab. */ export interface GitIntegration { enabled: boolean; /** Only for owners and admins. */ secret: string | null; webhookPath: string; } export interface Comment { id: string; issueId: string; author: UserRef; body: string; createdAt: string; editedAt: string | null; } export interface SprintProgress { total: number; /** Done or cancelled. */ finished: number; percent: number; storyPoints: number; finishedStoryPoints: number; } /** A time-boxed iteration of a project. */ export interface Sprint { id: string; projectId: string; name: string; goal: string | null; /** `YYYY-MM-DD`, both included. */ startDate: string; endDate: string; status: SprintStatus; startedAt: string | null; closedAt: string | null; progress: SprintProgress; } /** Per day of a sprint; null for the days to come. */ export interface SprintBurndown { sprintId: string; dates: string[]; scope: (number | null)[]; remaining: (number | null)[]; remainingPoints: (number | null)[]; ideal: number[]; } export interface Release { id: string; projectId: string; name: string; description: string | null; targetDate: string | null; status: ReleaseStatus; releasedAt: string | null; /** What shipped, told for people (Markdown). */ notes: string | null; progress: { total: number; finished: number; percent: number }; } export interface Activity { id: string; type: string; issueId: string | null; issueKey: string | null; actor: UserRef; summary: string; occurredAt: string; } export interface CountBy { key: T; count: number; } export interface ProjectStats { total: number; open: number; byStatus: CountBy[]; byType: CountBy[]; byPriority: CountBy[]; byArea: CountBy[]; byAssignee: { user: UserRef | null; count: number }[]; } export interface BoardColumn { status: string; issues: IssueSummary[]; total: number; } export interface DurationStats { count: number; averageDays: number | null; /** 85% of tickets take at most this long. */ p85Days: number | null; } /** Statistics of a project over the last days. */ export interface ProjectAnalytics { from: string; to: string; /** Per week (Monday, YYYY-MM-DD). */ createdVsResolved: { week: string; created: number; resolved: number }[]; /** Tickets in each status at the end of every day. */ cumulativeFlow: { dates: string[]; series: { status: string; counts: number[] }[]; }; /** Start of work → done. */ cycleTime: DurationStats; /** Creation → done. */ leadTime: DurationStats; throughput: { week: string; user: UserRef | null; count: number }[]; qa: { passed: number; failed: number; failureRate: number | null }; } /** Scope vs finished tickets of a release, day by day. */ export interface ReleaseBurnup { releaseId: string; targetDate: string | null; dates: string[]; scope: number[]; done: number[]; } export interface UserDirectoryEntry { id: string; name: string; email: string; } /** Ack of a command: the read model catches up asynchronously. */ export interface CommandResult { id: string; key?: string | null; version: number; } /** Something the signed-in person should know. */ export interface Notification { id: string; kind: NotificationKind; projectId: string; projectKey: string; issueId: string | null; issueKey: string | null; actor: UserRef; summary: string; /** Null: unread. */ readAt: string | null; createdAt: string; } export interface NotificationSettings { /** Copies by e-mail. */ email: boolean; /** Whether this installation can send e-mail at all. */ emailAvailable: boolean; }