Add issue change history and daily issue stats
Gitea Actions Demo / Deploy (push) Successful in 32s

Issue changes are recorded per field in the issue_change table, in the same
transaction as the issue itself. The new history module exposes:
- GET /api/issues/:issueId/history — change timeline grouped by save
- GET /api/issues/stats/daily — created, status transitions and status
  snapshot per day, with time zone support

The migration backfills history for existing issues. Setting a field to its
current value no longer bumps updatedAt or emits issue.updated.
This commit is contained in:
vadim committed 2026-10-08 09:55:21 +03:00
1 parent f44590b8ca
commit cb29c7d2c4
26 files changed
+1026 -16

No files matched your search

@@ -72,6 +72,14 @@ describe('UpdateIssueUseCase', () => {
expect(repository.update).toHaveBeenCalledTimes(1);
});
it('passes the acting user to the repository as the author of the changes', async () => {
vi.mocked(repository.findById).mockResolvedValue(buildIssue());
await useCase.execute(new UpdateIssueCommand(1, 'user-7', undefined, undefined, 'DONE'));
expect(repository.update).toHaveBeenCalledWith(expect.any(Issue), 'user-7');
});
it('assigns and unassigns depending on the assignee value', async () => {
vi.mocked(repository.findById).mockResolvedValue(buildIssue());
@@ -57,7 +57,7 @@ export class UpdateIssueUseCase {
issue.updateDueDate(command.dueDate);
}
await this.issueRepository.update(issue);
await this.issueRepository.update(issue, command.userId);
const dto = await this.issueUserExpander.expand(issue);
if (issue.assignee) {