Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add seen/delete notifications #38

Open
wants to merge 7 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions backend/typescript/graphql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ import authType from "./types/authType";
import entityResolvers from "./resolvers/entityResolvers";
import entityType from "./types/entityType";
import simpleEntityResolvers from "./resolvers/simpleEntityResolvers";
import adminResolvers from "./resolvers/adminResolvers";
import adminResolvers from "./resolvers/notificationResolvers";
import simpleEntityType from "./types/simpleEntityType";
import userResolvers from "./resolvers/userResolvers";
import userType from "./types/userType";
import staffType from "./types/staffType";
import staffResolver from "./resolvers/staffResolver";
import adminType from "./types/adminType";
import adminType from "./types/notificationType";
import residentResolvers from "./resolvers/residentResolvers";
import residentType from "./types/residentType";
import taskResolvers from "./resolvers/taskResolvers";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import AdminService from "../../services/implementations/adminService";
import AdminService from "../../services/implementations/notificationService";
import {
IAdminService,
NotificationDTO,
} from "../../services/interfaces/adminService";
} from "../../services/interfaces/notificationService";

const adminService: IAdminService = new AdminService();

Expand Down Expand Up @@ -45,6 +45,32 @@ const adminResolvers = {
);
return newAnnouncement;
},
deleteNotificationForResident: async (
_parent: undefined,
{
notificationId,
residentId,
}: { notificationId: number; residentId: number },
): Promise<NotificationDTO> => {
const updatedNotification = await adminService.deleteNotificationForResident(
Number(notificationId),
Number(residentId),
);
return updatedNotification;
},
updateSeenForResident: async (
_parent: undefined,
{
notificationId,
residentId,
}: { notificationId: number; residentId: number },
): Promise<NotificationDTO> => {
const updatedNotification = await adminService.updateSeenForResident(
Number(notificationId),
Number(residentId),
);
return updatedNotification;
},
},
};
export default adminResolvers;
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ const adminType = gql`
id: ID!
authorId: ID!
message: String!
createdAt: String!
createdAt: DateTime!
residents: [NotificationResidentDTO!]
}

type NotificationResidentDTO {
notificationId: ID!
residentId: ID!
seen: Boolean!
isDeleted: Boolean!
}

extend type Query {
Expand All @@ -22,11 +23,19 @@ const adminType = gql`

extend type Mutation {
sendNotification(
message: String
residentId: ID
staffId: ID
message: String!
residentId: ID!
staffId: ID!
): NotificationDTO!
sendAnnouncement(message: String!, staffId: ID!): NotificationDTO!
deleteNotificationForResident(
notificationId: ID!
residentId: ID!
): NotificationDTO!
updateSeenForResident(
notificationId: ID!
residentId: ID!
): NotificationDTO!
sendAnnouncement(message: String, staffId: ID): NotificationDTO!
}
`;

Expand Down
1 change: 1 addition & 0 deletions backend/typescript/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ model notificationResident {
resident resident @relation(fields: [residentId], references: [id])
residentId Int @map("resident_id")
seen Boolean @default(false)
isDeleted Boolean @default(false)

@@id([notificationId, residentId])
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import prisma from "../../prisma";
import type {
IAdminService,
NotificationDTO,
} from "../interfaces/adminService";
} from "../interfaces/notificationService";
import logger from "../../utilities/logger";
import { getErrorMessage } from "../../utilities/errorUtils";
import { IResidentService } from "../interfaces/residentService";
Expand Down Expand Up @@ -126,5 +126,81 @@ class AdminService implements IAdminService {
throw error;
}
}

async deleteNotificationForResident(
notificationId: number,
residentId: number,
): Promise<NotificationDTO> {
try {
await prisma.notificationResident.update({
where: {
notificationId_residentId: {
notificationId,
residentId,
},
},
data: {
isDeleted: true,
},
});

const updatedNotification = await prisma.notification.findUnique({
where: {
id: notificationId,
},
include: {
residents: true,
},
});

if (!updatedNotification)
throw new Error(`notification id ${notificationId} not found`);

return updatedNotification;
} catch (error) {
Logger.error(
`Failed to set isDelete flag. Reason = ${getErrorMessage(error)}`,
);
throw error;
}
}

async updateSeenForResident(
notificationId: number,
residentId: number,
): Promise<NotificationDTO> {
try {
await prisma.notificationResident.update({
where: {
notificationId_residentId: {
notificationId,
residentId,
},
},
data: {
seen: true,
},
});

const updatedNotification = await prisma.notification.findUnique({
where: {
id: notificationId,
},
include: {
residents: true,
},
});

if (!updatedNotification)
throw new Error(`notification id ${notificationId} not found`);

return updatedNotification;
} catch (error) {
Logger.error(
`Failed to set seen flag. Reason = ${getErrorMessage(error)}`,
);
throw error;
}
}
}
export default AdminService;
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface NotificationResidentDTO {
notificationId: number;
residentId: number;
seen: boolean;
isDeleted: boolean;
}

export interface IAdminService {
Expand All @@ -23,8 +24,9 @@ export interface IAdminService {

/**
* Post a notification to the specified resident
* @param notif_obj notification id
* @param resident_id resident id
* @param notifMessage notification message that is to be sent
* @param residentId resident id
* @param staffId staff id
* @returns a NotificationDTO associated with the posted notification
* @throws Error if creation fails
*/
Expand All @@ -37,18 +39,43 @@ export interface IAdminService {
/**
* Post a notification to the specified resident
* @returns a list of NotificationDTOs containing all notifications/ announcements
* @throws Error if creation fails
* @throws Error if retrieval fails
*/
getAllNotifications(): Promise<NotificationDTO[]>;

/**
* Post the announcement notif_obj to all active residents
* @param notif_obj notification
* Post the announcement notifMessage to all active residents
* @param notifMessage notification message that is to be sent
* @param staffId staff id
* @returns the new updated NotificationDTO
* @throws Error if creation fails
*/
sendAnnouncement(
notifMessage: string,
staffId: number,
): Promise<NotificationDTO>;

/**
* set a notification with notifId id to isDeleted for resident with id residentId
* @param notifId notification id
* @param residentId resident id
* @returns updated NotificationDTO with the isDeleted flag set to true for resident associated with residentId
* @throws Error if update fails
*/
deleteNotificationForResident(
notificationId: number,
residentId: number,
): Promise<NotificationDTO>;

/**
* update the seen flag of notification notifId for resident residentId
* @param notifId notification id
* @param residentId resident id
* @returns updated NotificationDTO with the seen flag set to true for resident associated with residentId
* @throws Error if update fails
*/
updateSeenForResident(
notificationId: number,
residentId: number,
): Promise<NotificationDTO>;
}
2 changes: 1 addition & 1 deletion backend/typescript/services/interfaces/residentService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NotificationResidentDTO } from "./adminService";
import { NotificationResidentDTO } from "./notificationService";

export interface ResidentDTO {
id: number;
Expand Down
2 changes: 1 addition & 1 deletion backend/typescript/services/interfaces/staffService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NotificationDTO } from "./adminService";
import { NotificationDTO } from "./notificationService";

export interface StaffDTO {
id: number;
Expand Down
Loading