feat: sprints with burndown and carry-over
Plan sprints with dates and a goal, run one at a time per project, and put tickets in them from the ticket page. The Sprints tab follows the one under way with its progress and a burndown in tickets or points against the ideal line. Closing a sprint sends what was left to the next one or back to the backlog; the board can be filtered by sprint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,12 +12,13 @@ export class IssueTimelineEntry {
|
||||
issueId!: string;
|
||||
projectId!: string;
|
||||
at!: string;
|
||||
kind!: 'status' | 'release';
|
||||
kind!: 'status' | 'release' | 'sprint';
|
||||
status?: string;
|
||||
category?: StatusCategory;
|
||||
/** Assignee when the status changed (throughput per person). */
|
||||
assigneeId?: string | null;
|
||||
releaseId?: string | null;
|
||||
sprintId?: string | null;
|
||||
}
|
||||
|
||||
export class DurationStats {
|
||||
|
||||
@@ -8,3 +8,4 @@ export * from './project-stats.read-model';
|
||||
export * from './analytics.read-model';
|
||||
export * from './notification.read-model';
|
||||
export * from './saved-filter.read-model';
|
||||
export * from './sprint.read-model';
|
||||
|
||||
@@ -70,6 +70,7 @@ export class IssueReadModel {
|
||||
reporter!: UserRefReadModel;
|
||||
assignee!: UserRefReadModel | null;
|
||||
release!: { id: string; name: string } | null;
|
||||
sprint!: { id: string; name: string } | null;
|
||||
labels!: string[];
|
||||
figmaUrl!: string | null;
|
||||
storyPoints!: number | null;
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { SprintStatus } from '../sprint/sprint-status';
|
||||
|
||||
export class SprintReadModel {
|
||||
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;
|
||||
createdAt!: string;
|
||||
version!: number;
|
||||
}
|
||||
|
||||
/** How far a sprint's tickets have got. */
|
||||
export class SprintProgressReadModel {
|
||||
total!: number;
|
||||
/** Done or cancelled. */
|
||||
finished!: number;
|
||||
percent!: number;
|
||||
storyPoints!: number;
|
||||
finishedStoryPoints!: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Per day of the sprint: tickets in it (cancelled ones aside), how many are
|
||||
* still open and their points. Days still to come are null; `ideal` falls in
|
||||
* a straight line from what was open on the first day to zero on the last.
|
||||
*/
|
||||
export class SprintBurndownReadModel {
|
||||
sprintId!: string;
|
||||
dates!: string[];
|
||||
scope!: (number | null)[];
|
||||
remaining!: (number | null)[];
|
||||
remainingPoints!: (number | null)[];
|
||||
ideal!: number[];
|
||||
}
|
||||
Reference in New Issue
Block a user