comments implement

This commit is contained in:
vadim committed 2026-10-01 12:02:03 +03:00
1 parent 9e0bef2527
commit 4b6ecfbf5d
41 files changed
+1350 -13

No files matched your search

@@ -0,0 +1,46 @@
import {
BadRequestException,
type CanActivate,
type ExecutionContext,
Injectable,
NotFoundException,
UnauthorizedException,
} from '@nestjs/common';
import type { UserSession } from '@thallesp/nestjs-better-auth';
import { CommentAccessService } from '../../application/services/comment-access.service.js';
import { IssueNotFoundException } from '../../../issue/domain/exceptions/issue-not-found.exception.js';
/**
* Проверяет доступ к задаче из `:issueId` ДО вызова обработчика.
*
* Нужен SSE-эндпоинтам: при наличии глобального interceptor'а Nest вызывает
* @Sse-обработчик уже после отправки заголовков 200, и ошибка из него доходит
* до клиента только как `event: error`. Guard же отвечает честным 404.
*
* Сессию в request кладёт глобальный AuthGuard, который выполняется раньше.
*/
@Injectable()
export class IssueVisibleGuard implements CanActivate {
constructor(private readonly commentAccess: CommentAccessService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest<{ params: Record<string, string | undefined>; session?: UserSession }>();
const userId = request.session?.user.id;
if (!userId) {
throw new UnauthorizedException();
}
// Пайпы (ParseIntPipe) выполняются после guard'ов — парсим сами
const issueId = Number(request.params.issueId);
if (!Number.isInteger(issueId)) {
throw new BadRequestException('Validation failed (numeric string is expected)');
}
if (!(await this.commentAccess.isIssueVisible(issueId, userId))) {
throw new NotFoundException(new IssueNotFoundException(issueId).message);
}
return true;
}
}