@@ -3,23 +3,30 @@ import { AppRoles } from "../roles.js";
3
3
import { z } from "zod" ;
4
4
import { zodToJsonSchema } from "zod-to-json-schema" ;
5
5
import { OrganizationList } from "../orgs.js" ;
6
- import { DynamoDBClient , PutItemCommand } from "@aws-sdk/client-dynamodb" ;
7
- import { marshall } from "@aws-sdk/util-dynamodb" ;
6
+ import {
7
+ DynamoDBClient ,
8
+ PutItemCommand ,
9
+ ScanCommand ,
10
+ } from "@aws-sdk/client-dynamodb" ;
11
+ import { marshall , unmarshall } from "@aws-sdk/util-dynamodb" ;
8
12
import config from "../config.js" ;
9
- import { DatabaseInsertError } from "../errors/index.js" ;
13
+ import { DatabaseFetchError , DatabaseInsertError } from "../errors/index.js" ;
10
14
import { randomUUID } from "crypto" ;
11
15
16
+ // POST
17
+
12
18
const repeatOptions = [ "weekly" , "biweekly" ] as const ;
13
19
14
20
const requestBodySchema = z . object ( {
15
21
title : z . string ( ) . min ( 1 ) ,
16
22
description : z . string ( ) . min ( 1 ) ,
17
- start : z . string ( ) . datetime ( ) ,
18
- end : z . optional ( z . string ( ) . datetime ( ) ) ,
23
+ start : z . string ( ) ,
24
+ end : z . optional ( z . string ( ) ) ,
19
25
location : z . string ( ) ,
20
26
locationLink : z . optional ( z . string ( ) . url ( ) ) ,
21
27
repeats : z . optional ( z . enum ( repeatOptions ) ) ,
22
28
host : z . enum ( OrganizationList ) ,
29
+ featured : z . boolean ( ) . default ( false )
23
30
} ) ;
24
31
const requestJsonSchema = zodToJsonSchema ( requestBodySchema ) ;
25
32
type EventPostRequest = z . infer < typeof requestBodySchema > ;
@@ -31,11 +38,15 @@ const responseJsonSchema = zodToJsonSchema(
31
38
} ) ,
32
39
) ;
33
40
41
+ // GET
42
+ const getResponseBodySchema = z . array ( requestBodySchema ) ;
43
+ const getResponseJsonSchema = zodToJsonSchema ( getResponseBodySchema ) ;
44
+
34
45
const dynamoClient = new DynamoDBClient ( {
35
46
region : process . env . AWS_REGION || "us-east-1" ,
36
47
} ) ;
37
48
38
- const createEvent : FastifyPluginAsync = async ( fastify , _options ) => {
49
+ const eventsPlugin : FastifyPluginAsync = async ( fastify , _options ) => {
39
50
fastify . post < { Body : EventPostRequest } > (
40
51
"/" ,
41
52
{
@@ -50,10 +61,14 @@ const createEvent: FastifyPluginAsync = async (fastify, _options) => {
50
61
async ( request , reply ) => {
51
62
try {
52
63
const entryUUID = randomUUID ( ) . toString ( ) ;
53
- const dynamoResponse = await dynamoClient . send (
64
+ await dynamoClient . send (
54
65
new PutItemCommand ( {
55
66
TableName : config . DYNAMO_TABLE_NAME ,
56
- Item : marshall ( { ...request . body , id : entryUUID } ) ,
67
+ Item : marshall ( {
68
+ ...request . body ,
69
+ id : entryUUID ,
70
+ createdBy : request . username ,
71
+ } ) ,
57
72
} ) ,
58
73
) ;
59
74
reply . send ( {
@@ -70,6 +85,33 @@ const createEvent: FastifyPluginAsync = async (fastify, _options) => {
70
85
}
71
86
} ,
72
87
) ;
88
+ fastify . get < { Body : undefined } > (
89
+ "/" ,
90
+ {
91
+ schema : {
92
+ response : { 200 : getResponseJsonSchema } ,
93
+ } ,
94
+ onRequest : async ( request , reply ) => {
95
+ await fastify . authorize ( request , reply , [ AppRoles . MANAGER ] ) ;
96
+ } ,
97
+ } ,
98
+ async ( request , reply ) => {
99
+ try {
100
+ const response = await dynamoClient . send (
101
+ new ScanCommand ( { TableName : config . DYNAMO_TABLE_NAME } ) ,
102
+ ) ;
103
+ const items = response . Items ?. map ( item => unmarshall ( item ) )
104
+ reply . send ( getResponseBodySchema . parse ( items ) ) ;
105
+ } catch ( e : unknown ) {
106
+ if ( e instanceof Error ) {
107
+ request . log . error ( "Failed to get from DynamoDB: " + e . toString ( ) ) ;
108
+ }
109
+ throw new DatabaseFetchError ( {
110
+ message : "Failed to get events from Dynamo table." ,
111
+ } ) ;
112
+ }
113
+ } ,
114
+ ) ;
73
115
} ;
74
116
75
- export default createEvent ;
117
+ export default eventsPlugin ;
0 commit comments