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>
60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
import { StatusCategory } from '../project/project-settings';
|
|
import { UserRefReadModel } from './user-ref.read-model';
|
|
|
|
/**
|
|
* One step in a ticket's life (projected from its events): the raw material
|
|
* of the statistics. `status` entries record where the ticket went (with the
|
|
* category it had then), `release` entries which release it joined or left.
|
|
*/
|
|
export class IssueTimelineEntry {
|
|
/** Id of the event that produced it (projection is idempotent). */
|
|
id!: string;
|
|
issueId!: string;
|
|
projectId!: string;
|
|
at!: string;
|
|
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 {
|
|
count!: number;
|
|
averageDays!: number | null;
|
|
/** 85th percentile: "85% of tickets take at most this long". */
|
|
p85Days!: number | null;
|
|
}
|
|
|
|
/** Statistics of a project over a period. */
|
|
export class ProjectAnalyticsReadModel {
|
|
from!: string;
|
|
to!: string;
|
|
/** Per week (Monday): tickets created and tickets finished. */
|
|
createdVsResolved!: { week: string; created: number; resolved: number }[];
|
|
/** Tickets in each status at the end of every day (cumulative flow). */
|
|
cumulativeFlow!: {
|
|
dates: string[];
|
|
series: { status: string; counts: number[] }[];
|
|
};
|
|
/** From starting work to done. */
|
|
cycleTime!: DurationStats;
|
|
/** From creation to done. */
|
|
leadTime!: DurationStats;
|
|
/** Tickets finished per person and week. */
|
|
throughput!: { week: string; user: UserRefReadModel | null; count: number }[];
|
|
/** Tickets leaving QA: to done (passed) or back to work (failed). */
|
|
qa!: { passed: number; failed: number; failureRate: number | null };
|
|
}
|
|
|
|
/** Scope vs finished tickets of a release, day by day. */
|
|
export class ReleaseBurnupReadModel {
|
|
releaseId!: string;
|
|
targetDate!: string | null;
|
|
dates!: string[];
|
|
scope!: number[];
|
|
done!: number[];
|
|
}
|