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

Feature/implement user data routes #63

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

r800360
Copy link
Member

@r800360 r800360 commented Feb 12, 2025

Tracking Info

Resolves #60

Changes

Implements the Controller and Validator functions for

Get Personal Information
Edit Personal Information
Get Professional Information
Edit Professional Information
Get Directory Personal Information
Edit Directory Personal Information
Get Directory Display Info
Edit Directory Display Info

using the precise fields in our User model and applying the firebaseId in place of standard id as needed. Middleware auth is assumed as part of a separate issue for the purposes of this code.

Testing

The right middleware needed to test this is part of a separate Firebase feature which I am also working on. In terms of testing, it would be helpful to have some mock data perhaps to speed things up; the code looks correct but more testing is needed. I currently do not have the MongoDB credentials, after which I could try testing this code more carefully.

@r800360 r800360 requested a review from Miyuki-L as a code owner February 12, 2025 20:42
Copy link
Contributor

@pratyush1718 pratyush1718 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks really good rohan! See some small code specific changes above. Also I think we should test with a monogodb connection before approval for this.

try {
res.status(200).send("Get professional information route works!");
const user = await User.findOne({ firebaseId: req.user?.firebaseId }).select("professional");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this line of code across multiple controller functions where you do look up for a user by firebaseId. Maybe worth abstracting this away to a common helper function?

} catch (error) {
next(error);
console.error("Error updating personal information:", error);
//Either handle directly or next(error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like you consider it here already but I would recommend going with next(error) since that allows it to be handled globally instead of preemptively returning a 500 error.

}
};

export const editPersonalInformation: RequestHandler = async (req, res, next) => {
export const editPersonalInformation = async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could use typescript types here for the request body? See example below:

interface PersonalInfoUpdate {
  firstName: string;
  lastName: string;
  email: string;
  phone?: string;
}

export const editPersonalInformation = async (
  req: AuthenticatedRequest & { body: PersonalInfoUpdate },
  res: Response,
  next: NextFunction
) => { ... }

Copy link
Member

@Miyuki-L Miyuki-L left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than Pratyush's comments just some other ones. Remove commented code out if not using

} = req.body;

// Validate required fields
if (!firebaseId || !account || !personal || !personal.firstName || !personal.lastName || !personal.email) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we have the validator to validate the request don't think this is needed.

const { name, email } = req.body as { name: string; email: string };
if (!name || !email) {
res.status(400).json({ error: "Name and email are required" });
// const { name, email } = req.body as { name: string; email: string };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

take out commented code


export const createUser = (req: Request, res: Response) => {
export const createUser = async (req: Request, res: Response, next: NextFunction) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See PIA: https://github.com/TritonSE/PIA-Program-Manager/blob/e59620c72cb8a77f7d8ad49ad5392fc6bf9b1431/backend/src/controllers/user.ts

Create a type for the req specific this request or
https://github.com/TritonSE/PAP-Inventory-Processing/blob/main/backend/src/controllers/user.ts
in PAP there is on specific to SPLAGEN

I recal in someone's PR a SPlagenREquest type is created

display,
});
await newUser.save();

res.status(201).json({ message: "User created successfully", user: newUser });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't think we'll need the message since we'll know with the user data the user is cretaed

res.status(201).json({ message: "User created successfully", user: newUser });
} catch (error) {
console.error("Error creating user:", error);
//Either handle directly or next(error)
res.status(500).json({ error: "Internal server error" });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call the next with the error for the error handling
something like
catch (error) { next(error); }

try {
res.status(200).send("Get personal information route works!");
const user = await User.findOne({ firebaseId: req.user?.firebaseId }).select("personal");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this one a different appraoch from above?

uid should be passed in with the request like body of request or params

with the req.user?.firebaseId are you handle case where user doesn't exist?

import { Request } from "express";

export interface AuthenticatedRequest extends Request {
user?: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is user optional? should we not have a user if is an authenticated request?

firebaseId should suffice for finding the user to get the correspondign information
do we need the extra user wrapper?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented code


const updatedUser = await User.findOneAndUpdate(
{ firebaseId: req.user?.firebaseId },
{ "personal.firstName": firstName, "personal.lastName": lastName, "personal.email": email, "personal.phone": phone },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

directory info should not use the personal.phone
image

This is the information to be retrieved by this route

try {
res.status(200).send("Get directory personal information route works!");
const user = await User.findOne({ firebaseId: req.user?.firebaseId }).select("personal");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there should be a different section in the schema for the directory info (if not make one or just pull and return the necessary information). Shouldn't be the personal one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement User Data Routes
3 participants