Files
ulitka/src/modules/issue/application/use-cases/unobserve-issue/unobserve-issue.use-case.ts
T
vadimandClaude Opus 5.5 b1f6b61994
Gitea Actions / Deploy (push) Canceled after 5m13s
create issues fix
issue observers

Наблюдатели задачи видят её и комментируют, но не редактируют.

- таблица issue_observer, наблюдатели — часть сущности Issue
- видимость: reporter, assignee или наблюдатель (задачи, история, SSE)
- правка/удаление задачи и вложений — только reporter/assignee (403 наблюдателю)
- observers в create/update, DELETE /issues/:id/observers/me, фильтр role
- история изменений и уведомления новым наблюдателям

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 22:23:49 +03:00

36 lines
1.5 KiB
TypeScript

import { Inject, Injectable } from '@nestjs/common';
import { ISSUE_REPOSITORY, type IIssueRepository } from '../../../domain/repositories/issue.repository.interface.js';
import { IssueNotFoundException } from '../../../domain/exceptions/issue-not-found.exception.js';
import { IssueEventsService } from '../../services/issue-events.service.js';
import { IssueApplicationMapper } from '../../mappers/issue-application.mapper.js';
import { UnobserveIssueCommand } from './unobserve-issue.command.js';
/**
* Наблюдатель сам отписывается от задачи. Редактировать задачу он не может,
* поэтому это отдельная операция, а не часть UpdateIssueUseCase.
* Повторный вызов (или вызов не наблюдателем) ничего не меняет.
*/
@Injectable()
export class UnobserveIssueUseCase {
constructor(
@Inject(ISSUE_REPOSITORY)
private readonly issueRepository: IIssueRepository,
private readonly issueEventsService: IssueEventsService,
) {}
async execute(command: UnobserveIssueCommand): Promise<void> {
const issue = await this.issueRepository.findById(command.id, command.userId);
if (!issue) {
throw new IssueNotFoundException(command.id);
}
if (!issue.observers.includes(command.userId)) return;
issue.removeObserver(command.userId);
await this.issueRepository.update(issue, command.userId);
this.issueEventsService.emitIssueUpdated(IssueApplicationMapper.toDto(issue));
}
}