feat: estimate tickets and see the team's velocity

Story points can be set on the ticket page and when creating a ticket,
and show on cards, column headers, subtasks and the backlog. The Sprints
tab charts the points finished per closed sprint and warns when a planned
sprint holds more than the recent average.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 15:04:11 +02:00
parent 50d3ffd1dd
commit 6aec774c92
16 changed files with 304 additions and 20 deletions

View File

@@ -289,6 +289,7 @@ export type IssueSummaryFieldsFragment = {
updatedAt: string;
version: number;
rank: string;
storyPoints: number | null;
assignee: { id: string; name: string } | null;
release: { id: string; name: string } | null;
sprint: { id: string; name: string } | null;
@@ -298,7 +299,6 @@ export type IssueSummaryFieldsFragment = {
export type IssueFieldsFragment = {
description: string | null;
figmaUrl: string | null;
storyPoints: number | null;
dueDate: string | null;
createdAt: string;
allowedTransitions: Array<string>;
@@ -316,6 +316,7 @@ export type IssueFieldsFragment = {
updatedAt: string;
version: number;
rank: string;
storyPoints: number | null;
reporter: { id: string; name: string };
links: Array<{
type: IssueLinkType;
@@ -409,6 +410,7 @@ export type BoardQuery = {
updatedAt: string;
version: number;
rank: string;
storyPoints: number | null;
assignee: { id: string; name: string } | null;
release: { id: string; name: string } | null;
sprint: { id: string; name: string } | null;
@@ -426,7 +428,6 @@ export type IssueQuery = {
issue: {
description: string | null;
figmaUrl: string | null;
storyPoints: number | null;
dueDate: string | null;
createdAt: string;
allowedTransitions: Array<string>;
@@ -444,6 +445,7 @@ export type IssueQuery = {
updatedAt: string;
version: number;
rank: string;
storyPoints: number | null;
reporter: { id: string; name: string };
links: Array<{
type: IssueLinkType;
@@ -490,6 +492,7 @@ export type SearchIssuesQuery = {
updatedAt: string;
version: number;
rank: string;
storyPoints: number | null;
assignee: { id: string; name: string } | null;
release: { id: string; name: string } | null;
sprint: { id: string; name: string } | null;
@@ -642,6 +645,7 @@ export type MyIssuesQuery = {
updatedAt: string;
version: number;
rank: string;
storyPoints: number | null;
assignee: { id: string; name: string } | null;
release: { id: string; name: string } | null;
sprint: { id: string; name: string } | null;
@@ -671,6 +675,7 @@ export type IssueChildrenQuery = {
updatedAt: string;
version: number;
rank: string;
storyPoints: number | null;
assignee: { id: string; name: string } | null;
release: { id: string; name: string } | null;
sprint: { id: string; name: string } | null;
@@ -700,6 +705,7 @@ export type EpicsQuery = {
updatedAt: string;
version: number;
rank: string;
storyPoints: number | null;
assignee: { id: string; name: string } | null;
release: { id: string; name: string } | null;
sprint: { id: string; name: string } | null;
@@ -771,6 +777,7 @@ export type BacklogQuery = {
updatedAt: string;
version: number;
rank: string;
storyPoints: number | null;
assignee: { id: string; name: string } | null;
release: { id: string; name: string } | null;
sprint: { id: string; name: string } | null;
@@ -1396,6 +1403,7 @@ export type IssueChangedSubscription = {
updatedAt: string;
version: number;
rank: string;
storyPoints: number | null;
assignee: { id: string; name: string } | null;
release: { id: string; name: string } | null;
sprint: { id: string; name: string } | null;
@@ -1783,6 +1791,7 @@ export const IssueSummaryFieldsFragmentDoc = {
},
},
{ kind: 'Field', name: { kind: 'Name', value: 'rank' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
],
},
},
@@ -1822,7 +1831,6 @@ export const IssueFieldsFragmentDoc = {
},
{ kind: 'Field', name: { kind: 'Name', value: 'description' } },
{ kind: 'Field', name: { kind: 'Name', value: 'figmaUrl' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
{ kind: 'Field', name: { kind: 'Name', value: 'dueDate' } },
{ kind: 'Field', name: { kind: 'Name', value: 'createdAt' } },
{
@@ -1997,6 +2005,7 @@ export const IssueFieldsFragmentDoc = {
},
},
{ kind: 'Field', name: { kind: 'Name', value: 'rank' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
],
},
},
@@ -2658,6 +2667,7 @@ export const BoardDocument = {
},
},
{ kind: 'Field', name: { kind: 'Name', value: 'rank' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
],
},
},
@@ -2801,6 +2811,7 @@ export const IssueDocument = {
},
},
{ kind: 'Field', name: { kind: 'Name', value: 'rank' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
],
},
},
@@ -2820,7 +2831,6 @@ export const IssueDocument = {
},
{ kind: 'Field', name: { kind: 'Name', value: 'description' } },
{ kind: 'Field', name: { kind: 'Name', value: 'figmaUrl' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
{ kind: 'Field', name: { kind: 'Name', value: 'dueDate' } },
{ kind: 'Field', name: { kind: 'Name', value: 'createdAt' } },
{
@@ -3063,6 +3073,7 @@ export const SearchIssuesDocument = {
},
},
{ kind: 'Field', name: { kind: 'Name', value: 'rank' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
],
},
},
@@ -4290,6 +4301,7 @@ export const MyIssuesDocument = {
},
},
{ kind: 'Field', name: { kind: 'Name', value: 'rank' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
],
},
},
@@ -4447,6 +4459,7 @@ export const IssueChildrenDocument = {
},
},
{ kind: 'Field', name: { kind: 'Name', value: 'rank' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
],
},
},
@@ -4622,6 +4635,7 @@ export const EpicsDocument = {
},
},
{ kind: 'Field', name: { kind: 'Name', value: 'rank' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
],
},
},
@@ -5101,6 +5115,7 @@ export const BacklogDocument = {
},
},
{ kind: 'Field', name: { kind: 'Name', value: 'rank' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
],
},
},
@@ -8748,6 +8763,7 @@ export const IssueChangedDocument = {
},
},
{ kind: 'Field', name: { kind: 'Name', value: 'rank' } },
{ kind: 'Field', name: { kind: 'Name', value: 'storyPoints' } },
],
},
},