mirror of
https://github.com/wekan/wekan.git
synced 2026-11-07 11:02:33 -05:00
A sprint's start and close snapshots kept one row per card inside the sprint document, so a sprint over about 15,000 cards could not be closed. The rows now go to their own collection, scrumSnapshotRows, in immutable chunks of 2,000 named by sprint, kind, snapshot time and chunk number, so a retried start or close, an undo or a redo finds the same rows. The sprint keeps a header and the report's totals, computed from all rows. The board data computes each sprint's report on the server and sends only snapshot headers: from the stored totals, or for an assigned-only reader from the rows they may see. The scope replay, the transfer export and the board copy read the rows from wherever they are kept; the transfer import writes them back as chunks through the import journal. Snapshots stored inline before this keep working. Thanks to xet7 !
20 lines
1.3 KiB
JavaScript
20 lines
1.3 KiB
JavaScript
import { Meteor } from 'meteor/meteor';
|
|
import { getScrumBoardData, getScrumDailyHistory } from '/server/scrum';
|
|
const { velocityReports } = require('/models/lib/scrumReports');
|
|
|
|
export async function loadScrumChartData(userId, boardId, chartKey, options = {}) {
|
|
if (chartKey === 'scrumDaily') {
|
|
if (typeof options.sprintId !== 'string' || !options.sprintId || options.sprintId.length > 200) throw new Meteor.Error('invalid-sprint');
|
|
return getScrumDailyHistory(userId, boardId, options.sprintId);
|
|
}
|
|
const data = await getScrumBoardData(userId, boardId);
|
|
if (data.importPending) throw new Meteor.Error('scrum-import-pending', 'The Scrum import is incomplete. Report exports are unavailable.');
|
|
// Reports computed by getScrumBoardData, from the rows the reader may see.
|
|
if (chartKey === 'scrumVelocity') return { reports: velocityReports(data.sprints), partial: data.partial };
|
|
if (chartKey !== 'scrumSprint') throw new Meteor.Error('invalid-chart');
|
|
if (typeof options.sprintId !== 'string' || options.sprintId.length > 200) throw new Meteor.Error('invalid-sprint');
|
|
const sprint = data.sprints.find(s => s._id === options.sprintId);
|
|
if (!sprint) throw new Meteor.Error('not-found', 'Sprint not found on this board');
|
|
return { reports: sprint.closeSnapshot && sprint.report ? [sprint.report] : [], partial: data.partial };
|
|
}
|