first commit

This commit is contained in:
2026-10-03 13:40:26 +02:00
parent 732a5b5a16
commit 566f415fa7
555 changed files with 62704 additions and 0 deletions

View File

@@ -0,0 +1,157 @@
import { Injectable } from '@nestjs/common';
import { CommandBus, QueryBus } from '@nestjs/cqrs';
import {
ActivityReadModel,
IssueDetails,
IssueLinkType,
IssueReadModel,
IssueStatus,
IssueType,
} from '@task-stream/api/tracker/domain';
import { AssignIssueCommand } from './commands/assign-issue.command';
import { ChangeIssueStatusCommand } from './commands/change-issue-status.command';
import { CommandResult } from './commands/command-result';
import { CreateIssueCommand } from './commands/create-issue.command';
import { LinkIssuesCommand } from './commands/link-issues.command';
import { SetIssueReleaseCommand } from './commands/set-issue-release.command';
import { UnlinkIssuesCommand } from './commands/unlink-issues.command';
import { UpdateIssueCommand } from './commands/update-issue.command';
import { IssueFilter, Page } from './ports/find-issues.repository';
import { GetActivityQuery } from './queries/get-activity.query';
import { GetIssueQuery } from './queries/get-issue.query';
import { GetIssuesByIdsQuery } from './queries/get-issues-by-ids.query';
import { SearchIssuesQuery } from './queries/search-issues.query';
export interface CreateIssueInput extends Omit<IssueDetails, 'title' | 'type'> {
projectId: string;
type: IssueType;
title: string;
assigneeId?: string | null;
releaseId?: string | null;
}
export interface IssueLinkInput {
issueId: string;
type: IssueLinkType;
targetIssueId: string;
}
@Injectable()
export class IssuesService {
constructor(
private readonly commandBus: CommandBus,
private readonly queryBus: QueryBus,
) {}
create(actorId: string, input: CreateIssueInput): Promise<CommandResult> {
const { projectId, type, title, assigneeId, releaseId, ...details } = input;
return this.commandBus.execute(
new CreateIssueCommand(
actorId,
projectId,
type,
title,
details,
assigneeId,
releaseId,
),
);
}
update(
actorId: string,
issueId: string,
changes: IssueDetails,
): Promise<CommandResult> {
return this.commandBus.execute(
new UpdateIssueCommand(actorId, issueId, changes),
);
}
changeStatus(
actorId: string,
issueId: string,
status: IssueStatus,
reason?: string | null,
): Promise<CommandResult> {
return this.commandBus.execute(
new ChangeIssueStatusCommand(actorId, issueId, status, reason),
);
}
/** @param assigneeId null to unassign */
assign(
actorId: string,
issueId: string,
assigneeId: string | null,
): Promise<CommandResult> {
return this.commandBus.execute(
new AssignIssueCommand(actorId, issueId, assigneeId),
);
}
link(actorId: string, input: IssueLinkInput): Promise<CommandResult> {
return this.commandBus.execute(
new LinkIssuesCommand(
actorId,
input.issueId,
input.type,
input.targetIssueId,
),
);
}
unlink(actorId: string, input: IssueLinkInput): Promise<CommandResult> {
return this.commandBus.execute(
new UnlinkIssuesCommand(
actorId,
input.issueId,
input.type,
input.targetIssueId,
),
);
}
/** @param releaseId null to take the ticket out of its release */
setRelease(
actorId: string,
issueId: string,
releaseId: string | null,
): Promise<CommandResult> {
return this.commandBus.execute(
new SetIssueReleaseCommand(actorId, issueId, releaseId),
);
}
findOne(viewerId: string, idOrKey: string): Promise<IssueReadModel> {
return this.queryBus.execute(new GetIssueQuery(viewerId, idOrKey));
}
findMany(viewerId: string, ids: string[]): Promise<IssueReadModel[]> {
return this.queryBus.execute(new GetIssuesByIdsQuery(viewerId, ids));
}
search(viewerId: string, filter: IssueFilter): Promise<Page<IssueReadModel>> {
return this.queryBus.execute(new SearchIssuesQuery(viewerId, filter));
}
activity(
viewerId: string,
params: {
projectId: string;
issueId?: string;
limit?: number;
before?: string;
},
): Promise<ActivityReadModel[]> {
return this.queryBus.execute(
new GetActivityQuery(
viewerId,
params.projectId,
params.issueId,
params.limit,
params.before,
),
);
}
}