Files
ulitka/src/modules/issue-attachment/application/services/issue-attachment-expander.service.ts
T
vadimandClaude Opus 5.5 423afa658d Add issue attachments
- IssueAttachment link table (issue <-> file) + migration
- GET/POST /issues/:issueId/attachments, DELETE .../attachments/:fileId
- Only own uploaded files can be attached; attach is idempotent
- Registers issues as a file owner: attached files stay visible to issue
  participants and are not collected by GC
- IssueDetail.attachments GraphQL field via @ResolveField, issue module untouched

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 09:18:02 +03:00

25 lines
1.3 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { IssueAttachment } from '../../domain/entities/issue-attachment.entity.js';
import { IssueAttachmentDto } from '../dto/issue-attachment.dto.js';
import { GetFilesUseCase } from '../../../file/application/use-cases/get-files/get-files.use-case.js';
import { GetFilesQuery } from '../../../file/application/use-cases/get-files/get-files.query.js';
/** Раскрывает вложения в метаданные файлов из file-модуля */
@Injectable()
export class IssueAttachmentExpanderService {
constructor(private readonly getFilesUseCase: GetFilesUseCase) {}
async expandAll(attachments: IssueAttachment[]): Promise<IssueAttachmentDto[]> {
if (attachments.length === 0) return [];
const files = await this.getFilesUseCase.execute(new GetFilesQuery(attachments.map((a) => a.fileId)));
const filesById = new Map(files.map((file) => [file.id, file]));
// Файл могли удалить между запросами — такое вложение просто не показываем
return attachments.flatMap((attachment) => {
const file = filesById.get(attachment.fileId);
return file ? [{ issueId: attachment.issueId, file, attachedAt: attachment.createdAt }] : [];
});
}
}