feat: guest role for clients and outsiders
A project member can be a GUEST. In a private project a guest only sees the tickets they take part in (opened, assigned or followed): every other ticket answers 404, also in my work, realtime changes, blockers and linked tickets, and project-wide views (activity, statistics, dashboard, releases, sprints, epics, trash) answer 403. Guests open tickets without assigning or planning them, and comment, attach, follow and vote on their own; they change nothing else. In a public project they see what anyone does. The web gives them only Tablero, Lista and Miembros and loads none of the project-wide data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { NotFoundError } from '@task-stream/api/shared/domain';
|
||||
import { FindIssuesRepository } from '../ports/find-issues.repository';
|
||||
import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
|
||||
import { ActivityReadModel } from '@task-stream/api/tracker/domain';
|
||||
import { FindActivityRepository } from '../ports/find-activity.repository';
|
||||
@@ -11,10 +13,23 @@ export class GetActivityQueryHandler
|
||||
constructor(
|
||||
private readonly findActivity: FindActivityRepository,
|
||||
private readonly access: ReadAccess,
|
||||
private readonly findIssues: FindIssuesRepository,
|
||||
) {}
|
||||
|
||||
async execute(query: GetActivityQuery): Promise<ActivityReadModel[]> {
|
||||
await this.access.assertCanView(query.projectId, query.viewerId);
|
||||
// A ticket's history goes with the ticket; the project's feed is for
|
||||
// whoever sees the whole project (not a guest).
|
||||
if (query.issueId) {
|
||||
const issue = this.access.assertFound(
|
||||
await this.findIssues.findById(query.issueId),
|
||||
'Issue',
|
||||
query.issueId,
|
||||
);
|
||||
if (issue.projectId !== query.projectId)
|
||||
throw new NotFoundError('Issue', query.issueId);
|
||||
await this.access.assertCanViewIssue(issue, query.viewerId);
|
||||
} else
|
||||
await this.access.assertSeesWholeProject(query.projectId, query.viewerId);
|
||||
return this.findActivity.find({
|
||||
projectId: query.projectId,
|
||||
issueId: query.issueId,
|
||||
|
||||
Reference in New Issue
Block a user