Skip to content
This repository has been archived by the owner on Oct 18, 2024. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'origin/main' into 122-add-filtering-by-…
Browse files Browse the repository at this point in the history
…restriction-code-to-websoc-endpoint
  • Loading branch information
andrew-wang0 committed Apr 24, 2024
2 parents b947e67 + 4bbd53d commit b7a47d8
Show file tree
Hide file tree
Showing 44 changed files with 1,677 additions and 1,508 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const config = {
],
rules: {
"no-unused-vars": "off",
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-unused-vars": [
"error",
{
Expand All @@ -28,6 +27,7 @@ const config = {
caughtErrorsIgnorePattern: "^_",
},
],
"import/consistent-type-specifier-style": ["error", "prefer-top-level"],
"import/first": "error",
"import/newline-after-import": "error",
"import/order": [
Expand Down
4 changes: 2 additions & 2 deletions .github/actions/setup-node-and-pnpm/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ runs:

steps:
- name: Setup Node.js environment
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
with:
node-version: lts/*

Expand All @@ -25,7 +25,7 @@ runs:
run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT

- name: Setup pnpm cache
uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
uses: ./.github/actions/setup-node-and-pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile
run: pnpm install -P false --frozen-lockfile

- name: Build API
run: pnpm build --filter="@apps/api"
Expand All @@ -71,7 +71,7 @@ jobs:
uses: ./.github/actions/setup-node-and-pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile
run: pnpm install -P false --frozen-lockfile

- name: Build documentation
run: pnpm build --filter="@apps/docs"
Expand All @@ -94,7 +94,7 @@ jobs:
uses: ./.github/actions/setup-node-and-pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile
run: pnpm install -P false --frozen-lockfile

- name: Build services
run: pnpm build --filter="@services/*"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/destroy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
run: pnpm --filter="@apps/api" cdk-app destroy

- name: Set API staging environment to inactive
uses: strumwolf/delete-deployment-environment@195215d2c5602aee6fb4b9cf0853970decca9e7a # v2.3.0
uses: strumwolf/delete-deployment-environment@a4825dd9648c57da8437a4885c3fcad58beac69c # v3.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
environment: staging-${{ github.event.pull_request.number }}
Expand Down Expand Up @@ -85,7 +85,7 @@ jobs:
run: pnpm --filter="@tools/cdk" docs destroy

- name: Set documentation staging environment as inactive
uses: strumwolf/delete-deployment-environment@195215d2c5602aee6fb4b9cf0853970decca9e7a # v2.3.0
uses: strumwolf/delete-deployment-environment@a4825dd9648c57da8437a4885c3fcad58beac69c # v3.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
environment: staging-${{ github.event.pull_request.number }}-docs
Expand Down
3 changes: 2 additions & 1 deletion apps/api/bronya.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { chmodSync, copyFileSync } from "node:fs";
import { join, resolve } from "node:path";

import { Api, type ApiConstructProps } from "@bronya.js/api-construct";
import { Api } from "@bronya.js/api-construct";
import type { ApiConstructProps } from "@bronya.js/api-construct";
import { createApiCliPlugins } from "@bronya.js/api-construct/plugins/cli";
import { isCdk } from "@bronya.js/core";
import { PrismaClient } from "@libs/db";
Expand Down
22 changes: 11 additions & 11 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,32 @@
},
"dependencies": {
"@apollo/server": "4.10.0",
"@aws-sdk/client-lambda": "3.501.0",
"@aws-sdk/client-lambda": "3.525.0",
"@graphql-tools/load-files": "7.0.0",
"@graphql-tools/merge": "9.0.1",
"@graphql-tools/utils": "10.0.13",
"@graphql-tools/merge": "9.0.3",
"@graphql-tools/utils": "10.1.0",
"@libs/db": "workspace:^",
"@libs/lambda": "workspace:^",
"@libs/uc-irvine-lib": "workspace:^",
"@libs/utils": "workspace:^",
"@libs/websoc-utils": "workspace:^",
"@peterportal-api/types": "workspace:^",
"@services/websoc-proxy": "workspace:^",
"aws-cdk-lib": "2.124.0",
"aws-cdk-lib": "2.131.0",
"cheerio": "1.0.0-rc.12",
"cross-fetch": "4.0.0",
"graphql": "16.8.1",
"zod": "3.22.4"
},
"devDependencies": {
"@bronya.js/api-construct": "0.11.3",
"@bronya.js/core": "0.11.3",
"@types/aws-lambda": "8.10.132",
"aws-cdk": "2.124.0",
"dotenv": "16.4.1",
"@bronya.js/api-construct": "0.11.4",
"@bronya.js/core": "0.11.4",
"@types/aws-lambda": "8.10.135",
"aws-cdk": "2.131.0",
"dotenv": "16.4.5",
"dotenv-cli": "7.3.0",
"esbuild": "0.20.0",
"tsx": "4.7.0"
"esbuild": "0.20.1",
"tsx": "4.7.1"
},
"//": "the CDK configuration in this config file is used in the deployment package, @tools/cdk"
}
3 changes: 1 addition & 2 deletions apps/api/src/routes/v1/graphql/lib.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { BaseContext, HTTPGraphQLResponse } from "@apollo/server";
import type { IFieldResolver } from "@graphql-tools/utils";
import { isErrorResponse } from "@peterportal-api/types";
import type { RawResponse } from "@peterportal-api/types";
import { GraphQLError } from "graphql/error";

Expand Down Expand Up @@ -58,7 +57,7 @@ export const proxyRestApi =
};
});

if (isErrorResponse(data)) {
if (!data.success) {
throw new GraphQLError(data.message, {
extensions: {
code: data.error.toUpperCase().replace(" ", "_"),
Expand Down
1 change: 1 addition & 0 deletions apps/api/src/routes/v1/graphql/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { geTransform, proxyRestApi } from "./lib";

export const resolvers: ApolloServerOptions<BaseContext>["resolvers"] = {
Query: {
allTermDates: proxyRestApi("/v1/rest/calendar"),
calendar: proxyRestApi("/v1/rest/calendar"),
course: proxyRestApi("/v1/rest/courses", { pathArg: "courseId" }),
courses: proxyRestApi("/v1/rest/courses", { argsTransform: geTransform }),
Expand Down
22 changes: 15 additions & 7 deletions apps/api/src/routes/v1/graphql/schema/calendar.graphql
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
"An object that includes important dates for a specified quarter."
type QuarterDates {
"When instruction begins for the given quarter."
type TermDates {
"The year of the given term."
year: String!
"The quarter of the given term."
quarter: String!
"When instruction begins for the given term."
instructionStart: Date!
"When instruction ends for the given quarter."
"When instruction ends for the given term."
instructionEnd: Date!
"When finals begin for the given quarter."
"When finals begin for the given term."
finalsStart: Date!
"When finals end for the given quarter."
"When finals end for the given term."
finalsEnd: Date!
"When the Schedule of Classes becomes available for the given term."
socAvailable: Date!
}

extend type Query {
"Get important dates for a quarter."
calendar(year: String!, quarter: Quarter!): QuarterDates!
"Get all available terms and their important dates."
allTermDates: [TermDates!]!
"Get important dates for a term."
calendar(year: String!, quarter: Quarter!): TermDates!
}
73 changes: 24 additions & 49 deletions apps/api/src/routes/v1/rest/calendar/+endpoint.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { PrismaClient } from "@libs/db";
import { createHandler } from "@libs/lambda";
import { getTermDateData } from "@libs/uc-irvine-lib/registrar";
import type { Quarter, QuarterDates } from "@peterportal-api/types";
import { ZodError } from "zod";
import type { QuarterDates } from "@peterportal-api/types";

import { QuerySchema } from "./schema";

Expand All @@ -14,56 +12,33 @@ async function onWarm() {

export const GET = createHandler(async (event, context, res) => {
const headers = event.headers;
const query = event.queryStringParameters;
const query = event.queryStringParameters ?? {};
const requestId = context.awsRequestId;

try {
const where = QuerySchema.parse(query);
const maybeParsed = QuerySchema.safeParse(query);

const result = await prisma.calendarTerm.findFirst({
where,
select: {
instructionStart: true,
instructionEnd: true,
finalsStart: true,
finalsEnd: true,
},
});

if (result) {
return res.createOKResult<QuarterDates>(result, headers, requestId);
}

const termDateData = await getTermDateData(
where.quarter === "Fall" ? where.year : (parseInt(where.year) - 1).toString(10),
);

await prisma.calendarTerm.createMany({
data: Object.entries(termDateData).map(([term, data]) => ({
year: term.split(" ")[0],
quarter: term.split(" ")[1] as Quarter,
...data,
})),
});

if (!Object.keys(termDateData).length) {
return res.createErrorResult(
400,
`The requested term, ${where.year} ${where.quarter}, is currently unavailable.`,
requestId,
);
}

return res.createOKResult(
termDateData[[where.year, where.quarter].join(" ")],
headers,
if (!maybeParsed.success)
return res.createErrorResult(
400,
maybeParsed.error.issues.map((issue) => issue.message).join("; "),
requestId,
);
} catch (error) {
if (error instanceof ZodError) {
const messages = error.issues.map((issue) => issue.message);
return res.createErrorResult(400, messages.join("; "), requestId);
}
return res.createErrorResult(400, error, requestId);

const { data: where } = maybeParsed;

if ("year" in where) {
const result = await prisma.calendarTerm.findFirst({ where });
return result
? res.createOKResult<QuarterDates>(result, headers, requestId)
: res.createErrorResult(
400,
`The requested term, ${where.year} ${where.quarter}, is currently unavailable.`,
requestId,
);
}
return res.createOKResult(
await prisma.calendarTerm.findMany({ orderBy: { instructionStart: "asc" } }),
headers,
requestId,
);
}, onWarm);
20 changes: 11 additions & 9 deletions apps/api/src/routes/v1/rest/calendar/schema.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { quarters } from "@peterportal-api/types";
import { z } from "zod";

export const QuerySchema = z.object({
year: z
.string({ required_error: 'Parameter "year" not provided' })
.length(4, { message: "Invalid year provided" }),
export const QuerySchema = z
.object({
year: z
.string({ required_error: 'Parameter "year" not provided' })
.length(4, { message: "Invalid year provided" }),

quarter: z.enum(quarters, {
required_error: 'Parameter "quarter" not provided',
invalid_type_error: "Invalid quarter provided",
}),
});
quarter: z.enum(quarters, {
required_error: 'Parameter "quarter" not provided',
invalid_type_error: "Invalid quarter provided",
}),
})
.or(z.object({}));

export type Query = z.infer<typeof QuerySchema>;
4 changes: 2 additions & 2 deletions apps/api/src/routes/v1/rest/websoc/+config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { constructs, esbuildOptions } from "../../../../../bronya.config";
export const overrides: ApiPropsOverride = {
constructs: {
...constructs,
functionProps: (scope, id) => ({
...constructs.functionProps?.(scope, id),
functionProps: (scope, id, route) => ({
...constructs.functionProps?.(scope, id, route),
role: new Role(scope, `${id}-v1-rest-websoc-role`, {
assumedBy: new ServicePrincipal("lambda.amazonaws.com"),
managedPolicies: [
Expand Down
8 changes: 4 additions & 4 deletions apps/api/src/routes/v1/rest/websoc/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,16 +142,16 @@ export function constructPrismaQuery(parsedQuery: Query): Prisma.WebsocSectionWh
if (parsedQuery.fullCourses && parsedQuery.fullCourses !== "ANY") {
switch (parsedQuery.fullCourses) {
case "FullOnly":
AND.push({ sectionFull: true, waitlistFull: true });
AND.push({ sectionFull: true }, { waitlistFull: true });
break;
case "OverEnrolled":
case "Overenrolled":
AND.push({ overEnrolled: true });
break;
case "SkipFull":
AND.push({ sectionFull: true, waitlistFull: false });
AND.push({ sectionFull: false });
break;
case "SkipFullWaitlist":
AND.push({ sectionFull: false, waitlistFull: false });
AND.push({ sectionFull: true }, { waitlistFull: false });
}
}

Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/routes/v1/rest/websoc/{id}/+config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { constructs, esbuildOptions } from "../../../../../../bronya.config";
export const overrides: ApiPropsOverride = {
constructs: {
...constructs,
functionProps: (scope, id) => ({
...constructs.functionProps?.(scope, id),
functionProps: (scope, id, route) => ({
...constructs.functionProps?.(scope, id, route),
role: new Role(scope, `${id}-v1-rest-websoc-id-role`, {
assumedBy: new ServicePrincipal("lambda.amazonaws.com"),
managedPolicies: [
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"@docusaurus/module-type-aliases": "2.4.3",
"@docusaurus/types": "2.4.3",
"@tsconfig/docusaurus": "2.0.2",
"@types/node": "20.11.10",
"@types/node": "20.11.24",
"typescript": "5.3.3"
}
}
4 changes: 2 additions & 2 deletions libs/db/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
"studio:prod": "dotenv -e ../../.env.production -- prisma studio"
},
"dependencies": {
"@prisma/client": "5.8.1"
"@prisma/client": "5.10.2"
},
"devDependencies": {
"prisma": "5.8.1"
"prisma": "5.10.2"
}
}
9 changes: 5 additions & 4 deletions libs/db/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ enum RestrictionCode {
model CalendarTerm {
year String
quarter Quarter
instructionStart DateTime
instructionEnd DateTime
finalsStart DateTime
finalsEnd DateTime
instructionStart DateTime @db.Date
instructionEnd DateTime @db.Date
finalsStart DateTime @db.Date
finalsEnd DateTime @db.Date
socAvailable DateTime @default("1970-01-01T00:00:00Z") @db.Date
@@id([year, quarter])
@@unique([year, quarter], name: "idx")
Expand Down
4 changes: 2 additions & 2 deletions libs/lambda/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
"main": "src/index.ts",
"types": "src/index.ts",
"dependencies": {
"winston": "3.11.0"
"winston": "3.12.0"
},
"devDependencies": {
"@peterportal-api/types": "workspace:^",
"@types/aws-lambda": "8.10.132"
"@types/aws-lambda": "8.10.135"
}
}
Loading

0 comments on commit b7a47d8

Please sign in to comment.