- 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>
39 lines
1.8 KiB
TypeScript
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));
|
|
}
|
|
}
|