From b780a2e9eae939fbbf671150ec4466f208f1ce4c Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Mon, 1 Apr 2024 18:08:54 -0500 Subject: [PATCH 01/18] starting attendee api routes --- package.json | 4 +-- src/app.ts | 44 +++++++++++++++++++++++ src/services/attendees/attendee-schema.ts | 20 +++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 src/services/attendees/attendee-schema.ts diff --git a/package.json b/package.json index 43f0f88..a0331e9 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "private": true, "version": "0.0.0", "scripts": { - "dev": "ENV=DEVELOPMENT nodemon -w src/ -x tsx src/app.ts", - "start": "ENV=PRODUCTION tsx src/app.ts", + "dev": "nodemon -w src/ -x tsx src/app.ts", + "start": "tsx src/app.ts", "lint": "yarn prettier . --write", "kill": "kill -9 $(lsof -t -i :3000)", "build": "tsc" diff --git a/src/app.ts b/src/app.ts index c4bb74f..5fb6247 100644 --- a/src/app.ts +++ b/src/app.ts @@ -9,6 +9,9 @@ import errorHandler from "./middleware/error-handler"; import authRouter from "./services/auth/auth-router"; +import { CreateAttendeeSchema } from "./services/attendees/attendee-schema"; +import { AttendeeModel } from "./services/attendees/attendee-schema"; + const app = express(); // to prevent server-side caching/returning status code 200 @@ -22,6 +25,47 @@ app.use("/", bodyParser.json()); app.use("/auth", authRouter); +// Create a new attendee +app.post("/attendees", async (req, res) => { + try { + const { name, email } = CreateAttendeeSchema.parse(req.body); + console.log("Name:", name); + console.log("Email:", email); + + // Save attendee to the database + const attendee = new AttendeeModel({ name, email }); + await attendee.save(); + + res.status(201).send("Attendee created successfully."); + } catch (error) { + console.error("Error:", error); + res.status(400).send("Error creating attendee."); + } +}); + +// Check if a user email exists +app.get("/attendees/:email", async (req, res) => { + try { + const { email } = req.params; + + // Check if the user exists in the database + const userExists = await AttendeeModel.exists({ email }); + + if (!userExists) { + return res + .status(StatusCodes.NOT_FOUND) + .send("User with that email does not exist."); + } + + return res.status(StatusCodes.OK).send("User exists."); + } catch (error) { + console.error("Error:", error); + return res + .status(StatusCodes.INTERNAL_SERVER_ERROR) + .send("Internal server error."); + } +}); + app.get("/status", (_, res) => { console.log(StatusCodes.OK); return res.status(StatusCodes.OK).send("API is alive!"); diff --git a/src/services/attendees/attendee-schema.ts b/src/services/attendees/attendee-schema.ts new file mode 100644 index 0000000..8e936bc --- /dev/null +++ b/src/services/attendees/attendee-schema.ts @@ -0,0 +1,20 @@ +import mongoose from "mongoose"; +import { z } from "zod"; + + +// Zod schema for attendee +const CreateAttendeeSchema = z.object({ + name: z.string(), + email: z.string().email(), +}); + + +// Mongoose schema for attendee +const AttendeeSchema = new mongoose.Schema({ + name: { type: String, required: true }, + email: { type: String, required: true, unique: true }, +}); + + +export const AttendeeModel = mongoose.model("Attendee", AttendeeSchema); +export { CreateAttendeeSchema }; \ No newline at end of file From d1dc4e26939f6bf743ff94244b10303238f14eab Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Sun, 7 Apr 2024 12:17:19 -0500 Subject: [PATCH 02/18] continuing attendee schema and event schema --- src/app.ts | 49 ++----------- src/services/attendees/attendee-router.ts | 49 +++++++++++++ src/services/attendees/attendee-schema.ts | 43 ++++++++++-- src/services/events/event-router.ts | 86 +++++++++++++++++++++++ src/services/events/event-schema.ts | 50 +++++++++++++ 5 files changed, 228 insertions(+), 49 deletions(-) create mode 100644 src/services/attendees/attendee-router.ts create mode 100644 src/services/events/event-router.ts create mode 100644 src/services/events/event-schema.ts diff --git a/src/app.ts b/src/app.ts index 5fb6247..7bb4ff9 100644 --- a/src/app.ts +++ b/src/app.ts @@ -8,9 +8,8 @@ import bodyParser from "body-parser"; import errorHandler from "./middleware/error-handler"; import authRouter from "./services/auth/auth-router"; - -import { CreateAttendeeSchema } from "./services/attendees/attendee-schema"; -import { AttendeeModel } from "./services/attendees/attendee-schema"; +import attendeeRouter from "./services/attendees/attendee-router"; +import eventRouter from "./services/events/event-router"; const app = express(); @@ -23,48 +22,10 @@ app.use("/", morgan("dev")); app.use("/", bodyParser.json()); +// API routes app.use("/auth", authRouter); - -// Create a new attendee -app.post("/attendees", async (req, res) => { - try { - const { name, email } = CreateAttendeeSchema.parse(req.body); - console.log("Name:", name); - console.log("Email:", email); - - // Save attendee to the database - const attendee = new AttendeeModel({ name, email }); - await attendee.save(); - - res.status(201).send("Attendee created successfully."); - } catch (error) { - console.error("Error:", error); - res.status(400).send("Error creating attendee."); - } -}); - -// Check if a user email exists -app.get("/attendees/:email", async (req, res) => { - try { - const { email } = req.params; - - // Check if the user exists in the database - const userExists = await AttendeeModel.exists({ email }); - - if (!userExists) { - return res - .status(StatusCodes.NOT_FOUND) - .send("User with that email does not exist."); - } - - return res.status(StatusCodes.OK).send("User exists."); - } catch (error) { - console.error("Error:", error); - return res - .status(StatusCodes.INTERNAL_SERVER_ERROR) - .send("Internal server error."); - } -}); +app.use("/attendee", attendeeRouter); +app.use("/event", eventRouter); app.get("/status", (_, res) => { console.log(StatusCodes.OK); diff --git a/src/services/attendees/attendee-router.ts b/src/services/attendees/attendee-router.ts new file mode 100644 index 0000000..6c27a72 --- /dev/null +++ b/src/services/attendees/attendee-router.ts @@ -0,0 +1,49 @@ +import { Router } from "express"; +import { StatusCodes } from "http-status-codes"; +import { AttendeeValidator } from "./attendee-schema"; +import { AttendeeModel } from "./attendee-schema"; + +const attendeeRouter = Router(); + +// Create a new attendee +attendeeRouter.post("/", async (req, res) => { + try { + const { name, email } = AttendeeValidator.parse(req.body); + console.log("Name:", name); + console.log("Email:", email); + + // Save attendee to the database + const attendee = new AttendeeModel({ name, email }); + await attendee.save(); + + res.status(201).send("Attendee created successfully."); + } catch (error) { + console.error("Error:", error); + res.status(400).send("Error creating attendee."); + } +}); + +// Check if a user email exists +attendeeRouter.get("/:email", async (req, res) => { + try { + const { email } = req.params; + + // Check if the user exists in the database + const userExists = await AttendeeModel.exists({ email }); + + if (!userExists) { + return res + .status(StatusCodes.NOT_FOUND) + .send("User with that email does not exist."); + } + + return res.status(StatusCodes.OK).send("User exists."); + } catch (error) { + console.error("Error:", error); + return res + .status(StatusCodes.INTERNAL_SERVER_ERROR) + .send("Internal server error."); + } +}); + +export default attendeeRouter; diff --git a/src/services/attendees/attendee-schema.ts b/src/services/attendees/attendee-schema.ts index 8e936bc..c82a490 100644 --- a/src/services/attendees/attendee-schema.ts +++ b/src/services/attendees/attendee-schema.ts @@ -1,20 +1,53 @@ import mongoose from "mongoose"; import { z } from "zod"; - // Zod schema for attendee -const CreateAttendeeSchema = z.object({ +const AttendeeValidator = z.object({ name: z.string(), email: z.string().email(), + studentInfo: z.object({ + university: z.string().nonempty(), + graduation: z.string().nullable().optional(), + major: z.string().nullable().optional(), + }), + events: z.array(z.string()), + dietary_restrictions: z.string(), + age: z.number().nullable().optional(), + gender: z.string().nullable().optional(), + race: z.array(z.string()).nullable().optional(), + ethnicity: z.string().nullable().optional(), + first_gen: z.string().nullable().optional(), + hear_about_rp: z.array(z.string()).nullable().optional(), + portfolio: z.string().nullable().optional(), + job_interest: z.array(z.string()).nullable().optional(), + interest_mech_puzzle: z.array(z.string()).nullable().optional(), + priority_expiry: z.date().nullable().optional(), + has_resume: z.boolean().optional(), }); - // Mongoose schema for attendee const AttendeeSchema = new mongoose.Schema({ name: { type: String, required: true }, email: { type: String, required: true, unique: true }, + studentInfo: { + university: { type: String, required: true }, + graduation: { type: String, default: null }, + major: { type: String, default: null }, + }, + events: [{ type: mongoose.Schema.Types.ObjectId, ref: "Event" }], + dietary_restrictions: { type: String, required: true }, + age: { type: Number, default: null }, + gender: { type: String, default: null }, + race: [{ type: String }], + ethnicity: { type: String, default: null }, + first_gen: { type: String, default: null }, + hear_about_rp: [{ type: String }], + portfolio: { type: String, default: null }, + job_interest: [{ type: String }], + interest_mech_puzzle: [{ type: String }], + priority_expiry: { type: Date, default: null }, + has_resume: { type: Boolean, default: false }, }); - export const AttendeeModel = mongoose.model("Attendee", AttendeeSchema); -export { CreateAttendeeSchema }; \ No newline at end of file +export { AttendeeValidator }; diff --git a/src/services/events/event-router.ts b/src/services/events/event-router.ts new file mode 100644 index 0000000..360b1b3 --- /dev/null +++ b/src/services/events/event-router.ts @@ -0,0 +1,86 @@ +import { Router } from "express"; +import { StatusCodes } from "http-status-codes"; +import { EventValidator } from "./event-schema"; +import { EventModel } from "./event-schema"; + +const eventRouter = Router(); + +// Create a new event +eventRouter.post("/", async (req, res) => { + try { + const eventData = EventValidator.parse(req.body); + const event = new EventModel(eventData); + await event.save(); + res.status(StatusCodes.CREATED).json(event); + } catch (error) { + console.error("Error:", error); + res.status(StatusCodes.BAD_REQUEST).send("Error creating event."); + } +}); + +// Get all events +eventRouter.get("/", async (req, res) => { + try { + const events = await EventModel.find(); + res.status(StatusCodes.OK).json(events); + } catch (error) { + console.error("Error:", error); + res.status(StatusCodes.INTERNAL_SERVER_ERROR).send( + "Internal server error." + ); + } +}); + +// Get event by ID +eventRouter.get("/:id", async (req, res) => { + try { + const event = await EventModel.findById(req.params.id); + if (!event) { + return res.status(StatusCodes.NOT_FOUND).send("Event not found."); + } + res.status(StatusCodes.OK).json(event); + } catch (error) { + console.error("Error:", error); + res.status(StatusCodes.INTERNAL_SERVER_ERROR).send( + "Internal server error." + ); + } +}); + +// Update event +eventRouter.patch("/:id", async (req, res) => { + try { + const event = await EventModel.findByIdAndUpdate( + req.params.id, + req.body, + { new: true } + ); + if (!event) { + return res.status(StatusCodes.NOT_FOUND).send("Event not found."); + } + res.status(StatusCodes.OK).json(event); + } catch (error) { + console.error("Error:", error); + res.status(StatusCodes.INTERNAL_SERVER_ERROR).send( + "Internal server error." + ); + } +}); + +// Delete event +eventRouter.delete("/:id", async (req, res) => { + try { + const event = await EventModel.findByIdAndDelete(req.params.id); + if (!event) { + return res.status(StatusCodes.NOT_FOUND).send("Event not found."); + } + res.status(StatusCodes.NO_CONTENT).send(); + } catch (error) { + console.error("Error:", error); + res.status(StatusCodes.INTERNAL_SERVER_ERROR).send( + "Internal server error." + ); + } +}); + +export default eventRouter; diff --git a/src/services/events/event-schema.ts b/src/services/events/event-schema.ts new file mode 100644 index 0000000..db29a3d --- /dev/null +++ b/src/services/events/event-schema.ts @@ -0,0 +1,50 @@ +import mongoose from "mongoose"; +import { z } from "zod"; + +// Zod schema for event +const EventValidator = z.object({ + name: z.string(), + description: z.string(), + start_time: z.date(), + end_time: z.date(), + attendees: z.array(z.string()), + location: z.array( + z.object({ + description: z.string(), + tags: z.array(z.string()), + latitude: z.number(), + longitude: z.number(), + }) + ), + virtual: z.boolean(), + upgrade: z.boolean().default(false), + downgrade: z.boolean().default(false), + imageUrl: z.string().nullable().optional(), + visible: z.boolean().default(false), +}); + +// Mongoose schema for location +const LocationSchema = new mongoose.Schema({ + description: { type: String, required: true }, + tags: [{ type: String }], + latitude: { type: Number, required: true }, + longitude: { type: Number, required: true }, +}); + +// Mongoose schema for event +const EventSchema = new mongoose.Schema({ + name: { type: String, required: true }, + description: { type: String, required: true }, + start_time: { type: Date, required: true }, + end_time: { type: Date, required: true }, + attendees: [{ type: mongoose.Schema.Types.ObjectId, ref: "Attendee" }], + location: [LocationSchema], + virtual: { type: Boolean, required: true }, + upgrade: { type: Boolean, default: false }, + downgrade: { type: Boolean, default: false }, + imageUrl: { type: String, default: null }, + visible: { type: Boolean, default: false }, +}); + +export const EventModel = mongoose.model("Event", EventSchema); +export { EventValidator }; From 85dccb18303f7a99737324c7f4828d3a6269fc17 Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Tue, 9 Apr 2024 17:57:42 -0500 Subject: [PATCH 03/18] request changes --- src/app.ts | 2 +- src/database.ts | 7 +++ src/services/attendees/attendee-router.ts | 24 ++++++----- src/services/attendees/attendee-schema.ts | 3 +- src/services/events/event-router.ts | 52 ++++++++++++----------- src/services/events/event-schema.ts | 3 +- 6 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/app.ts b/src/app.ts index 7bb4ff9..bcfb50a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -23,8 +23,8 @@ app.use("/", morgan("dev")); app.use("/", bodyParser.json()); // API routes -app.use("/auth", authRouter); app.use("/attendee", attendeeRouter); +app.use("/auth", authRouter); app.use("/event", eventRouter); app.get("/status", (_, res) => { diff --git a/src/database.ts b/src/database.ts index 2e8c4c5..4d58e4f 100644 --- a/src/database.ts +++ b/src/database.ts @@ -1,5 +1,10 @@ import mongoose, { Schema } from "mongoose"; import { RoleInfo, RoleSchema } from "./services/auth/auth-schema"; +import { EventValidator, EventSchema } from "./services/events/event-schema"; +import { + AttendeeSchema, + AttendeeValidator, +} from "./services/attendees/attendee-schema"; mongoose.set("toObject", { versionKey: false }); @@ -32,4 +37,6 @@ function initializeModel( // Example usage export const Database = { ROLES: initializeModel("roles", RoleSchema, RoleInfo), + EVENTS: initializeModel("events", EventSchema, EventValidator), + ATTENDEES: initializeModel("attendees", AttendeeSchema, AttendeeValidator), }; diff --git a/src/services/attendees/attendee-router.ts b/src/services/attendees/attendee-router.ts index 6c27a72..a5ebfac 100644 --- a/src/services/attendees/attendee-router.ts +++ b/src/services/attendees/attendee-router.ts @@ -1,25 +1,23 @@ import { Router } from "express"; import { StatusCodes } from "http-status-codes"; import { AttendeeValidator } from "./attendee-schema"; -import { AttendeeModel } from "./attendee-schema"; +import { Database } from "../../database"; const attendeeRouter = Router(); // Create a new attendee attendeeRouter.post("/", async (req, res) => { try { - const { name, email } = AttendeeValidator.parse(req.body); - console.log("Name:", name); - console.log("Email:", email); - - // Save attendee to the database - const attendee = new AttendeeModel({ name, email }); + const attendeeData = AttendeeValidator.parse(req.body); + const attendee = new Database.ATTENDEES(attendeeData); await attendee.save(); - res.status(201).send("Attendee created successfully."); + return res.status(StatusCodes.CREATED).json(attendeeData); } catch (error) { console.error("Error:", error); - res.status(400).send("Error creating attendee."); + return res + .status(StatusCodes.INTERNAL_SERVER_ERROR) + .send("Error creating attendee."); } }); @@ -29,7 +27,7 @@ attendeeRouter.get("/:email", async (req, res) => { const { email } = req.params; // Check if the user exists in the database - const userExists = await AttendeeModel.exists({ email }); + const userExists = await Database.ATTENDEES.exists({ email }); if (!userExists) { return res @@ -37,7 +35,11 @@ attendeeRouter.get("/:email", async (req, res) => { .send("User with that email does not exist."); } - return res.status(StatusCodes.OK).send("User exists."); + const user = await Database.ATTENDEES.findOne({ + email, + }); + + return res.status(StatusCodes.OK).json(user); } catch (error) { console.error("Error:", error); return res diff --git a/src/services/attendees/attendee-schema.ts b/src/services/attendees/attendee-schema.ts index c82a490..279a125 100644 --- a/src/services/attendees/attendee-schema.ts +++ b/src/services/attendees/attendee-schema.ts @@ -49,5 +49,4 @@ const AttendeeSchema = new mongoose.Schema({ has_resume: { type: Boolean, default: false }, }); -export const AttendeeModel = mongoose.model("Attendee", AttendeeSchema); -export { AttendeeValidator }; +export { AttendeeSchema, AttendeeValidator }; diff --git a/src/services/events/event-router.ts b/src/services/events/event-router.ts index 360b1b3..f365ea1 100644 --- a/src/services/events/event-router.ts +++ b/src/services/events/event-router.ts @@ -1,7 +1,7 @@ import { Router } from "express"; import { StatusCodes } from "http-status-codes"; import { EventValidator } from "./event-schema"; -import { EventModel } from "./event-schema"; +import { Database } from "../../database"; const eventRouter = Router(); @@ -9,77 +9,81 @@ const eventRouter = Router(); eventRouter.post("/", async (req, res) => { try { const eventData = EventValidator.parse(req.body); - const event = new EventModel(eventData); + const event = new Database.EVENTS(eventData); await event.save(); - res.status(StatusCodes.CREATED).json(event); + return res.status(StatusCodes.CREATED).json(event); } catch (error) { console.error("Error:", error); - res.status(StatusCodes.BAD_REQUEST).send("Error creating event."); + return res + .status(StatusCodes.BAD_REQUEST) + .send("Error creating event."); } }); // Get all events eventRouter.get("/", async (req, res) => { try { - const events = await EventModel.find(); - res.status(StatusCodes.OK).json(events); + const events = await Database.EVENTS.find(); + return res.status(StatusCodes.OK).json(events); } catch (error) { console.error("Error:", error); - res.status(StatusCodes.INTERNAL_SERVER_ERROR).send( - "Internal server error." - ); + return res + .status(StatusCodes.INTERNAL_SERVER_ERROR) + .send("Internal server error."); } }); // Get event by ID eventRouter.get("/:id", async (req, res) => { try { - const event = await EventModel.findById(req.params.id); + const event = await Database.EVENTS.findById(req.params.id); if (!event) { return res.status(StatusCodes.NOT_FOUND).send("Event not found."); } - res.status(StatusCodes.OK).json(event); + return res.status(StatusCodes.OK).json(event); } catch (error) { console.error("Error:", error); - res.status(StatusCodes.INTERNAL_SERVER_ERROR).send( - "Internal server error." - ); + return res + .status(StatusCodes.INTERNAL_SERVER_ERROR) + .send("Internal server error."); } }); // Update event eventRouter.patch("/:id", async (req, res) => { try { - const event = await EventModel.findByIdAndUpdate( + const event = await Database.EVENTS.findByIdAndUpdate( req.params.id, req.body, { new: true } ); + if (!event) { return res.status(StatusCodes.NOT_FOUND).send("Event not found."); } - res.status(StatusCodes.OK).json(event); + + return res.status(StatusCodes.OK).json(event); } catch (error) { console.error("Error:", error); - res.status(StatusCodes.INTERNAL_SERVER_ERROR).send( - "Internal server error." - ); + return res + .status(StatusCodes.INTERNAL_SERVER_ERROR) + .send("Internal server error."); } }); // Delete event eventRouter.delete("/:id", async (req, res) => { try { - const event = await EventModel.findByIdAndDelete(req.params.id); + const event = await Database.EVENTS.findByIdAndDelete(req.params.id); if (!event) { return res.status(StatusCodes.NOT_FOUND).send("Event not found."); } - res.status(StatusCodes.NO_CONTENT).send(); + return res.status(StatusCodes.NO_CONTENT).send(); } catch (error) { console.error("Error:", error); - res.status(StatusCodes.INTERNAL_SERVER_ERROR).send( - "Internal server error." - ); + return res + .status(StatusCodes.INTERNAL_SERVER_ERROR) + .send("Internal server error."); } }); diff --git a/src/services/events/event-schema.ts b/src/services/events/event-schema.ts index db29a3d..768be72 100644 --- a/src/services/events/event-schema.ts +++ b/src/services/events/event-schema.ts @@ -46,5 +46,4 @@ const EventSchema = new mongoose.Schema({ visible: { type: Boolean, default: false }, }); -export const EventModel = mongoose.model("Event", EventSchema); -export { EventValidator }; +export { EventSchema, EventValidator, LocationSchema }; From d8841b19bf9af802d7031030713435c54f877b59 Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Tue, 9 Apr 2024 18:14:33 -0500 Subject: [PATCH 04/18] error messages --- src/services/attendees/attendee-router.ts | 18 ++------ src/services/events/event-router.ts | 56 ++++++++++------------- 2 files changed, 29 insertions(+), 45 deletions(-) diff --git a/src/services/attendees/attendee-router.ts b/src/services/attendees/attendee-router.ts index a5ebfac..8006361 100644 --- a/src/services/attendees/attendee-router.ts +++ b/src/services/attendees/attendee-router.ts @@ -6,7 +6,7 @@ import { Database } from "../../database"; const attendeeRouter = Router(); // Create a new attendee -attendeeRouter.post("/", async (req, res) => { +attendeeRouter.post("/", async (req, res, next) => { try { const attendeeData = AttendeeValidator.parse(req.body); const attendee = new Database.ATTENDEES(attendeeData); @@ -14,15 +14,12 @@ attendeeRouter.post("/", async (req, res) => { return res.status(StatusCodes.CREATED).json(attendeeData); } catch (error) { - console.error("Error:", error); - return res - .status(StatusCodes.INTERNAL_SERVER_ERROR) - .send("Error creating attendee."); + next(error); } }); // Check if a user email exists -attendeeRouter.get("/:email", async (req, res) => { +attendeeRouter.get("/:email", async (req, res, next) => { try { const { email } = req.params; @@ -30,9 +27,7 @@ attendeeRouter.get("/:email", async (req, res) => { const userExists = await Database.ATTENDEES.exists({ email }); if (!userExists) { - return res - .status(StatusCodes.NOT_FOUND) - .send("User with that email does not exist."); + return { error: "DoesNotExist" }; } const user = await Database.ATTENDEES.findOne({ @@ -41,10 +36,7 @@ attendeeRouter.get("/:email", async (req, res) => { return res.status(StatusCodes.OK).json(user); } catch (error) { - console.error("Error:", error); - return res - .status(StatusCodes.INTERNAL_SERVER_ERROR) - .send("Internal server error."); + next(error); } }); diff --git a/src/services/events/event-router.ts b/src/services/events/event-router.ts index f365ea1..f7e154a 100644 --- a/src/services/events/event-router.ts +++ b/src/services/events/event-router.ts @@ -6,84 +6,76 @@ import { Database } from "../../database"; const eventRouter = Router(); // Create a new event -eventRouter.post("/", async (req, res) => { +eventRouter.post("/", async (req, res, next) => { try { const eventData = EventValidator.parse(req.body); const event = new Database.EVENTS(eventData); await event.save(); return res.status(StatusCodes.CREATED).json(event); } catch (error) { - console.error("Error:", error); - return res - .status(StatusCodes.BAD_REQUEST) - .send("Error creating event."); + next(error); } }); // Get all events -eventRouter.get("/", async (req, res) => { +eventRouter.get("/", async (req, res, next) => { try { const events = await Database.EVENTS.find(); return res.status(StatusCodes.OK).json(events); } catch (error) { - console.error("Error:", error); - return res - .status(StatusCodes.INTERNAL_SERVER_ERROR) - .send("Internal server error."); + next(error); } }); // Get event by ID -eventRouter.get("/:id", async (req, res) => { +eventRouter.get("/:id", async (req, res, next) => { try { - const event = await Database.EVENTS.findById(req.params.id); + const event = await Database.EVENTS.findOneAndUpdate( + { _id: req.params.id }, + { new: true } + ); + if (!event) { - return res.status(StatusCodes.NOT_FOUND).send("Event not found."); + return { error: "DoesNotExist" }; } + return res.status(StatusCodes.OK).json(event); } catch (error) { - console.error("Error:", error); - return res - .status(StatusCodes.INTERNAL_SERVER_ERROR) - .send("Internal server error."); + next(error); } }); // Update event -eventRouter.patch("/:id", async (req, res) => { +eventRouter.patch("/:id", async (req, res, next) => { try { - const event = await Database.EVENTS.findByIdAndUpdate( - req.params.id, + const event = await Database.EVENTS.findOneAndUpdate( + { _id: req.params.id }, req.body, { new: true } ); if (!event) { - return res.status(StatusCodes.NOT_FOUND).send("Event not found."); + return { error: "DoesNotExist" }; } return res.status(StatusCodes.OK).json(event); } catch (error) { - console.error("Error:", error); - return res - .status(StatusCodes.INTERNAL_SERVER_ERROR) - .send("Internal server error."); + next(error); } }); // Delete event -eventRouter.delete("/:id", async (req, res) => { +eventRouter.delete("/:id", async (req, res, next) => { try { const event = await Database.EVENTS.findByIdAndDelete(req.params.id); + if (!event) { - return res.status(StatusCodes.NOT_FOUND).send("Event not found."); + return { error: "DoesNotExist" }; } - return res.status(StatusCodes.NO_CONTENT).send(); + + return res.status(StatusCodes.OK).json(event); } catch (error) { - console.error("Error:", error); - return res - .status(StatusCodes.INTERNAL_SERVER_ERROR) - .send("Internal server error."); + next(error); } }); From 0057b2a5b660ca56575779035dcbec2a7adbf65a Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Tue, 9 Apr 2024 18:17:35 -0500 Subject: [PATCH 05/18] event points --- src/services/events/event-schema.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/services/events/event-schema.ts b/src/services/events/event-schema.ts index 768be72..73890cd 100644 --- a/src/services/events/event-schema.ts +++ b/src/services/events/event-schema.ts @@ -17,8 +17,7 @@ const EventValidator = z.object({ }) ), virtual: z.boolean(), - upgrade: z.boolean().default(false), - downgrade: z.boolean().default(false), + points: z.number().min(0).default(0), imageUrl: z.string().nullable().optional(), visible: z.boolean().default(false), }); @@ -40,8 +39,7 @@ const EventSchema = new mongoose.Schema({ attendees: [{ type: mongoose.Schema.Types.ObjectId, ref: "Attendee" }], location: [LocationSchema], virtual: { type: Boolean, required: true }, - upgrade: { type: Boolean, default: false }, - downgrade: { type: Boolean, default: false }, + points: { type: Number, default: 0 }, imageUrl: { type: String, default: null }, visible: { type: Boolean, default: false }, }); From 4e64b938a0f920a9ab2e07f0f3211f24feeeb10e Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Tue, 9 Apr 2024 18:32:52 -0500 Subject: [PATCH 06/18] registration schema --- src/app.ts | 2 ++ src/config.ts | 2 ++ src/database.ts | 9 ++++++++ src/services/attendees/attendee-schema.ts | 2 ++ .../registration/registration-router.ts | 10 +++++++++ .../registration/registration-schema.ts | 22 +++++++++++++++++++ 6 files changed, 47 insertions(+) create mode 100644 src/services/registration/registration-router.ts create mode 100644 src/services/registration/registration-schema.ts diff --git a/src/app.ts b/src/app.ts index bcfb50a..632e8cb 100644 --- a/src/app.ts +++ b/src/app.ts @@ -10,6 +10,7 @@ import errorHandler from "./middleware/error-handler"; import authRouter from "./services/auth/auth-router"; import attendeeRouter from "./services/attendees/attendee-router"; import eventRouter from "./services/events/event-router"; +import registrationRouter from "./services/registration/registration-router"; const app = express(); @@ -26,6 +27,7 @@ app.use("/", bodyParser.json()); app.use("/attendee", attendeeRouter); app.use("/auth", authRouter); app.use("/event", eventRouter); +app.use("/registration", registrationRouter); app.get("/status", (_, res) => { console.log(StatusCodes.OK); diff --git a/src/config.ts b/src/config.ts index e3a6f9f..d6fbe74 100644 --- a/src/config.ts +++ b/src/config.ts @@ -6,6 +6,8 @@ import { getEnv } from "./utilities"; export const Environment = z.enum(["PRODUCTION", "DEVELOPMENT", "TESTING"]); +export const ListName = z.enum(["RP_INTEREST"]); + export const Config = { DEFAULT_APP_PORT: 3000, ENV: Environment.parse(getEnv("ENV")), diff --git a/src/database.ts b/src/database.ts index 4d58e4f..15b4aca 100644 --- a/src/database.ts +++ b/src/database.ts @@ -5,6 +5,10 @@ import { AttendeeSchema, AttendeeValidator, } from "./services/attendees/attendee-schema"; +import { + RegistrationSchema, + RegistrationValidator, +} from "./services/registration/registration-schema"; mongoose.set("toObject", { versionKey: false }); @@ -39,4 +43,9 @@ export const Database = { ROLES: initializeModel("roles", RoleSchema, RoleInfo), EVENTS: initializeModel("events", EventSchema, EventValidator), ATTENDEES: initializeModel("attendees", AttendeeSchema, AttendeeValidator), + REGISTRATION: initializeModel( + "registration", + RegistrationSchema, + RegistrationValidator + ), }; diff --git a/src/services/attendees/attendee-schema.ts b/src/services/attendees/attendee-schema.ts index 279a125..79baebe 100644 --- a/src/services/attendees/attendee-schema.ts +++ b/src/services/attendees/attendee-schema.ts @@ -23,6 +23,7 @@ const AttendeeValidator = z.object({ interest_mech_puzzle: z.array(z.string()).nullable().optional(), priority_expiry: z.date().nullable().optional(), has_resume: z.boolean().optional(), + points: z.number().min(0).default(0), // }); // Mongoose schema for attendee @@ -47,6 +48,7 @@ const AttendeeSchema = new mongoose.Schema({ interest_mech_puzzle: [{ type: String }], priority_expiry: { type: Date, default: null }, has_resume: { type: Boolean, default: false }, + points: { type: Number, default: 0 }, }); export { AttendeeSchema, AttendeeValidator }; diff --git a/src/services/registration/registration-router.ts b/src/services/registration/registration-router.ts new file mode 100644 index 0000000..18d0210 --- /dev/null +++ b/src/services/registration/registration-router.ts @@ -0,0 +1,10 @@ +import { Router } from "express"; +import { StatusCodes } from "http-status-codes"; +import { RegistrationValidator } from "./registration-schema"; +import { Database } from "../../database"; + +const registrationRouter = Router(); + +// TODO: registration routes + +export default registrationRouter; diff --git a/src/services/registration/registration-schema.ts b/src/services/registration/registration-schema.ts new file mode 100644 index 0000000..2a35c14 --- /dev/null +++ b/src/services/registration/registration-schema.ts @@ -0,0 +1,22 @@ +import mongoose from "mongoose"; +import { z } from "zod"; + +// Zod schema for registration +const RegistrationValidator = z.object({ + name: z.string(), + email: z.string().email(), + events: z.array(z.string()), + dietary_restrictions: z.string(), + points: z.number().min(0).default(0), +}); + +// Mongoose schema for registration +const RegistrationSchema = new mongoose.Schema({ + name: { type: String, required: true }, + email: { type: String, required: true, unique: true }, + events: [{ type: mongoose.Schema.Types.ObjectId, ref: "Event" }], + dietary_restrictions: { type: String, required: true }, + points: { type: Number, default: 0 }, +}); + +export { RegistrationSchema, RegistrationValidator }; From 94c4591b3d2d47dba709e9926574c8bc88c9ed68 Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Tue, 9 Apr 2024 19:04:24 -0500 Subject: [PATCH 07/18] subscription basic --- src/app.ts | 2 ++ src/config.ts | 2 +- src/database.ts | 9 +++++++++ .../subscription/subscription-router.ts | 19 +++++++++++++++++++ .../subscription/subscription-schema.ts | 17 +++++++++++++++++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/services/subscription/subscription-router.ts create mode 100644 src/services/subscription/subscription-schema.ts diff --git a/src/app.ts b/src/app.ts index 632e8cb..642b78d 100644 --- a/src/app.ts +++ b/src/app.ts @@ -11,6 +11,7 @@ import authRouter from "./services/auth/auth-router"; import attendeeRouter from "./services/attendees/attendee-router"; import eventRouter from "./services/events/event-router"; import registrationRouter from "./services/registration/registration-router"; +import subscriptionRouter from "./services/subscription/subscription-router"; const app = express(); @@ -28,6 +29,7 @@ app.use("/attendee", attendeeRouter); app.use("/auth", authRouter); app.use("/event", eventRouter); app.use("/registration", registrationRouter); +app.use("/subscription", subscriptionRouter); app.get("/status", (_, res) => { console.log(StatusCodes.OK); diff --git a/src/config.ts b/src/config.ts index d6fbe74..a0f7e13 100644 --- a/src/config.ts +++ b/src/config.ts @@ -6,7 +6,7 @@ import { getEnv } from "./utilities"; export const Environment = z.enum(["PRODUCTION", "DEVELOPMENT", "TESTING"]); -export const ListName = z.enum(["RP_INTEREST"]); +export const MailingListName = z.enum(["RP_INTEREST"]); export const Config = { DEFAULT_APP_PORT: 3000, diff --git a/src/database.ts b/src/database.ts index 15b4aca..dfb71df 100644 --- a/src/database.ts +++ b/src/database.ts @@ -9,6 +9,10 @@ import { RegistrationSchema, RegistrationValidator, } from "./services/registration/registration-schema"; +import { + SubscriptionValidator, + SubscriptionSchema, +} from "./services/subscription/subscription-schema"; mongoose.set("toObject", { versionKey: false }); @@ -48,4 +52,9 @@ export const Database = { RegistrationSchema, RegistrationValidator ), + SUBSCRIPTION: initializeModel( + "subscription", + SubscriptionSchema, + SubscriptionValidator + ), }; diff --git a/src/services/subscription/subscription-router.ts b/src/services/subscription/subscription-router.ts new file mode 100644 index 0000000..b7b9517 --- /dev/null +++ b/src/services/subscription/subscription-router.ts @@ -0,0 +1,19 @@ +import { Router } from "express"; +import { StatusCodes } from "http-status-codes"; +import { SubscriptionValidator } from "./subscription-schema"; +import { Database } from "../../database"; + +const subscriptionRouter = Router(); + +// Create a new subscription +subscriptionRouter.post("/subscribe", async (req, res, next) => { + try { + const subscriptionData = SubscriptionValidator.parse(req.body); + await Database.SUBSCRIPTION.create(subscriptionData); + return res.status(StatusCodes.CREATED).json(subscriptionData); + } catch (error) { + next(error); + } +}); + +export default subscriptionRouter; diff --git a/src/services/subscription/subscription-schema.ts b/src/services/subscription/subscription-schema.ts new file mode 100644 index 0000000..a2089e6 --- /dev/null +++ b/src/services/subscription/subscription-schema.ts @@ -0,0 +1,17 @@ +import mongoose from "mongoose"; +import { z } from "zod"; +import { MailingListName } from "../../config"; + +// Zod schema for subscription +const SubscriptionValidator = z.object({ + email: z.string().email(), + mailing_list_name: MailingListName, +}); + +// Mongoose schema for subscription +const SubscriptionSchema = new mongoose.Schema({ + email: { type: String, required: true }, + mailing_list_name: { type: String, required: true }, +}); + +export { SubscriptionValidator, SubscriptionSchema }; From 46af86eb91a60441735adaf3815af65b67824c66 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Tue, 9 Apr 2024 21:46:10 -0500 Subject: [PATCH 08/18] Delete src/services/attendees/attendee-router.ts --- src/services/attendees/attendee-router.ts | 43 ----------------------- 1 file changed, 43 deletions(-) delete mode 100644 src/services/attendees/attendee-router.ts diff --git a/src/services/attendees/attendee-router.ts b/src/services/attendees/attendee-router.ts deleted file mode 100644 index 8006361..0000000 --- a/src/services/attendees/attendee-router.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Router } from "express"; -import { StatusCodes } from "http-status-codes"; -import { AttendeeValidator } from "./attendee-schema"; -import { Database } from "../../database"; - -const attendeeRouter = Router(); - -// Create a new attendee -attendeeRouter.post("/", async (req, res, next) => { - try { - const attendeeData = AttendeeValidator.parse(req.body); - const attendee = new Database.ATTENDEES(attendeeData); - await attendee.save(); - - return res.status(StatusCodes.CREATED).json(attendeeData); - } catch (error) { - next(error); - } -}); - -// Check if a user email exists -attendeeRouter.get("/:email", async (req, res, next) => { - try { - const { email } = req.params; - - // Check if the user exists in the database - const userExists = await Database.ATTENDEES.exists({ email }); - - if (!userExists) { - return { error: "DoesNotExist" }; - } - - const user = await Database.ATTENDEES.findOne({ - email, - }); - - return res.status(StatusCodes.OK).json(user); - } catch (error) { - next(error); - } -}); - -export default attendeeRouter; From a354741f58c74c86c12b52b6ef903eb1f8568d35 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Tue, 9 Apr 2024 21:46:19 -0500 Subject: [PATCH 09/18] Delete src/services/attendees/attendee-schema.ts --- src/services/attendees/attendee-schema.ts | 54 ----------------------- 1 file changed, 54 deletions(-) delete mode 100644 src/services/attendees/attendee-schema.ts diff --git a/src/services/attendees/attendee-schema.ts b/src/services/attendees/attendee-schema.ts deleted file mode 100644 index 79baebe..0000000 --- a/src/services/attendees/attendee-schema.ts +++ /dev/null @@ -1,54 +0,0 @@ -import mongoose from "mongoose"; -import { z } from "zod"; - -// Zod schema for attendee -const AttendeeValidator = z.object({ - name: z.string(), - email: z.string().email(), - studentInfo: z.object({ - university: z.string().nonempty(), - graduation: z.string().nullable().optional(), - major: z.string().nullable().optional(), - }), - events: z.array(z.string()), - dietary_restrictions: z.string(), - age: z.number().nullable().optional(), - gender: z.string().nullable().optional(), - race: z.array(z.string()).nullable().optional(), - ethnicity: z.string().nullable().optional(), - first_gen: z.string().nullable().optional(), - hear_about_rp: z.array(z.string()).nullable().optional(), - portfolio: z.string().nullable().optional(), - job_interest: z.array(z.string()).nullable().optional(), - interest_mech_puzzle: z.array(z.string()).nullable().optional(), - priority_expiry: z.date().nullable().optional(), - has_resume: z.boolean().optional(), - points: z.number().min(0).default(0), // -}); - -// Mongoose schema for attendee -const AttendeeSchema = new mongoose.Schema({ - name: { type: String, required: true }, - email: { type: String, required: true, unique: true }, - studentInfo: { - university: { type: String, required: true }, - graduation: { type: String, default: null }, - major: { type: String, default: null }, - }, - events: [{ type: mongoose.Schema.Types.ObjectId, ref: "Event" }], - dietary_restrictions: { type: String, required: true }, - age: { type: Number, default: null }, - gender: { type: String, default: null }, - race: [{ type: String }], - ethnicity: { type: String, default: null }, - first_gen: { type: String, default: null }, - hear_about_rp: [{ type: String }], - portfolio: { type: String, default: null }, - job_interest: [{ type: String }], - interest_mech_puzzle: [{ type: String }], - priority_expiry: { type: Date, default: null }, - has_resume: { type: Boolean, default: false }, - points: { type: Number, default: 0 }, -}); - -export { AttendeeSchema, AttendeeValidator }; From 873ed6df1dfeaa1257c962a576840901d2437bf9 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Tue, 9 Apr 2024 21:46:33 -0500 Subject: [PATCH 10/18] Delete src/services/events/event-router.ts --- src/services/events/event-router.ts | 82 ----------------------------- 1 file changed, 82 deletions(-) delete mode 100644 src/services/events/event-router.ts diff --git a/src/services/events/event-router.ts b/src/services/events/event-router.ts deleted file mode 100644 index f7e154a..0000000 --- a/src/services/events/event-router.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { Router } from "express"; -import { StatusCodes } from "http-status-codes"; -import { EventValidator } from "./event-schema"; -import { Database } from "../../database"; - -const eventRouter = Router(); - -// Create a new event -eventRouter.post("/", async (req, res, next) => { - try { - const eventData = EventValidator.parse(req.body); - const event = new Database.EVENTS(eventData); - await event.save(); - return res.status(StatusCodes.CREATED).json(event); - } catch (error) { - next(error); - } -}); - -// Get all events -eventRouter.get("/", async (req, res, next) => { - try { - const events = await Database.EVENTS.find(); - return res.status(StatusCodes.OK).json(events); - } catch (error) { - next(error); - } -}); - -// Get event by ID -eventRouter.get("/:id", async (req, res, next) => { - try { - const event = await Database.EVENTS.findOneAndUpdate( - { _id: req.params.id }, - { new: true } - ); - - if (!event) { - return { error: "DoesNotExist" }; - } - - return res.status(StatusCodes.OK).json(event); - } catch (error) { - next(error); - } -}); - -// Update event -eventRouter.patch("/:id", async (req, res, next) => { - try { - const event = await Database.EVENTS.findOneAndUpdate( - { _id: req.params.id }, - req.body, - { new: true } - ); - - if (!event) { - return { error: "DoesNotExist" }; - } - - return res.status(StatusCodes.OK).json(event); - } catch (error) { - next(error); - } -}); - -// Delete event -eventRouter.delete("/:id", async (req, res, next) => { - try { - const event = await Database.EVENTS.findByIdAndDelete(req.params.id); - - if (!event) { - return { error: "DoesNotExist" }; - } - - return res.status(StatusCodes.OK).json(event); - } catch (error) { - next(error); - } -}); - -export default eventRouter; From 6fa633db24c0340bd299868cfa2e315b46af8086 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Tue, 9 Apr 2024 21:47:25 -0500 Subject: [PATCH 11/18] Delete src/services/registration/registration-schema.ts --- .../registration/registration-schema.ts | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/services/registration/registration-schema.ts diff --git a/src/services/registration/registration-schema.ts b/src/services/registration/registration-schema.ts deleted file mode 100644 index 2a35c14..0000000 --- a/src/services/registration/registration-schema.ts +++ /dev/null @@ -1,22 +0,0 @@ -import mongoose from "mongoose"; -import { z } from "zod"; - -// Zod schema for registration -const RegistrationValidator = z.object({ - name: z.string(), - email: z.string().email(), - events: z.array(z.string()), - dietary_restrictions: z.string(), - points: z.number().min(0).default(0), -}); - -// Mongoose schema for registration -const RegistrationSchema = new mongoose.Schema({ - name: { type: String, required: true }, - email: { type: String, required: true, unique: true }, - events: [{ type: mongoose.Schema.Types.ObjectId, ref: "Event" }], - dietary_restrictions: { type: String, required: true }, - points: { type: Number, default: 0 }, -}); - -export { RegistrationSchema, RegistrationValidator }; From bb2008795fca9ac2ef4e2974b7ee1c8874b8233e Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Tue, 9 Apr 2024 21:47:39 -0500 Subject: [PATCH 12/18] Delete src/services/registration/registration-router.ts --- src/services/registration/registration-router.ts | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 src/services/registration/registration-router.ts diff --git a/src/services/registration/registration-router.ts b/src/services/registration/registration-router.ts deleted file mode 100644 index 18d0210..0000000 --- a/src/services/registration/registration-router.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Router } from "express"; -import { StatusCodes } from "http-status-codes"; -import { RegistrationValidator } from "./registration-schema"; -import { Database } from "../../database"; - -const registrationRouter = Router(); - -// TODO: registration routes - -export default registrationRouter; From 4746216d0975a74229265a5d837cda335ed3df72 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Tue, 9 Apr 2024 21:47:52 -0500 Subject: [PATCH 13/18] Delete src/services/events/event-schema.ts --- src/services/events/event-schema.ts | 47 ----------------------------- 1 file changed, 47 deletions(-) delete mode 100644 src/services/events/event-schema.ts diff --git a/src/services/events/event-schema.ts b/src/services/events/event-schema.ts deleted file mode 100644 index 73890cd..0000000 --- a/src/services/events/event-schema.ts +++ /dev/null @@ -1,47 +0,0 @@ -import mongoose from "mongoose"; -import { z } from "zod"; - -// Zod schema for event -const EventValidator = z.object({ - name: z.string(), - description: z.string(), - start_time: z.date(), - end_time: z.date(), - attendees: z.array(z.string()), - location: z.array( - z.object({ - description: z.string(), - tags: z.array(z.string()), - latitude: z.number(), - longitude: z.number(), - }) - ), - virtual: z.boolean(), - points: z.number().min(0).default(0), - imageUrl: z.string().nullable().optional(), - visible: z.boolean().default(false), -}); - -// Mongoose schema for location -const LocationSchema = new mongoose.Schema({ - description: { type: String, required: true }, - tags: [{ type: String }], - latitude: { type: Number, required: true }, - longitude: { type: Number, required: true }, -}); - -// Mongoose schema for event -const EventSchema = new mongoose.Schema({ - name: { type: String, required: true }, - description: { type: String, required: true }, - start_time: { type: Date, required: true }, - end_time: { type: Date, required: true }, - attendees: [{ type: mongoose.Schema.Types.ObjectId, ref: "Attendee" }], - location: [LocationSchema], - virtual: { type: Boolean, required: true }, - points: { type: Number, default: 0 }, - imageUrl: { type: String, default: null }, - visible: { type: Boolean, default: false }, -}); - -export { EventSchema, EventValidator, LocationSchema }; From 1016299b12fc62d0c361a679372a54c6807cc075 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Tue, 9 Apr 2024 21:48:15 -0500 Subject: [PATCH 14/18] Update app.ts --- src/app.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/app.ts b/src/app.ts index 642b78d..0f2e66c 100644 --- a/src/app.ts +++ b/src/app.ts @@ -8,9 +8,6 @@ import bodyParser from "body-parser"; import errorHandler from "./middleware/error-handler"; import authRouter from "./services/auth/auth-router"; -import attendeeRouter from "./services/attendees/attendee-router"; -import eventRouter from "./services/events/event-router"; -import registrationRouter from "./services/registration/registration-router"; import subscriptionRouter from "./services/subscription/subscription-router"; const app = express(); @@ -25,10 +22,7 @@ app.use("/", morgan("dev")); app.use("/", bodyParser.json()); // API routes -app.use("/attendee", attendeeRouter); app.use("/auth", authRouter); -app.use("/event", eventRouter); -app.use("/registration", registrationRouter); app.use("/subscription", subscriptionRouter); app.get("/status", (_, res) => { From 62c8190e00c701bb6f1b804f867adce774c60f18 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Tue, 9 Apr 2024 21:49:35 -0500 Subject: [PATCH 15/18] Update database.ts --- src/database.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/database.ts b/src/database.ts index dfb71df..33fa1a2 100644 --- a/src/database.ts +++ b/src/database.ts @@ -1,14 +1,5 @@ import mongoose, { Schema } from "mongoose"; import { RoleInfo, RoleSchema } from "./services/auth/auth-schema"; -import { EventValidator, EventSchema } from "./services/events/event-schema"; -import { - AttendeeSchema, - AttendeeValidator, -} from "./services/attendees/attendee-schema"; -import { - RegistrationSchema, - RegistrationValidator, -} from "./services/registration/registration-schema"; import { SubscriptionValidator, SubscriptionSchema, @@ -45,13 +36,6 @@ function initializeModel( // Example usage export const Database = { ROLES: initializeModel("roles", RoleSchema, RoleInfo), - EVENTS: initializeModel("events", EventSchema, EventValidator), - ATTENDEES: initializeModel("attendees", AttendeeSchema, AttendeeValidator), - REGISTRATION: initializeModel( - "registration", - RegistrationSchema, - RegistrationValidator - ), SUBSCRIPTION: initializeModel( "subscription", SubscriptionSchema, From 024fa8e634e141518f36525c4c8bf865319885b8 Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Wed, 10 Apr 2024 19:12:22 -0500 Subject: [PATCH 16/18] pr changes subscription --- src/config.ts | 2 +- src/services/subscription/subscription-router.ts | 8 ++++++-- src/services/subscription/subscription-schema.ts | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/config.ts b/src/config.ts index a0f7e13..ed601c8 100644 --- a/src/config.ts +++ b/src/config.ts @@ -6,7 +6,7 @@ import { getEnv } from "./utilities"; export const Environment = z.enum(["PRODUCTION", "DEVELOPMENT", "TESTING"]); -export const MailingListName = z.enum(["RP_INTEREST"]); +export const MailingListName = z.enum(["rp_interest"]); export const Config = { DEFAULT_APP_PORT: 3000, diff --git a/src/services/subscription/subscription-router.ts b/src/services/subscription/subscription-router.ts index b7b9517..6806ab3 100644 --- a/src/services/subscription/subscription-router.ts +++ b/src/services/subscription/subscription-router.ts @@ -6,10 +6,14 @@ import { Database } from "../../database"; const subscriptionRouter = Router(); // Create a new subscription -subscriptionRouter.post("/subscribe", async (req, res, next) => { +subscriptionRouter.post("/", async (req, res, next) => { try { const subscriptionData = SubscriptionValidator.parse(req.body); - await Database.SUBSCRIPTION.create(subscriptionData); + await Database.SUBSCRIPTION.findOneAndUpdate( + { email: subscriptionData.email }, + { mailingList: subscriptionData.mailingList }, + { upsert: true, new: true } + ); return res.status(StatusCodes.CREATED).json(subscriptionData); } catch (error) { next(error); diff --git a/src/services/subscription/subscription-schema.ts b/src/services/subscription/subscription-schema.ts index a2089e6..32579bf 100644 --- a/src/services/subscription/subscription-schema.ts +++ b/src/services/subscription/subscription-schema.ts @@ -5,13 +5,13 @@ import { MailingListName } from "../../config"; // Zod schema for subscription const SubscriptionValidator = z.object({ email: z.string().email(), - mailing_list_name: MailingListName, + mailingList: MailingListName, }); // Mongoose schema for subscription const SubscriptionSchema = new mongoose.Schema({ email: { type: String, required: true }, - mailing_list_name: { type: String, required: true }, + mailingList: { type: String, required: true }, }); export { SubscriptionValidator, SubscriptionSchema }; From 1cdd1d9bcdba23b68dd6a5494d9bb1c85b83950b Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Wed, 10 Apr 2024 23:26:16 -0500 Subject: [PATCH 17/18] minor change to subscription format --- src/services/subscription/subscription-router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/subscription/subscription-router.ts b/src/services/subscription/subscription-router.ts index 6806ab3..d847061 100644 --- a/src/services/subscription/subscription-router.ts +++ b/src/services/subscription/subscription-router.ts @@ -10,8 +10,8 @@ subscriptionRouter.post("/", async (req, res, next) => { try { const subscriptionData = SubscriptionValidator.parse(req.body); await Database.SUBSCRIPTION.findOneAndUpdate( - { email: subscriptionData.email }, { mailingList: subscriptionData.mailingList }, + { $push: { subscriptions: data.email } }, { upsert: true, new: true } ); return res.status(StatusCodes.CREATED).json(subscriptionData); From 6303fcec65ebae2ad5c92176a6f4f680d3cfd6d7 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Wed, 10 Apr 2024 23:39:49 -0500 Subject: [PATCH 18/18] Update subscription-router.ts --- src/services/subscription/subscription-router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/subscription/subscription-router.ts b/src/services/subscription/subscription-router.ts index d847061..b503fbe 100644 --- a/src/services/subscription/subscription-router.ts +++ b/src/services/subscription/subscription-router.ts @@ -11,7 +11,7 @@ subscriptionRouter.post("/", async (req, res, next) => { const subscriptionData = SubscriptionValidator.parse(req.body); await Database.SUBSCRIPTION.findOneAndUpdate( { mailingList: subscriptionData.mailingList }, - { $push: { subscriptions: data.email } }, + { $push: { subscriptions: subscriptionData.email } }, { upsert: true, new: true } ); return res.status(StatusCodes.CREATED).json(subscriptionData);