Skip to content
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
3 changes: 3 additions & 0 deletions api-examples/deleteEvent.rest
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
DELETE http://localhost:3000/events/683f38cbecb0f8e7404c76a2
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2ODNkODY0YzQ5YmI1MDYxNTM3YjA1NTMiLCJuYW1lX2ZpcnN0IjoiQm9iIiwibmFtZV9sYXN0IjoiQnVpbGRlciIsImVtYWlsIjoiYm9iQGJ1aWxkZXIuY29tIiwidXNlcm5hbWUiOiJib2IiLCJzYXZlZF9ldmVudHMiOltdLCJyb2xlIjoidXNlciJ9.8f-bElJ6461QVgMFeA0rE72ionI5iuB7JOLrsa159fQ
6 changes: 3 additions & 3 deletions api-examples/login.rest
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ POST http://localhost:3000/auth/login
Content-Type: application/json

{
"email": "admin@example.com",
"password": "supersecretadminpassword",
"username": "admin"
"email": "bob@builder.com",
"password": "builder",
"username": "bob"
}
14 changes: 14 additions & 0 deletions api-examples/updateEvent.rest
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
PUT http://localhost:3000/events/683f38cbecb0f8e7404c76a1
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2ODNkODY0YzQ5YmI1MDYxNTM3YjA1NTMiLCJuYW1lX2ZpcnN0IjoiQm9iIiwibmFtZV9sYXN0IjoiQnVpbGRlciIsImVtYWlsIjoiYm9iQGJ1aWxkZXIuY29tIiwidXNlcm5hbWUiOiJib2IiLCJzYXZlZF9ldmVudHMiOltdLCJyb2xlIjoidXNlciJ9.8f-bElJ6461QVgMFeA0rE72ionI5iuB7JOLrsa159fQ

{
"mode": "other",
"name": "Something",
"description": "For something",
"location": "Earth",
"date": "Tomorrow",
"price": 42,
"distance": 0,
"url": "http://localhost:3000"
}
76 changes: 64 additions & 12 deletions src/controllers/event.controller.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// deno-lint-ignore-file require-await
import { Context, ObjectId, RouterContext, Status } from '../../deps.ts';
import { eventService } from '../services/event.service.ts';
import { generateEvents } from '../services/openai.service.ts';
import { eventFilterSchema } from 'models/event.model.ts';
import { eventFilterSchema, FullEvent } from 'models/event.model.ts';

export const getAllEvents = async (ctx: Context) => {
const params = ctx.request.url.searchParams;
Expand Down Expand Up @@ -55,6 +54,69 @@ export const getEventById = async (ctx: RouterContext<'/:id'>) => {
ctx.response.body = event;
};

export const updateEventById = async (ctx: RouterContext<'/:id'>) => {
const user = ctx.state.user;

if (!user) {
ctx.response.status = Status.Unauthorized;
ctx.response.body = { message: 'User not authenticated' };
return;
}

const id: string = ctx.params.id;
const event: FullEvent = await ctx.request.body.json();

if (!ObjectId.isValid(id)) {
ctx.response.status = Status.BadRequest;
ctx.response.body = `Invalid event id "${id}"`;
return;
}

if (!eventService.isEvent(event)) {
ctx.response.status = Status.BadRequest;
ctx.response.body = `Failed to validate event body`;
return;
}

const result = await eventService.updateEventById(id, event);

if (!result.acknowledged) {
ctx.response.status = Status.NotFound;
ctx.response.body = `Failed to update event by id "${id}"`;
return;
}

ctx.response.body = { message: `Updated event id "${id}"` };
};

export const deleteEventById = async (ctx: RouterContext<'/:id'>) => {
const user = ctx.state.user;

if (!user) {
ctx.response.status = Status.Unauthorized;
ctx.response.body = { message: 'User not authenticated' };
return;
}

const id: string = ctx.params.id;

if (!ObjectId.isValid(id)) {
ctx.response.status = Status.BadRequest;
ctx.response.body = `Invalid event id "${id}"`;
return;
}

const result = await eventService.deleteEventById(id);

if (result.deletedCount == 0) {
ctx.response.status = Status.NotFound;
ctx.response.body = `Could not find event id "${id}"`;
return;
}

ctx.response.body = { message: `Successfully deleted event id "${id}"` };
};

export const saveNewEvent = async (ctx: Context) => {
// Things to note. Will this need admin authorisation? Possible need to implement token auth on this route or admin auth middleware?
const event = await ctx.request.body.json();
Expand Down Expand Up @@ -97,13 +159,3 @@ export const saveEventsCronHandler = async (ctx: Context) => {
console.log('There were no events to save');
}
};

export const updateEvent = async (ctx: Context) => {
// TODO: Update event in DB
ctx.response.body = { message: `Update event of params.id` };
};

export const deleteEvent = async (ctx: Context) => {
// TODO: Delete event from DB
ctx.response.body = { message: `Delete event params.id` };
};
8 changes: 6 additions & 2 deletions src/routes/event.routes.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Router } from '../../deps.ts';
import {
deleteEventById,
getAllEvents,
getEventById,
saveEventsCronHandler,
saveNewEvent,
updateEventById,
} from '../controllers/event.controller.ts';
import ProtectRoute from '../middleware/protectRoute.ts';
import protectAdmin from '../middleware/requireAdmin.ts';

const router = new Router();

Expand All @@ -13,11 +17,11 @@ const router = new Router();
// -> to controllers
router.get('/', getAllEvents);
router.get('/:id', getEventById);
router.put('/:id', ProtectRoute, protectAdmin, updateEventById);
router.delete('/:id', ProtectRoute, protectAdmin, deleteEventById);
router.post('/save-event', saveNewEvent);
router.post('/cron/save-events', saveEventsCronHandler);
// router.post("/")
// router.put("/:id", updateEvent)
// router.delete("/:id", deleteEvent)

// router.post("/generate", generateEvents) (using the openAi service)

Expand Down
10 changes: 10 additions & 0 deletions src/services/event.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ const getEventById = async (id: string): Promise<FullEvent | null> => {
return await events.findOne({ _id: new ObjectId(id) });
};

const updateEventById = async (id: string, event: FullEvent) => {
return await events.updateOne({ _id: new ObjectId(id) }, { $set: event });
};

const deleteEventById = async (id: string) => {
return await events.deleteOne({ _id: new ObjectId(id) });
};

const databaseIncludes = async (event: FullEvent): Promise<boolean> => {
const existingEvent = await events.findOne({ eventKey: event.eventKey });
return existingEvent !== null;
Expand Down Expand Up @@ -93,6 +101,8 @@ const saveEvents = async (input: Event | CompleteEventType) => {
export const eventService = {
getAllEvents,
getEventById,
updateEventById,
deleteEventById,
saveEvents,
isEvent,
};