Skip to content

Commit 9224530

Browse files
Johan BookJohan Book
Johan Book
authored and
Johan Book
committed
feat(api): add notification entityt
1 parent deff9ee commit 9224530

File tree

9 files changed

+143
-8
lines changed

9 files changed

+143
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export class NotificationDetails {
2+
id!: string;
3+
resourcePath!: string;
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { BaseQuery } from "src/core/query";
2+
3+
export class GetNotificationListQuery extends BaseQuery {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { IQueryHandler, QueryHandler } from "@nestjs/cqrs";
2+
import { InjectRepository } from "@nestjs/typeorm";
3+
import { Repository } from "typeorm";
4+
5+
import { mapArray } from "src/core/mapper";
6+
import { QueryService } from "src/core/query";
7+
import { CurrentOrganizationService } from "src/features/organizations";
8+
import { CurrentProfileService } from "src/features/profiles";
9+
10+
import { Notification } from "../../../infrastructure/entities/notification.entity";
11+
import { NotificationDetails } from "../../contracts/dtos/notification.dto";
12+
import { GetNotificationListQuery } from "../../contracts/queries/get-notification-list.query";
13+
14+
@QueryHandler(GetNotificationListQuery)
15+
export class GetNotificationListHandler
16+
implements IQueryHandler<GetNotificationListQuery, NotificationDetails[]>
17+
{
18+
constructor(
19+
private readonly currentOrganizationService: CurrentOrganizationService,
20+
private readonly currentProfileService: CurrentProfileService,
21+
@InjectRepository(Notification)
22+
private readonly notifications: Repository<Notification>,
23+
private readonly queryService: QueryService<Notification>,
24+
) {}
25+
26+
async execute(query: GetNotificationListQuery) {
27+
const organizationId =
28+
await this.currentOrganizationService.fetchCurrentOrganizationId();
29+
const profileId = await this.currentProfileService.fetchCurrentProfileId();
30+
31+
const fountNotifications = await this.queryService.find(
32+
this.notifications,
33+
{
34+
required: {
35+
where: {
36+
organizationId,
37+
profileId,
38+
},
39+
},
40+
query,
41+
},
42+
);
43+
44+
return mapArray(
45+
NotificationDetails,
46+
fountNotifications,
47+
(notification) => ({
48+
id: notification.id,
49+
resourcePath: notification.resourcePath,
50+
}),
51+
);
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Controller, Get, Query } from "@nestjs/common";
2+
import { QueryBus } from "@nestjs/cqrs";
3+
import { ApiTags } from "@nestjs/swagger";
4+
5+
import { NotificationDetails } from "../../application/contracts/dtos/notification.dto";
6+
import { GetNotificationListQuery } from "../../application/contracts/queries/get-notification-list.query";
7+
8+
@Controller("notifications")
9+
@ApiTags("notifications")
10+
export class NotificationsController {
11+
constructor(private queryBus: QueryBus) {}
12+
13+
@Get()
14+
async getNotifactions(
15+
@Query() query: GetNotificationListQuery,
16+
): Promise<NotificationDetails[]> {
17+
return await this.queryBus.execute(query);
18+
}
19+
}

services/api/src/core/notifications/notification.service.ts renamed to services/api/src/core/notifications/domain/services/notification.service.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import { InjectRepository } from "@nestjs/typeorm";
33
import { In, Not, Repository } from "typeorm";
44

55
import { UserIdService } from "src/core/authentication";
6+
import { EmailService } from "src/core/email/domain/services/email.service";
67
import { Logger } from "src/core/logging";
78
import { OrganizationMembership } from "src/features/organizations/infrastructure/entities/organization-membership.entity";
89
import { Profile } from "src/features/profiles";
910
import { getRequiredStringConfig } from "src/utils/config.helper";
1011

11-
import { EmailService } from "../email/domain/services/email.service";
12-
import { NotificationGateway } from "./notification.gateway";
13-
import { INotification } from "./types";
12+
import { NotificationGateway } from "../../notification.gateway";
13+
import { INotification } from "../../types";
1414

1515
const UI_DOMAIN = getRequiredStringConfig("UI_DOMAIN");
1616

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export { NotificationEventsConstants } from "./constants/notification-events.constants";
2-
export { NotificationService } from "./notification.service";
2+
export { NotificationService } from "./domain/services/notification.service";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Column, Entity, ManyToOne } from "typeorm";
2+
3+
import { BaseEntity } from "src/core/database";
4+
import { Organization } from "src/features/organizations";
5+
import { Profile } from "src/features/profiles";
6+
7+
@Entity()
8+
export class Notification extends BaseEntity {
9+
@Column({ type: "varchar", length: 4096, default: "" })
10+
description!: string;
11+
12+
@Column({ type: "varchar", length: 2048, default: "" })
13+
message!: string;
14+
15+
@ManyToOne(() => Organization)
16+
organization!: Organization;
17+
18+
@Column()
19+
organizationId!: number;
20+
21+
@ManyToOne(() => Profile)
22+
profile!: Profile;
23+
24+
@Column()
25+
profileId!: number;
26+
27+
@Column()
28+
read!: boolean;
29+
30+
@Column({
31+
type: "timestamp without time zone",
32+
})
33+
readAt!: Date;
34+
35+
@Column({ type: "varchar", length: 2048, default: "" })
36+
resourcePath!: string;
37+
38+
@Column({ type: "varchar", length: 256, default: "" })
39+
type!: string;
40+
}
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,37 @@
11
import { Module } from "@nestjs/common";
2+
import { CqrsModule } from "@nestjs/cqrs";
23
import { TypeOrmModule } from "@nestjs/typeorm";
34

45
import { EmailModule } from "src/core/email/email.module";
56
import { OrganizationMembership } from "src/features/organizations/infrastructure/entities/organization-membership.entity";
7+
import { OrganizationModule } from "src/features/organizations/organization.module";
68
import { Profile } from "src/features/profiles";
9+
import { ProfileModule } from "src/features/profiles/profile.module";
710

811
import { AuthenticationModule } from "../authentication/authentication.module";
12+
import { QueryModule } from "../query/query.module";
13+
import { GetNotificationListHandler } from "./application/handlers/query-handlers/get-notification-list.handler";
14+
import { NotificationsController } from "./client/controllers/notifications.controller";
15+
import { NotificationService } from "./domain/services/notification.service";
16+
import { Notification } from "./infrastructure/entities/notification.entity";
917
import { NotificationGateway } from "./notification.gateway";
10-
import { NotificationService } from "./notification.service";
1118

1219
@Module({
20+
controllers: [NotificationsController],
1321
exports: [NotificationService],
1422
imports: [
1523
AuthenticationModule,
24+
CqrsModule,
1625
EmailModule,
17-
TypeOrmModule.forFeature([OrganizationMembership, Profile]),
26+
OrganizationModule,
27+
ProfileModule,
28+
QueryModule,
29+
TypeOrmModule.forFeature([Notification, OrganizationMembership, Profile]),
30+
],
31+
providers: [
32+
NotificationGateway,
33+
GetNotificationListHandler,
34+
NotificationService,
1835
],
19-
providers: [NotificationGateway, NotificationService],
2036
})
2137
export class NotificationModule {}

services/api/src/core/notifications/test/mocks/notification.service.mock.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { NotificationService } from "../../notification.service";
1+
import { NotificationService } from "../../domain/services/notification.service";
22

33
/* eslint-disable unicorn/consistent-function-scoping */
44

0 commit comments

Comments
 (0)