1
- import { FastifyPluginAsync } from "fastify" ;
1
+ import { FastifyPluginAsync , FastifyRequest } from "fastify" ;
2
2
import { AppRoles } from "../roles.js" ;
3
3
import { z } from "zod" ;
4
4
import { zodToJsonSchema } from "zod-to-json-schema" ;
@@ -8,10 +8,11 @@ import {
8
8
PutItemCommand ,
9
9
ScanCommand ,
10
10
} from "@aws-sdk/client-dynamodb" ;
11
+ import { genericConfig } from "../config.js" ;
11
12
import { marshall , unmarshall } from "@aws-sdk/util-dynamodb" ;
12
- import config from "../config.js" ;
13
13
import { DatabaseFetchError , DatabaseInsertError } from "../errors/index.js" ;
14
14
import { randomUUID } from "crypto" ;
15
+ import moment from 'moment-timezone' ;
15
16
16
17
// POST
17
18
@@ -37,8 +38,10 @@ const requestBodySchema = baseBodySchema
37
38
message : "repeats is required when repeatEnds is defined" ,
38
39
} ) ;
39
40
41
+
40
42
type EventPostRequest = z . infer < typeof requestBodySchema > ;
41
43
44
+
42
45
const responseJsonSchema = zodToJsonSchema (
43
46
z . object ( {
44
47
id : z . string ( ) ,
@@ -50,6 +53,14 @@ const responseJsonSchema = zodToJsonSchema(
50
53
const getResponseBodySchema = z . array ( requestBodySchema ) ;
51
54
const getResponseJsonSchema = zodToJsonSchema ( getResponseBodySchema ) ;
52
55
56
+
57
+ const getQueryParams = z . object ( {
58
+ upcomingOnly : z . boolean ( ) . default ( false ) ,
59
+ } )
60
+ type EventsGetQueryParams = z . infer < typeof getQueryParams > ;
61
+ const getQueryParamsJsonSchema = zodToJsonSchema ( getResponseBodySchema ) ;
62
+
63
+
53
64
const dynamoClient = new DynamoDBClient ( {
54
65
region : process . env . AWS_REGION || "us-east-1" ,
55
66
} ) ;
@@ -75,7 +86,7 @@ const eventsPlugin: FastifyPluginAsync = async (fastify, _options) => {
75
86
randomUUID ( ) . toString ( ) ;
76
87
await dynamoClient . send (
77
88
new PutItemCommand ( {
78
- TableName : config . DYNAMO_TABLE_NAME ,
89
+ TableName : genericConfig . DynamoTableName ,
79
90
Item : marshall ( {
80
91
...request . body ,
81
92
id : entryUUID ,
@@ -97,20 +108,48 @@ const eventsPlugin: FastifyPluginAsync = async (fastify, _options) => {
97
108
}
98
109
} ,
99
110
) ;
100
- fastify . get < { Body : undefined } > (
111
+ type EventsGetRequest = { Body : undefined , Querystring ?: EventsGetQueryParams }
112
+ fastify . get < EventsGetRequest > (
101
113
"/" ,
102
114
{
103
115
schema : {
116
+ querystring : {
117
+ upcomingOnly : { type : 'boolean' } ,
118
+ } ,
104
119
response : { 200 : getResponseJsonSchema } ,
105
120
} ,
106
121
} ,
107
- async ( request , reply ) => {
122
+ async ( request : FastifyRequest < EventsGetRequest > , reply ) => {
123
+ const upcomingOnly = request . query ?. upcomingOnly || false ;
108
124
try {
109
125
const response = await dynamoClient . send (
110
- new ScanCommand ( { TableName : config . DYNAMO_TABLE_NAME } ) ,
126
+ new ScanCommand ( { TableName : genericConfig . DynamoTableName } ) ,
111
127
) ;
112
128
const items = response . Items ?. map ( ( item ) => unmarshall ( item ) ) ;
113
- reply . send ( getResponseBodySchema . parse ( items ) ) ;
129
+ const currentTimeChicago = moment ( ) . tz ( "America/Chicago" ) ;
130
+ let parsedItems = getResponseBodySchema . parse ( items ) ;
131
+ if ( upcomingOnly ) {
132
+ parsedItems = parsedItems . filter ( item => {
133
+ try {
134
+ if ( ! item . repeatEnds || item . repeatEnds === 'never' ) {
135
+ return true ;
136
+ }
137
+ if ( ! item . repeats ) {
138
+ const end = item . end || item . start ;
139
+ const momentEnds = moment . tz ( end , "America/Chicago" )
140
+ const diffTime = currentTimeChicago . diff ( momentEnds ) ;
141
+ return Boolean ( diffTime <= genericConfig . UpcomingEventThresholdSeconds )
142
+ }
143
+ const momentRepeatEnds = moment . tz ( item . repeatEnds , "America/Chicago" )
144
+ const diffTime = currentTimeChicago . diff ( momentRepeatEnds ) ;
145
+ return Boolean ( diffTime <= genericConfig . UpcomingEventThresholdSeconds ) ;
146
+ } catch ( e ) {
147
+ request . log . warn ( `Could not compute upcoming event status for event ${ item . title } !` )
148
+ return false ;
149
+ }
150
+ } )
151
+ }
152
+ reply . send ( parsedItems ) ;
114
153
} catch ( e : unknown ) {
115
154
if ( e instanceof Error ) {
116
155
request . log . error ( "Failed to get from DynamoDB: " + e . toString ( ) ) ;
0 commit comments