Skip to content

Commit

Permalink
Add newsletter specification
Browse files Browse the repository at this point in the history
  • Loading branch information
Timothy-Gonzalez committed Oct 16, 2024
1 parent 4b8f32c commit 6d7da52
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 59 deletions.
2 changes: 1 addition & 1 deletion src/database/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { AttendeeFollowing, AttendeeProfile } from "./attendee-db";
import { AdmissionDecision } from "./admission-db";
import { MentorOfficeHours } from "./mentor-db";
import { Event, EventAttendance, EventFollowers } from "./event-db";
import { NewsletterSubscription } from "./newsletter-db";
import { NewsletterSubscription } from "../services/newsletter/newsletter-schemas";
import { RegistrationApplication } from "./registration-db";
import { ShopItem } from "../services/shop/shop-schemas";
import { UserAttendance, UserInfo } from "../services/user/user-schemas";
Expand Down
12 changes: 0 additions & 12 deletions src/database/newsletter-db.ts

This file was deleted.

5 changes: 0 additions & 5 deletions src/services/newsletter/newsletter-formats.ts

This file was deleted.

68 changes: 27 additions & 41 deletions src/services/newsletter/newsletter-router.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,36 @@
import { Request, Response, Router } from "express";
import { SubscribeRequest } from "./newsletter-formats";
import { NewsletterSubscription } from "../../database/newsletter-db";
import { Router } from "express";
import { NewsletterSubscription, SubscribeRequestSchema } from "./newsletter-schemas";
import Models from "../../database/models";
import { UpdateQuery } from "mongoose";
import { StatusCode } from "status-code-enum";
import { RouterError } from "../../middleware/error-handler";
import { NextFunction } from "express-serve-static-core";
import specification, { Tag } from "../../middleware/specification";
import { SuccessResponseSchema } from "../../common/schemas";

const newsletterRouter = Router();

/**
* @api {post} /newsletter/subscribe/ POST /newsletter/subscribe/
* @apiGroup Newsletter
* @apiDescription Subscribe an email address to a newsletter. Will create a newsleter if it doesn't exist.
*
* @apiBody {String} listName Name of the list to add the user to
* @apiBody {String} emailAddress Email address to add to the list
* @apiParamExample {json} Example Request:
* {"listName": "testingList", "emailAddress": "example@hackillinois.org" }
*
* @apiSuccess {String} status Status of the request
* @apiSuccessExample Example Success Response:
* HTTP/1.1 200 OK
* {"status": "Succesful"}
*
* @apiError (400: Bad Request) {String} InvalidParams Invalid input passed in (missing name or email)
* @apiError (400: Bad Request) {String} ListNotFound List doesn't exist within the database
*
* @apiErrorExample Example Error Response:
* HTTP/1.1 400 Bad Request
* {"error": "InvalidParams"}
*/
newsletterRouter.post("/subscribe/", async (request: Request, res: Response, next: NextFunction) => {
const requestBody = request.body as SubscribeRequest;
const listName = requestBody.listName as string | undefined;
const emailAddress = requestBody.emailAddress as string | undefined;
newsletterRouter.post(
"/subscribe/",
specification({
method: "post",
path: "/newsletter/subscribe/",
tag: Tag.NEWSLETTER,
role: null,
summary: "Subscribes the requested email to the requested newsletter",
body: SubscribeRequestSchema,
responses: {
[StatusCode.SuccessOK]: {
description: "Successfully added email to newsletter",
schema: SuccessResponseSchema,
},
},
}),
async (request, res) => {
const { listName, emailAddress } = request.body;

// Verify that both parameters do exist
if (!listName || !emailAddress) {
return next(new RouterError(StatusCode.ClientErrorBadRequest, "InvalidParams"));
}

// Perform a lazy delete
const updateQuery: UpdateQuery<NewsletterSubscription> = { $addToSet: { subscribers: emailAddress } };
await Models.NewsletterSubscription.findOneAndUpdate({ newsletterId: listName }, updateQuery, { upsert: true });
return res.status(StatusCode.SuccessOK).send({ status: "Success" });
});
const updateQuery: UpdateQuery<NewsletterSubscription> = { $addToSet: { subscribers: emailAddress } };
await Models.NewsletterSubscription.findOneAndUpdate({ newsletterId: listName }, updateQuery, { upsert: true });
return res.status(StatusCode.SuccessOK).send({ success: true });
},
);

export default newsletterRouter;
25 changes: 25 additions & 0 deletions src/services/newsletter/newsletter-schemas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { prop } from "@typegoose/typegoose";
import { z } from "zod";

export class NewsletterSubscription {
@prop({ required: true })
public newsletterId: string;

@prop({
required: true,
type: () => String,
})
public subscribers: string[];
}

export const SubscribeRequestSchema = z
.object({
listName: z.string(),
emailAddress: z.string(),
})
.openapi("SubscribeRequest", {
example: {
listName: "recruitment_interest",
emailAddress: "example@example.com",
},
});

0 comments on commit 6d7da52

Please sign in to comment.