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

Create Mutations to Set Resident or Staff to Inactive #98

Open
wants to merge 2 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
5 changes: 4 additions & 1 deletion backend/graphql/resolvers/notificationResolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import INotificationService, {
} from "../../services/interfaces/notificationService";
import IResidentService from "../../services/interfaces/residentService";
import ResidentService from "../../services/implementations/residentService";
import IUserService from "../../services/interfaces/userService";
import UserService from "../../services/implementations/userService";

const residentService: IResidentService = new ResidentService();
const userService: IUserService = new UserService();
const residentService: IResidentService = new ResidentService(userService);
const notificationService: INotificationService = new NotificationService(
residentService,
);
Expand Down
14 changes: 13 additions & 1 deletion backend/graphql/resolvers/residentResolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import IResidentService, {
UpdateResidentDTO,
RedeemCreditsResponse,
} from "../../services/interfaces/residentService";
import UserService from "../../services/implementations/userService";
import IUserService from "../../services/interfaces/userService";

const residentService: IResidentService = new ResidentService();
const userService: IUserService = new UserService();
const residentService: IResidentService = new ResidentService(userService);

const residentResolvers = {
Query: {
Expand Down Expand Up @@ -67,6 +70,15 @@ const residentResolvers = {
): Promise<RedeemCreditsResponse> => {
return residentService.redeemCredits(parseInt(userId, 10), credits);
},
setResidentInactive: async (
_parent: undefined,
{ userId }: { userId: string },
): Promise<ResidentDTO> => {
const updatedResident = await residentService.setResidentInactive(
parseInt(userId, 10),
);
return updatedResident;
},
},
};

Expand Down
14 changes: 13 additions & 1 deletion backend/graphql/resolvers/staffResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import IStaffService, {
CreateStaffDTO,
UpdateStaffDTO,
} from "../../services/interfaces/staffService";
import UserService from "../../services/implementations/userService";
import IUserService from "../../services/interfaces/userService";

const staffService: IStaffService = new StaffService();
const userService: IUserService = new UserService();
const staffService: IStaffService = new StaffService(userService);

const staffResolvers = {
Query: {
Expand Down Expand Up @@ -50,6 +53,15 @@ const staffResolvers = {
const deletedStaff = await staffService.deleteStaff(parseInt(userId, 10));
return deletedStaff;
},
setStaffInactive: async (
_parent: undefined,
{ userId }: { userId: string },
): Promise<StaffDTO> => {
const updatedStaff = await staffService.setStaffInactive(
parseInt(userId, 10),
);
return updatedStaff;
},
},
};

Expand Down
1 change: 1 addition & 0 deletions backend/graphql/types/residentType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const residentType = gql`
updateResident(userId: ID!, resident: UpdateResidentDTO!): ResidentDTO!
deleteResident(userId: ID!): ResidentDTO!
redeemCredits(userId: ID!, credits: Float!): RedeemCreditResponse!
setResidentInactive(userId: ID!): ResidentDTO!
}
`;

Expand Down
1 change: 1 addition & 0 deletions backend/graphql/types/staffType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const staffType = gql`
addStaff(staff: CreateStaffDTO!): StaffDTO!
updateStaff(userId: ID!, staff: UpdateStaffDTO!): StaffDTO!
deleteStaff(userId: ID!): StaffDTO!
setStaffInactive(userId: ID!): StaffDTO!
}
`;

Expand Down
45 changes: 45 additions & 0 deletions backend/services/implementations/residentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@ import IResidentService, {
UpdateResidentDTO,
RedeemCreditsResponse,
} from "../interfaces/residentService";
import IUserService from "../interfaces/userService";
import logger from "../../utilities/logger";
import { getErrorMessage } from "../../utilities/errorUtils";

const Logger = logger(__filename);

