feat: an ordered backlog

A Backlog tab lists the tickets still to start in the order the team will
take them; drag them, or use the arrows, to reorder. Moving a ticket only
rewrites that ticket's rank, read from the event store, and board columns
follow the same order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 14:01:44 +02:00
parent d4da33d4e8
commit 0606f53026
53 changed files with 1599 additions and 32 deletions

View File

@@ -279,6 +279,32 @@ describe('Issue', () => {
});
});
describe('backlog order', () => {
it('moves between two tickets, to the top, and survives a replay', () => {
const issue = newIssue();
const other = (number: number) =>
factory.create({
projectId: 'p-1',
projectKey: 'TS',
number,
title: `#${number}`,
type: IssueType.TASK,
reporterId: 'u',
});
const [one, two] = [other(1), other(2)];
issue.moveBetween('u-pm', one, two);
expect(issue.backlogRank > one.backlogRank).toBe(true);
expect(issue.backlogRank < two.backlogRank).toBe(true);
issue.moveBetween('u-pm', null, one);
expect(issue.backlogRank < one.backlogRank).toBe(true);
expect(replay(issue, Issue).rebuilt.rank).toBe(issue.rank);
expect(() => issue.moveBetween('u-pm', issue, null)).toThrow(
BusinessRuleError,
);
});
});
describe('checklist', () => {
it('adds, ticks, rewords and removes steps, and survives a replay', () => {
const issue = newIssue();