import { Injectable } from '@nestjs/common'; import { IssuesService, ProjectsService, } from '@task-stream/api/tracker/application'; import { IssueReadModel, IssueWorkflow } from '@task-stream/api/tracker/domain'; const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; /** * REST routes accept a project or ticket by id or by key (`WEB`, `WEB-12`), * which is what other apps usually have. Keys are looked up in the read model; * ids go straight to the command (the service still checks membership). */ @Injectable() export class Refs { constructor( private readonly projects: ProjectsService, private readonly issues: IssuesService, ) {} async projectId(viewerId: string, ref: string): Promise { if (UUID.test(ref)) return ref; return (await this.projects.findOne(viewerId, ref)).id; } async issueId(viewerId: string, ref: string): Promise { if (UUID.test(ref)) return ref; return (await this.issues.findOne(viewerId, ref)).id; } } /** The ticket as the REST API returns it: read model + allowed transitions. */ export function toIssueDto(issue: IssueReadModel) { return { ...issue, allowedTransitions: IssueWorkflow.allowedFrom(issue.status), }; }