class ResidentService implements IResidentService {
userService: IUserService;

constructor(userService: IUserService) {
this.userService = userService;
}

async addResident(resident: CreateResidentDTO): Promise<ResidentDTO> {
try {
const firebaseUser = await firebaseAdmin.auth().createUser({
Expand Down Expand Up @@ -365,6 +372,44 @@ class ResidentService implements IResidentService {
throw error;
}
}

async setResidentInactive(userId: number): Promise<ResidentDTO> {
try {
const resident = await prisma.resident.findUnique({
where: { userId },
include: { user: true },
});

if (!resident) {
throw new Error(`Resident with ${userId} not found.`);
}

this.userService.setUserInactive(userId);

return {
userId: resident.userId,
residentId: resident.residentId,
birthDate: resident.birthDate,
roomNumber: resident.roomNumber,
credits: resident.credits,
dateJoined: resident.dateJoined,
dateLeft: resident.dateLeft,
notes: resident.notes,
email: resident.user.email,
phoneNumber: resident.user.phoneNumber,
firstName: resident.user.firstName,
lastName: resident.user.lastName,
displayName: resident.user.displayName,
profilePictureURL: resident.user.profilePictureURL,
isActive: false,
};
} catch (error: unknown) {
Logger.error(
`Failed to set resident inactive. Reason = ${getErrorMessage(error)}`,
);
throw error;
}
}
}

export default ResidentService;
41 changes: 41 additions & 0 deletions backend/services/implementations/staffService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,19 @@ import IStaffService, {
CreateStaffDTO,
UpdateStaffDTO,
} from "../interfaces/staffService";
import IUserService from "../interfaces/userService";
import logger from "../../utilities/logger";
import { getErrorMessage } from "../../utilities/errorUtils";

const Logger = logger(__filename);

class StaffService implements IStaffService {
userService: IUserService;

constructor(userService: IUserService) {
this.userService = userService;
}

async addStaff(staff: CreateStaffDTO): Promise<StaffDTO> {
try {
const firebaseUser = await firebaseAdmin.auth().createUser({
Expand Down Expand Up @@ -234,6 +241,40 @@ class StaffService implements IStaffService {
throw error;
}
}

async setStaffInactive(userId: number): Promise<StaffDTO> {
try {
const staff = await prisma.staff.findUnique({
where: { userId },
include: { user: true },
});

if (!staff) {
throw new Error(`Staff with userId ${userId} not found.`);
}

this.userService.setUserInactive(userId);

return {
userId: staff.userId,
isAdmin: staff.isAdmin,
email: staff.user.email,
phoneNumber: staff.user.phoneNumber,
firstName: staff.user.firstName,
lastName: staff.user.lastName,
displayName: staff.user.displayName,
profilePictureURL: staff.user.profilePictureURL,
isActive: false,
};
} catch (error: unknown) {
Logger.error(
`Failed to set staff inactive. IDs = ${userId} because ${getErrorMessage(
error,
)}`,
);
throw error;
}
}
}

export default StaffService;
22 changes: 22 additions & 0 deletions backend/services/implementations/userService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,28 @@ class UserService implements IUserService {
throw error;
}
}

async setUserInactive(userId: number): Promise<void> {
try {
const user = await prisma.user.update({
where: {
id: userId,
},
data: {
isActive: false,
},
});

if (!user) {
throw new Error(`User with userId ${userId} not found.`);
}
} catch (error: unknown) {
Logger.error(
`Failed to set user inactive. Reason = ${getErrorMessage(error)}`,
);
throw error;
}
}
}

export default UserService;
8 changes: 8 additions & 0 deletions backend/services/interfaces/residentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ interface IResidentService {
*/
getActiveResidents(): Promise<Array<ResidentDTO>>;

/**
* Update resident with userId to inactive
* @param userId resident's id
* @returns resident's type
* @throws Error if user type retrieval fails
*/
setResidentInactive(userId: number): Promise<ResidentDTO>;

/**
* Redeems certain resident's credits based on resident id
* @param userId: resident id whose credits are to be redeemed
Expand Down
8 changes: 8 additions & 0 deletions backend/services/interfaces/staffService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ interface IStaffService {
* @throws Error if staff retrieval fails
*/
getStaffByIds(staffIds: number[]): Promise<Array<StaffDTO>>;

/**
* Update staff with staffId to inactive
* @param staffId staff ids
* @returns a StaffDTO with staff's information
* @throws Error if staff retrieval fails
*/
setStaffInactive(userId: number): Promise<StaffDTO>;
}

export default IStaffService;
8 changes: 8 additions & 0 deletions backend/services/interfaces/userService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ interface IUserService {
* @throws Error if user type retrieval fails
*/
getUserTypeByAuthId(authId: string): Promise<UserType>;

/**
* Update user with userId to inactive
* @param userId user's id
* @returns user's type
* @throws Error if user type retrieval fails
*/
setUserInactive(userId: number): Promise<void>;
}

export default IUserService;
Loading