Files
task-stream/libs/api/tracker/application/src/lib/automations.service.ts
Josep Piguillem 1550332d41 refactor(api): buses only in services, atomic commands, @Prop schemas
- Mongo read models are @Schema/@Prop classes (SchemaFactory), still
  loose: the props declared are the indexed or shaped ones.
- CommandBus and QueryBus are used by the application services alone.
  Duplicating a ticket, bulk updates, CSV imports, proposals and
  emptying the trash chain several commands, so they are service
  methods now and their composite commands are gone; every command
  handler is atomic. No forwardRef is needed.
- The due-date and trash timers are entry points: they live in the
  presenters and call the services. The automations event handler has
  its own file and calls AutomationsService.
- The tracker's user directory asks IdentityService; the composition
  root hands the identity application module to the tracker
  infrastructure (withIdentity), with no global module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 19:56:59 +02:00

58 lines
1.6 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { CommandBus, QueryBus } from '@nestjs/cqrs';
import {
AutomationInput,
CreateAutomationCommand,
DeleteAutomationCommand,
GetAutomationsQuery,
RunAutomationCommand,
UpdateAutomationCommand,
} from './automations/automations';
import { Automation } from './ports/automations.repository';
/** The project's automation rules (owners and admins). */
@Injectable()
export class AutomationsService {
constructor(
private readonly commandBus: CommandBus,
private readonly queryBus: QueryBus,
) {}
list(viewerId: string, projectId: string): Promise<Automation[]> {
return this.queryBus.execute(new GetAutomationsQuery(viewerId, projectId));
}
create(
actorId: string,
projectId: string,
rule: AutomationInput,
): Promise<Automation> {
return this.commandBus.execute(
new CreateAutomationCommand(actorId, projectId, rule),
);
}
update(
actorId: string,
automationId: string,
changes: { name?: string; active?: boolean },
): Promise<Automation> {
return this.commandBus.execute(
new UpdateAutomationCommand(actorId, automationId, changes),
);
}
/** Runs a rule on a ticket; the error, if any, as text. */
run(automation: Automation, issueId: string): Promise<string | null> {
return this.commandBus.execute(
new RunAutomationCommand(automation, issueId),
);
}
delete(actorId: string, automationId: string): Promise<void> {
return this.commandBus.execute(
new DeleteAutomationCommand(actorId, automationId),
);
}
}