import { Args, ID, Resolver, Subscription } from '@nestjs/graphql'; import { User } from '@task-stream/api/identity/domain'; import { CurrentUser } from '@task-stream/api/identity/presenters'; import { ChangesService, NotificationsService, } from '@task-stream/api/tracker/application'; import { ActivityGql, CommentChangeGql, IssueChangeGql, NotificationGql, ProjectChangeGql, ReleaseChangeGql, SprintChangeGql, TypingGql, } from './types'; const asIs = { resolve: (payload: T) => payload }; /** * Realtime API (graphql-ws). Events are emitted after the read model is * updated, so a client can refetch and always see the new state. */ @Resolver() export class SubscriptionResolver { constructor( private readonly changes: ChangesService, private readonly notifications: NotificationsService, ) {} @Subscription(() => IssueChangeGql, { ...asIs, description: 'Tickets created/updated/moved in a project (board in realtime)', }) issueChanged( @CurrentUser() me: User, @Args('projectId', { type: () => ID }) projectId: string, ) { return this.changes.watchIssues(me.id, projectId); } @Subscription(() => CommentChangeGql, asIs) commentChanged( @CurrentUser() me: User, @Args('issueId', { type: () => ID }) issueId: string, ) { return this.changes.watchComments(me.id, issueId); } @Subscription(() => TypingGql, { ...asIs, description: "Who is writing on a ticket, as they type (one's own come too: leave them out)", }) typing( @CurrentUser() me: User, @Args('issueId', { type: () => ID }) issueId: string, ) { return this.changes.watchTyping(me.id, issueId); } @Subscription(() => ActivityGql, { ...asIs, description: 'Live activity feed', }) activityAdded( @CurrentUser() me: User, @Args('projectId', { type: () => ID }) projectId: string, ) { return this.changes.watchActivity(me.id, projectId); } @Subscription(() => ReleaseChangeGql, asIs) releaseChanged( @CurrentUser() me: User, @Args('projectId', { type: () => ID }) projectId: string, ) { return this.changes.watchReleases(me.id, projectId); } @Subscription(() => SprintChangeGql, asIs) sprintChanged( @CurrentUser() me: User, @Args('projectId', { type: () => ID }) projectId: string, ) { return this.changes.watchSprints(me.id, projectId); } @Subscription(() => ProjectChangeGql, asIs) projectChanged( @CurrentUser() me: User, @Args('projectId', { type: () => ID }) projectId: string, ) { return this.changes.watchProject(me.id, projectId); } @Subscription(() => ProjectChangeGql, { ...asIs, description: 'Projects I am added to / removed from', }) myProjectsChanged(@CurrentUser() me: User) { return this.changes.watchMyProjects(me.id); } @Subscription(() => NotificationGql, { ...asIs, description: 'My notifications, as they happen', }) notificationAdded(@CurrentUser() me: User) { return this.notifications.watch(me.id); } }