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

Fix Missing Services #24

Merged
merged 11 commits into from
Apr 20, 2024
Merged
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
24 changes: 12 additions & 12 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
name: Lint

on:
push:
push:

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18.x'
- name: Install dependencies
run: yarn
- name: Run ESLint
run: npx eslint .
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
- name: Install dependencies
run: yarn
- name: Run ESLint
run: npx eslint .
36 changes: 18 additions & 18 deletions .github/workflows/prettier.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
name: Prettier
on:
push:
jobs:
prettier:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
- name: Install dependencies
run: yarn
- name: Run Prettier
run: npx prettier --write .
name: Prettier

on:
push:

jobs:
prettier:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "18.x"
- name: Install dependencies
run: yarn
- name: Run Prettier
run: npx prettier --write .
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# API for Reflections | Projections 2024

Contributors:
- Aydan Pirani
- Divya Koya
- Riya Patel
- Jacob Chang
- Alex Yang
- Shreenija Daggavolu

- Aydan Pirani
- Divya Koya
- Riya Patel
- Jacob Chang
- Alex Yang
- Shreenija Daggavolu
44 changes: 22 additions & 22 deletions appspec.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/rp-api
file_exists_behavior: OVERWRITE
hooks:
BeforeInstall:
- location: scripts/install_dependencies.sh
timeout: 300
runas: root
AfterInstall:
- location: scripts/build.sh
timeout: 300
runas: root
ApplicationStart:
- location: scripts/install_dependencies.sh
timeout: 300
runas: root
- location: scripts/reload_server.sh
timeout: 300
runas: root
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/rp-api
file_exists_behavior: OVERWRITE
hooks:
BeforeInstall:
- location: scripts/install_dependencies.sh
timeout: 300
runas: root
AfterInstall:
- location: scripts/build.sh
timeout: 300
runas: root
ApplicationStart:
- location: scripts/install_dependencies.sh
timeout: 300
runas: root
- location: scripts/reload_server.sh
timeout: 300
runas: root
6 changes: 5 additions & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import morgan from "morgan";
import bodyParser from "body-parser";
import errorHandler from "./middleware/error-handler";

import attendeeRouter from "./services/attendees/attendee-router";
import authRouter from "./services/auth/auth-router";
import eventRouter from "./services/events/events-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();
Expand All @@ -26,8 +28,10 @@ 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) => {
Expand Down
14 changes: 14 additions & 0 deletions src/database.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import mongoose, { Schema } from "mongoose";
import {
AttendeeSchema,
AttendeeValidator,
} from "./services/attendees/attendee-schema";
import { RoleValidator, RoleSchema } from "./services/auth/auth-schema";
import { EventSchema, EventValidator } from "./services/events/events-schema";
import {
RegistrationSchema,
RegistrationValidator,
} from "./services/registration/registration-schema";
import {
SubscriptionSchemaValidator,
SubscriptionSchema,
Expand Down Expand Up @@ -43,4 +51,10 @@ export const Database = {
SubscriptionSchema,
SubscriptionSchemaValidator
),
ATTENDEES: initializeModel("attendees", AttendeeSchema, AttendeeValidator),
REGISTRATION: initializeModel(
"registration",
RegistrationSchema,
RegistrationValidator
),
};
43 changes: 43 additions & 0 deletions src/services/attendees/attendee-router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
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;
26 changes: 26 additions & 0 deletions src/services/attendees/attendee-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import mongoose from "mongoose";
import { z } from "zod";

// Zod schema for attendee
const AttendeeValidator = z.object({
userId: z.string(),
name: z.string(),
email: z.string().email(),
events: z.array(z.string()),
dietary_restrictions: z.string(),
priority_expiry: z.date().nullable().optional(),
points: z.number().min(0).default(0),
});

// Mongoose schema for attendee
const AttendeeSchema = new mongoose.Schema({
userId: { type: String, required: true, unique: true },
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 },
priority_expiry: { type: Date, default: null },
points: { type: Number, default: 0 },
});

export { AttendeeSchema, AttendeeValidator };
82 changes: 82 additions & 0 deletions src/services/events/event-router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
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;
47 changes: 47 additions & 0 deletions src/services/events/event-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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 };
10 changes: 10 additions & 0 deletions src/services/registration/registration-router.ts
Original file line number Diff line number Diff line change
@@ -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;
Loading