-
Notifications
You must be signed in to change notification settings - Fork 0
events-rsvp get all rsvps for an event route created #427
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
base: main
Are you sure you want to change the base?
Changes from 3 commits
86a2126
440fae7
9e2f331
9e6ba13
96a29a1
8b5a252
258a044
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| import { FastifyPluginAsync } from "fastify"; | ||
| import rateLimiter from "api/plugins/rateLimiter.js"; | ||
| import { withRoles, withTags } from "api/components/index.js"; | ||
| import { QueryCommand } from "@aws-sdk/client-dynamodb"; | ||
| import { unmarshall } from "@aws-sdk/util-dynamodb"; | ||
| import { getUserOrgRoles } from "api/functions/organizations.js"; | ||
| import { | ||
| UnauthenticatedError, | ||
| UnauthorizedError, | ||
| ValidationError, | ||
| } from "common/errors/index.js"; | ||
| import * as z from "zod/v4"; | ||
| import { verifyUiucAccessToken } from "api/functions/uin.js"; | ||
| import { checkPaidMembership } from "api/functions/membership.js"; | ||
| import { FastifyZodOpenApiTypeProvider } from "fastify-zod-openapi"; | ||
| import { genericConfig } from "common/config.js"; | ||
|
|
||
| const rsvpItemSchema = z.object({ | ||
| eventId: z.string(), | ||
| userId: z.string(), | ||
| isPaidMember: z.boolean(), | ||
| createdAt: z.string(), | ||
| }); | ||
| const rsvpListSchema = z.array(rsvpItemSchema); | ||
|
|
||
| const rsvpRoutes: FastifyPluginAsync = async (fastify, _options) => { | ||
| await fastify.register(rateLimiter, { | ||
| limit: 30, | ||
| duration: 30, | ||
| rateLimitIdentifier: "rsvp", | ||
| }); | ||
| fastify.withTypeProvider<FastifyZodOpenApiTypeProvider>().post( | ||
| "/:orgId/event/:eventId", | ||
| { | ||
| schema: withTags(["RSVP"], { | ||
| summary: "Submit an RSVP for an event.", | ||
| params: z.object({ | ||
| eventId: z.string().min(1).meta({ | ||
| description: "The previously-created event ID in the events API.", | ||
| }), | ||
| }), | ||
| headers: z.object({ | ||
| "x-uiuc-token": z.jwt().min(1).meta({ | ||
| description: | ||
| "An access token for the user in the UIUC Entra ID tenant.", | ||
| }), | ||
|
Comment on lines
+39
to
+42
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainScript executed: #!/bin/bash
# Search for z.jwt() usage and any custom JWT schema definitions
rg -n "z\.jwt|\.jwt\(\)" --type ts -C 3Repository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Check for Zod version in package.json and any custom extensions
cat package.json | grep -A2 -B2 "zod"Repository: acm-uiuc/core <shell_result> </shell_result> Script executed: #!/bin/bash
# Read the specific file to see context around lines 43-46 and 95-98
head -100 src/api/routes/rsvp.ts | tail -60Repository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Search for any zod extensions or custom schema definitions
rg -n "z\.|extend\(|.jwt" src/api/routes/rsvp.ts -C 2Repository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Search for jwt function definition or Zod extension
rg -n "jwt\s*[:=]|\.jwt\s*=|extend.*jwt" --type tsRepository: acm-uiuc/core <shell_result> </shell_result> Script executed: #!/bin/bash
# Check imports in rsvp.ts to understand where z comes from
head -20 src/api/routes/rsvp.tsRepository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Look for zod configuration or extensions files
fd -e ts -e js | xargs rg -l "z\.extend|ZodType.*jwt" | head -20Repository: acm-uiuc/core <shell_result> </shell_result> Script executed: #!/bin/bash
# Check package.json for zod version and look at dependencies
cat package.json | head -50Repository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Search for any z.jwt or jwt extension setup
rg -n "jwt" --type ts -g "!node_modules" | grep -i "extend\|z\.jwt\|define" | head -20Repository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Look for zod setup or configuration files
fd -type f \( -name "*zod*" -o -name "*config*" \) --type ts --type js | head -20Repository: acm-uiuc/core <shell_result> stderr: </shell_result> Script executed: #!/bin/bash
# Search in common directory for any Zod extensions
rg -n "z\.|jwt" src/common --type ts -C 2 | head -50Repository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Check API workspace for zod version
cat src/api/package.json | grep -A 2 -B 2 "zod"Repository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Search for where jwt() might be extended onto z
rg -n "\.jwt\s*=" --type tsRepository: acm-uiuc/core <shell_result> </shell_result> Script executed: #!/bin/bash
# Look for any custom Zod types or extensions
rg -n "extend\|\.jwt\|jwt\(" --type ts | grep -v "x-uiuc-token" | head -30Repository: acm-uiuc/core <shell_result> </shell_result> Script executed: #!/bin/bash
# Check if zod has jwt method in v4
web_search "Zod v4 jwt method"Repository: acm-uiuc/core <shell_result> stderr: </shell_result> Script executed: #!/bin/bash
# Look for .d.ts files or type augmentation
find . -name "*.d.ts" -o -name "*types*" | grep -v node_modules | head -20Repository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Search for any Zod augmentation or type declaration
rg -n "declare|augment|namespace.*z|interface.*z" --type ts | grep -i zod | head -20Repository: acm-uiuc/core <shell_result> </shell_result> Script executed: #!/bin/bash
# Check if there's a tsconfig that might reveal anything
cat tsconfig.json | head -50Repository: acm-uiuc/core <shell_result> stderr: </shell_result> Script executed: #!/bin/bash
# More thorough search for "jwt" across all files
rg -n "jwt" --type ts -C 1 | head -50Repository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Read the API types file which likely contains the jwt() extension
cat src/api/types.d.tsRepository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Also check the resources types
cat src/api/resources/types.d.tsRepository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Search for fastify-zod-openapi imports and usage
rg -n "fastify-zod-openapi" --type tsRepository: acm-uiuc/core <shell_result> stdout: </shell_result> Script executed: #!/bin/bash
# Check if there's any setup file that might extend Zod
rg -n "import.*z|from.*zod" src/api --type ts | head -20Repository: acm-uiuc/core <shell_result> stdout: </shell_result> Zod v4 jwt method <web_search_result> Fix Zod v4 provides Note: 🤖 Prompt for AI Agents |
||
| }), | ||
| }), | ||
| }, | ||
| async (request, reply) => { | ||
| const accessToken = request.headers["x-uiuc-token"]; | ||
| const verifiedData = await verifyUiucAccessToken({ | ||
| accessToken, | ||
| logger: request.log, | ||
| }); | ||
| const { userPrincipalName: upn, givenName, surname } = verifiedData; | ||
| const netId = upn.replace("@illinois.edu", ""); | ||
| if (netId.includes("@")) { | ||
| request.log.error( | ||
| `Found UPN ${upn} which cannot be turned into NetID via simple replacement.`, | ||
| ); | ||
| throw new ValidationError({ | ||
| message: "ID token could not be parsed.", | ||
| }); | ||
| } | ||
| const isPaidMember = await checkPaidMembership({ | ||
| netId, | ||
| dynamoClient: fastify.dynamoClient, | ||
| redisClient: fastify.redisClient, | ||
| logger: request.log, | ||
| }); | ||
| const entry = { | ||
| partitionKey: `${request.params.eventId}#${upn}`, | ||
| eventId: request.params.eventId, | ||
| userId: upn, | ||
| isPaidMember, | ||
| createdAt: "", | ||
| }; | ||
| }, | ||
|
Comment on lines
68
to
81
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. POST handler is incomplete — entry is created but never persisted or returned. The handler constructs an RSVP
The handler needs to persist the entry and return a response. Example fix: const entry = {
partitionKey: `${request.params.eventId}#${upn}`,
eventId: request.params.eventId,
userId: upn,
isPaidMember,
- createdAt: "",
+ createdAt: new Date().toISOString(),
};
+ const putCommand = new PutItemCommand({
+ TableName: genericConfig.RsvpDynamoTableName, // Add this config
+ Item: marshall(entry),
+ });
+ await fastify.dynamoClient.send(putCommand);
+ return reply.status(201).send(entry);
},You'll also need to import
🤖 Prompt for AI Agents |
||
| ); | ||
| fastify.withTypeProvider<FastifyZodOpenApiTypeProvider>().get( | ||
| "/:orgId/event/:eventId", | ||
| { | ||
| schema: withTags(["RSVP"], { | ||
| summary: "Get all RSVPs for an event.", | ||
| params: z.object({ | ||
| eventId: z.string().min(1).meta({ | ||
| description: "The previously-created event ID in the events API.", | ||
| }), | ||
| orgId: z.string().min(1).meta({ | ||
| description: "The organization ID the event belongs to.", | ||
| }), | ||
| }), | ||
| headers: z.object({ | ||
| "x-uiuc-token": z.jwt().min(1).meta({ | ||
| description: | ||
| "An access token for the user in the UIUC Entra ID tenant.", | ||
| }), | ||
| }), | ||
| }), | ||
| }, | ||
| async (request, reply) => { | ||
| const commnand = new QueryCommand({ | ||
| TableName: genericConfig.EventsDynamoTableName, | ||
| IndexName: "EventIdIndex", | ||
| KeyConditionExpression: "eventId = :eid", | ||
| ExpressionAttributeValues: { | ||
| ":eid": { S: request.params.eventId }, | ||
| }, | ||
| }); | ||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const response = await fastify.dynamoClient.send(commnand); | ||
| const items = response.Items?.map((item) => unmarshall(item)) || []; | ||
| return reply.send(items as z.infer<typeof rsvpListSchema>); | ||
| }, | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ); | ||
| }; | ||
|
|
||
| export default rsvpRoutes; | ||
Uh oh!
There was an error while loading. Please reload this page.