Files
ulitka/src/modules/comment/application/services/comment-expander.service.ts
T
vadimandClaude Opus 5.5 60fb39f98f Add attachments to comments
- CommentAttachment link table (comment <-> file) + migration
- fileIds in create/update comment; update replaces the whole set,
  synced in one transaction with the comment
- CommentDto.attachments; empty for deleted comments
- Soft delete drops attachments so GC can collect the files
- Max 10 files per comment, ordered by upload time (uuid v7)
- Registers comments as a file owner
- Rename CommentAuthorExpanderService -> CommentExpanderService
  (expands authors and files)

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

39 lines
1.8 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { Comment } from '../../domain/entities/comment.entity.js';
import { CommentDto } from '../dto/comment.dto.js';
import { CommentApplicationMapper } from '../mappers/comment-application.mapper.js';
import { GetUsersUseCase } from '../../../user/application/use-cases/get-users/get-users.use-case.js';
import { GetUsersQuery } from '../../../user/application/use-cases/get-users/get-users.query.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';
/** Раскрывает автора и вложения комментария (или списка комментариев) */
@Injectable()
export class CommentExpanderService {
constructor(
private readonly getUsersUseCase: GetUsersUseCase,
private readonly getFilesUseCase: GetFilesUseCase,
) {}
async expand(comment: Comment): Promise<CommentDto> {
const [dto] = await this.expandAll([comment]);
return dto!;
}
async expandAll(comments: Comment[]): Promise<CommentDto[]> {
if (comments.length === 0) return [];
const userIds = [...new Set(comments.map((comment) => comment.authorId).filter((id): id is string => Boolean(id)))];
const fileIds = comments.flatMap((comment) => comment.fileIds);
const [users, files] = await Promise.all([
userIds.length > 0 ? this.getUsersUseCase.execute(new GetUsersQuery(userIds)) : [],
fileIds.length > 0 ? this.getFilesUseCase.execute(new GetFilesQuery(fileIds)) : [],
]);
const usersById = new Map(users.map((user) => [user.id, user]));
const filesById = new Map(files.map((file) => [file.id, file]));
return comments.map((comment) => CommentApplicationMapper.toDto(comment, usersById, filesById));
}
}