Skip to content

Commit

Permalink
Create an endpoint to get schools
Browse files Browse the repository at this point in the history
  • Loading branch information
Dlurak committed Mar 29, 2024
1 parent cd41e4b commit 842283a
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 82 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# BTW, this isn't used in production - please use a secure secret in production!
JWT_SECRET=secret
72 changes: 72 additions & 0 deletions src/routes/school/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import e from "@edgedb"
import Elysia, { t } from "elysia";
import { HttpStatusCode } from "elysia-http-status-code";
import { DATABASE_READ_FAILED } from "constants/responses";
import { promiseResult } from "utils/errors";
import { client } from "index";
import { responseBuilder } from "utils/response";

export const getSchools = new Elysia()
.use(HttpStatusCode())
.get(
"/",
async ({ query: { limit, offset, query }, set, httpStatus }) => {
const schoolsQuery = e.select(e.School, (s) => {
const isLikeName = e.op(s.name, "like", `%${query}%`);
const isLikeDescription = e.op(
s.description,
"like",
`%${query}%`,
);

const useFilter = !!query

return {
limit,
offset,
name: true,
description: true,
filter: useFilter
? e.op(isLikeName, "or", isLikeDescription)
: undefined,
};
});

const result = await promiseResult(() => schoolsQuery.run(client));
if (result.status === "error") {
set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR;
return DATABASE_READ_FAILED;
}

return responseBuilder("success", {
data: result.data,
message: "Successfully retrieved schools",
});
},
{
query: t.Object({
offset: t.Numeric({
minimum: 0,
default: 0,
description: "The number of schools to skip",
}),
limit: t.Numeric({
minimum: 1,
maximum: 100,
default: 20,
description: "The maximum number of schools to retrieve",
}),
query: t.Optional(
t.String({
minLength: 1,
description: "A query to search for schools",
}),
),

}),
detail: {
description: "Get the schools in a paginated manner",
tags: ["school"]
}
},
)
87 changes: 5 additions & 82 deletions src/routes/school/index.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,7 @@
import e from "@edgedb";
import {
DATABASE_READ_FAILED,
DATABASE_WRITE_FAILED,
UNAUTHORIZED,
} from "constants/responses";
import Elysia, { t } from "elysia";
import { HttpStatusCode } from "elysia-http-status-code";
import { client } from "index";
import { auth } from "plugins/auth";
import { promiseResult } from "utils/errors";
import { responseBuilder } from "utils/response";
import Elysia from "elysia";
import { getSchools } from "./get";
import { createSchool } from "./post";

export const schoolRouter = new Elysia({ prefix: "/school" })
.use(auth)
.use(HttpStatusCode())
.post(
"/",
async ({ auth, body, set, httpStatus }) => {
if (!auth.isAuthorized) {
set.status = httpStatus.HTTP_401_UNAUTHORIZED;
return UNAUTHORIZED;
}

const countQuery = e.count(
e.select(e.School, (s) => ({
filter: e.op(s.name, "=", body.name),
})),
);
const count = await promiseResult(() => countQuery.run(client));

if (count.status === "error") {
set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR;
return DATABASE_READ_FAILED;
}
if (count.data >= 1) {
set.status = httpStatus.HTTP_400_BAD_REQUEST;
return responseBuilder("error", {
error: `A school with the name ${body.name} already exists`,
});
}

const createSchoolQuery = e.insert(e.School, {
name: body.name,
description: body.description,
});
const result = await promiseResult(() => createSchoolQuery.run(client));

if (result.status === "error") {
set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR;
return DATABASE_WRITE_FAILED;
}

set.status = httpStatus.HTTP_201_CREATED;
return responseBuilder("success", {
message: `Successfully created school ${body.name}`,
data: null,
});
},
{
body: t.Object({
name: t.String({
minLength: 1,
description: "The name of the school",
examples: ["Dlool High School", "Humboldt Gymnasium", "Hogwarts"],
}),
description: t.String({
minLength: 1,
description:
"A description of the school, this is only so other users can distinguish between schools with similar names",
examples: [
"The Dlool High School in Chicago",
"Das Humboldt Gymnasium in Köln",
"Hogwarts straight out of the Harry Potter books",
],
}),
}),
detail: {
description:
"Create a new school, this requires the user to be authenthicated",
tags: ["school"],
},
},
);
.use(getSchools)
.use(createSchool);
84 changes: 84 additions & 0 deletions src/routes/school/post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import e from "@edgedb";
import {
DATABASE_READ_FAILED,
DATABASE_WRITE_FAILED,
UNAUTHORIZED,
} from "constants/responses";
import Elysia, { t } from "elysia";
import { HttpStatusCode } from "elysia-http-status-code";
import { client } from "index";
import { auth } from "plugins/auth";
import { promiseResult } from "utils/errors";
import { responseBuilder } from "utils/response";

export const createSchool = new Elysia()
.use(auth)
.use(HttpStatusCode())
.post(
"/",
async ({ auth, body, set, httpStatus }) => {
if (!auth.isAuthorized) {
set.status = httpStatus.HTTP_401_UNAUTHORIZED;
return UNAUTHORIZED;
}

const countQuery = e.count(
e.select(e.School, (s) => ({
filter: e.op(s.name, "=", body.name),
})),
);
const count = await promiseResult(() => countQuery.run(client));

if (count.status === "error") {
set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR;
return DATABASE_READ_FAILED;
}
if (count.data >= 1) {
set.status = httpStatus.HTTP_400_BAD_REQUEST;
return responseBuilder("error", {
error: `A school with the name ${body.name} already exists`,
});
}

const createSchoolQuery = e.insert(e.School, {
name: body.name,
description: body.description,
});
const result = await promiseResult(() => createSchoolQuery.run(client));

if (result.status === "error") {
set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR;
return DATABASE_WRITE_FAILED;
}

set.status = httpStatus.HTTP_201_CREATED;
return responseBuilder("success", {
message: `Successfully created school ${body.name}`,
data: null,
});
},
{
body: t.Object({
name: t.String({
minLength: 1,
description: "The name of the school",
examples: ["Dlool High School", "Humboldt Gymnasium", "Hogwarts"],
}),
description: t.String({
minLength: 1,
description:
"A description of the school, this is only so other users can distinguish between schools with similar names",
examples: [
"The Dlool High School in Chicago",
"Das Humboldt Gymnasium in Köln",
"Hogwarts straight out of the Harry Potter books",
],
}),
}),
detail: {
description:
"Create a new school, this requires the user to be authenthicated",
tags: ["school"],
},
},
)

0 comments on commit 842283a

Please sign in to comment.