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>
28 lines
1.1 KiB
TypeScript
28 lines
1.1 KiB
TypeScript
import { guestOnly } from './read-access';
|
|
import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
|
|
import { ReleaseReadModel } from '@task-stream/api/tracker/domain';
|
|
import { FindProjectsRepository } from '../ports/find-projects.repository';
|
|
import { FindReleasesRepository } from '../ports/find-releases.repository';
|
|
import { GetUpcomingReleasesQuery } from './get-upcoming-releases.query';
|
|
|
|
@QueryHandler(GetUpcomingReleasesQuery)
|
|
export class GetUpcomingReleasesQueryHandler
|
|
implements IQueryHandler<GetUpcomingReleasesQuery, ReleaseReadModel[]>
|
|
{
|
|
constructor(
|
|
private readonly findProjects: FindProjectsRepository,
|
|
private readonly findReleases: FindReleasesRepository,
|
|
) {}
|
|
|
|
async execute(query: GetUpcomingReleasesQuery): Promise<ReleaseReadModel[]> {
|
|
const projects = await this.findProjects.findByMember(query.viewerId);
|
|
// A guest does not see a private project's releases.
|
|
return this.findReleases.findUpcoming(
|
|
projects
|
|
.filter((project) => !guestOnly(project, query.viewerId))
|
|
.map((project) => project.id),
|
|
Math.min(query.limit, 50),
|
|
);
|
|
}
|
|
}
|