Skip to content

Commit

Permalink
Merge pull request #126 from uwblueprint/kathleen-megan/announcement-…
Browse files Browse the repository at this point in the history
…full-functionality

Kathleen megan/announcement full functionality
  • Loading branch information
applepie7864 authored Feb 2, 2025
2 parents 04d474c + e2e9945 commit 8959188
Show file tree
Hide file tree
Showing 8 changed files with 558 additions and 165 deletions.
63 changes: 62 additions & 1 deletion backend/services/implementations/notificationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,65 @@ class NotificationService implements INotificationService {
roomIds: number[],
): Promise<NotificationGroupDTO> {
try {
if (roomIds.length === 0) {
throw Object.assign(new Error("No rooms specified."), { code: 400 });
}
if (roomIds.length > 1) {
// enforces that a group can only have one member
// remove in the future if the requirements change
throw Object.assign(
new Error("Notification Group can only have one room."),
{ code: 400 },
);
}
const residents = await prisma.resident.findMany({
where: { roomNumber: { in: roomIds } },
});
if (residents.length !== roomIds.length) {
throw Object.assign(new Error("Room id does not exist."), {
code: 400,
});
}
const residentIds = residents.map((resident) => resident.userId);

const existingGroup = await prisma.notificationGroup.findMany({
where: {
announcementGroup: false,
recipients: {
every: {
userId: { in: residentIds },
},
},
},
include: {
recipients: true,
},
});

if (existingGroup && existingGroup.length > 0) {
// throw error if residents match
existingGroup.forEach((group) => {
if (group.recipients.length === residentIds.length) {
throw Object.assign(
new Error(
"Notification Group already exists with specified roomIds.",
),
{ code: 400 },
);
}
});
}

const newNotificationGroup = await prisma.notificationGroup.create({
data: {
recipients: {
connect: residentIds.map((id) => ({ userId: id })),
},
announcementGroup: false,
},
include: {
recipients: true,
},
});

return newNotificationGroup;
Expand All @@ -50,6 +97,17 @@ class NotificationService implements INotificationService {

async createAnnouncementGroup(): Promise<NotificationGroupDTO> {
try {
const existingGroup = await prisma.notificationGroup.findMany({
where: {
announcementGroup: true,
},
});
if (existingGroup && existingGroup.length > 0) {
throw Object.assign(new Error("Announcement Group already exists."), {
code: 400,
});
}

const residents = await prisma.resident.findMany({
where: { dateLeft: null },
});
Expand All @@ -62,6 +120,9 @@ class NotificationService implements INotificationService {
},
announcementGroup: true,
},
include: {
recipients: true,
},
});

return newNotificationGroup;
Expand Down Expand Up @@ -143,7 +204,7 @@ class NotificationService implements INotificationService {
try {
const notificationGroups = await prisma.notificationGroup.findMany({
include: {
// recipients: true, // TODO: resident type is incompatiable at time of writing
recipients: true,
notifications: true,
},
});
Expand Down
100 changes: 67 additions & 33 deletions frontend/src/APIClients/Mutations/NotificationMutations.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,92 @@
import { gql } from "@apollo/client";

export const SEND_NOTIFICATION = gql`
mutation SendNotification(
$authorId: ID!
$title: String!
$message: String!
$recipientIds: [ID!]
) {
sendNotification(
authorId: $authorId
title: $title
message: $message
recipientIds: $recipientIds
) {
export const CREATE_NOTIFICATION_GROUP = gql`
mutation CreateNotificationGroup($roomIds: [Int!]) {
createNotificationGroup(roomIds: $roomIds) {
id
authorId
title
message
createdAt
announcementGroup
recipients {
userId
residentId
roomNumber
credits
dateJoined
dateLeft
}
}
}
`;

export const DELETE_USER_NOTIFICATION = gql`
mutation DeleteUserNotification($notificationId: ID!) {
deleteUserNotification(notificationId: $notificationId) {
export const CREATE_ANNOUNCEMENT_GROUP = gql`
mutation CreateAnnouncementGroup {
createAnnouncementGroup {
id
announcementGroup
recipients {
userId
residentId
roomNumber
credits
dateJoined
dateLeft
}
}
}
`;

export const SEND_NOTIFICATION_TO_GROUP = gql`
mutation SendNotificationToGroup(
$groupId: ID!
$notification: CreateNotificationDTO!
) {
sendNotificationToGroup(groupId: $groupId, notification: $notification) {
id
authorId
title
message
createdAt
authorId
}
}
`;

export const UPDATE_SEEN_NOTIFICATION = gql`
mutation UpdateSeenNotification($notificationId: ID!) {
updateSeenNotification(notificationId: $notificationId) {
export const DELETE_NOTIFICATION_GROUP = gql`
mutation DeleteNotificationGroup($groupId: ID!) {
deleteNotificationGroup(groupId: $groupId) {
id
notificationId
recipientId
seen
announcementGroup
}
}
`;

export const SEND_ANNOUNCEMENT = gql`
mutation SendAnnouncement($title: String, $message: String, $userId: ID) {
sendAnnouncement(title: $title, message: $message, userId: $userId) {
export const UPDATE_NOTIFICATION_BY_ID = gql`
mutation UpdateNotificationById(
$notificationId: ID!
$notification: UpdateNotificationDTO!
) {
updateNotificationById(
notificationId: $notificationId
notification: $notification
) {
id
authorId
title
message
createdAt
authorId
}
}
`;

export const DELETE_NOTIFICATION_BY_IDS = gql`
mutation DeleteNotificationByIds($notificationIds: [ID!]) {
deleteNotificationByIds(notificationIds: $notificationIds)
}
`;

export const UPDATE_SEEN_NOTIFICATION = gql`
mutation UpdateSeenNotification($notificationSeenId: ID!) {
updateSeenNotification(notificationSeenId: $notificationSeenId) {
id
notificationId
recipientId
seen
}
}
`;
47 changes: 41 additions & 6 deletions frontend/src/APIClients/Queries/NotificationQueries.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,58 @@
import { gql } from "@apollo/client";

export const GET_NOTIFICATIONS_BY_USER_ID = gql`
query GetNotificationsByUserId($userId: ID!) {
getNotificationsByUserId(userId: $userId) {
export const GET_NOTIFICATIONS_BY_IDS = gql`
query getNotificationsByIds($notificationIds: [ID!]) {
getNotificationsByIds(notificationIds: $notificationIds) {
id
notificationId
recipientId
seen
notification {
id
message
createdAt
authorId
}
}
}
`;

export const GET_NOTIFCATION_BY_ID = gql`
query GetNotificationById($id: ID!) {
getNotificationById(id: $id) {
export const GET_NOTIFCATION_BY_RESIDENT = gql`
query getNotificationByResident($residentId: ID!) {
getNotificationByResident(residentId: $id) {
id
notificationId
recipientId
seen
notification {
id
message
createdAt
authorId
}
}
}
`;

export const GET_ALL_GROUPS_AND_NOTIFICATIONS = gql`
query getAllGroupsAndNotifications {
getAllGroupsAndNotifications {
id
announcementGroup
notifications {
id
message
createdAt
authorId
}
recipients {
userId
residentId
roomNumber
credits
dateJoined
dateLeft
}
}
}
`;
29 changes: 25 additions & 4 deletions frontend/src/APIClients/Types/NotificationType.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
import { ResidentResponse } from "./ResidentsType";

export type NotificationResponse = {
id: string;
message: string;
createdAt?: Date;
authorId?: string;
title: string;
recipients?: NotificationReceivedResponse[];
};

export type NotificationCreateRequest = {
message: string;
createdAt: Date;
recipients?: [NotificationReceived];
createdAt?: Date;
authorId?: string;
};

export type NotificationUpdateRequest = {
message?: string;
createdAt?: Date;
authorId?: string;
};

export type NotificationGroupResponse = {
id: string;
recipients?: ResidentResponse[];
notifications?: NotificationResponse[];
announcementGroup: boolean;
};

export type NotificationReceived = {
export type NotificationReceivedResponse = {
id: string;
notificationId: string;
notification?: NotificationResponse;
recipientId: number;
seen: boolean;
};
12 changes: 9 additions & 3 deletions frontend/src/APIClients/Types/ResidentsType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export type UserResponse = {
phoneNumber?: string;
firstName: string;
lastName: string;
displayName?: string;
profilePictureURL?: string;
birthDate: string;
roomNumber: number;
Expand All @@ -21,7 +20,6 @@ export type UserRequest = {
phoneNumber?: string;
firstName: string;
lastName: string;
displayName?: string;
profilePictureURL?: string;
residentId: number;
birthDate: string;
Expand All @@ -38,7 +36,6 @@ export type UserRequestUpdate = {
phoneNumber?: string;
firstName?: string;
lastName?: string;
displayName?: string;
profilePictureURL?: string;
residentId?: number;
birthDate?: string;
Expand All @@ -48,3 +45,12 @@ export type UserRequestUpdate = {
dateLeft?: Date;
notes?: string;
};

export type ResidentResponse = {
userId: string;
residentId: string;
roomNumber: number;
credits: number;
dateJoined: Date;
dateLeft: Date;
};
Loading

0 comments on commit 8959188

Please # to comment.