Skip to content

Commit f8176e6

Browse files
committed
#8 update serverless file with SQS queus, new Dynamo structure and new endpoints
1 parent 81dc06b commit f8176e6

1 file changed

Lines changed: 188 additions & 37 deletions

File tree

serverless/api/serverless.yml

Lines changed: 188 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ provider:
1313
JAILDATA_TABLE: !Ref JailDataTable
1414
ERROR_CACHE_TABLE: !Ref ErrorCacheTable
1515
SERVICE_NAME: ${self:service}
16+
AWS_ACCOUNT_ID: !Ref "AWS::AccountId"
17+
BATCH_PROCESSING_QUEUE_URL: !Ref BatchProcessingQueue
1618
iam:
1719
role:
1820
statements:
1921
- Effect: Allow
2022
Action:
2123
- dynamodb:BatchGetItem
24+
- dynamodb:BatchWriteItem
2225
- dynamodb:GetItem
2326
- dynamodb:PutItem
2427
- dynamodb:Query
@@ -53,6 +56,16 @@ provider:
5356
Resource:
5457
- !Ref AlertTopic
5558

59+
- Effect: Allow
60+
Action:
61+
- sqs:SendMessage
62+
- sqs:ReceiveMessage
63+
- sqs:DeleteMessage
64+
- sqs:GetQueueAttributes
65+
Resource:
66+
- !GetAtt BatchProcessingQueue.Arn
67+
- !GetAtt BatchProcessingDeadLetterQueue.Arn
68+
5669
apiGateway:
5770
disableDefaultEndpoint: true
5871
apiKeys:
@@ -124,40 +137,32 @@ resources:
124137
TopicArn: !Ref AlertTopic
125138
Endpoint: ${ssm:/jaildata/alert-email}
126139

127-
# DynamoDB table for jail data
140+
# DynamoDB table for jail data (single table design)
128141
JailDataTable:
129142
Type: AWS::DynamoDB::Table
130143
Properties:
131144
TableName: jaildata-${self:provider.stage}
132145
BillingMode: PAY_PER_REQUEST
133146
AttributeDefinitions:
134-
- AttributeName: detaineeId
147+
- AttributeName: PK
135148
AttributeType: S
136-
- AttributeName: timestamp
149+
- AttributeName: SK
137150
AttributeType: S
138-
- AttributeName: status
151+
- AttributeName: GSI1PK
139152
AttributeType: S
140-
- AttributeName: createdDate
153+
- AttributeName: GSI1SK
141154
AttributeType: S
142155
KeySchema:
143-
- AttributeName: detaineeId
156+
- AttributeName: PK
144157
KeyType: HASH
145-
- AttributeName: timestamp
158+
- AttributeName: SK
146159
KeyType: RANGE
147160
GlobalSecondaryIndexes:
148-
- IndexName: StatusCreatedDateIndex
149-
KeySchema:
150-
- AttributeName: status
151-
KeyType: HASH
152-
- AttributeName: createdDate
153-
KeyType: RANGE
154-
Projection:
155-
ProjectionType: ALL
156-
- IndexName: CreatedDateTimestampIndex
161+
- IndexName: GSI1
157162
KeySchema:
158-
- AttributeName: createdDate
163+
- AttributeName: GSI1PK
159164
KeyType: HASH
160-
- AttributeName: timestamp
165+
- AttributeName: GSI1SK
161166
KeyType: RANGE
162167
Projection:
163168
ProjectionType: ALL
@@ -169,6 +174,38 @@ resources:
169174
- Key: Service
170175
Value: JailData
171176

177+
# SQS queue for batch processing (handles inmate data batches)
178+
BatchProcessingQueue:
179+
Type: AWS::SQS::Queue
180+
Properties:
181+
QueueName: jaildata-batch-processing-${self:provider.stage}
182+
VisibilityTimeoutSeconds: 300
183+
MessageRetentionPeriod: 1209600 # 14 days
184+
RedrivePolicy:
185+
deadLetterTargetArn: !GetAtt BatchProcessingDeadLetterQueue.Arn
186+
maxReceiveCount: 3
187+
Tags:
188+
- Key: Name
189+
Value: JailData Batch Processing Queue
190+
- Key: Environment
191+
Value: ${self:provider.stage}
192+
- Key: Service
193+
Value: JailData
194+
195+
# Dead letter queue for batch processing
196+
BatchProcessingDeadLetterQueue:
197+
Type: AWS::SQS::Queue
198+
Properties:
199+
QueueName: jaildata-batch-processing-dlq-${self:provider.stage}
200+
MessageRetentionPeriod: 1209600 # 14 days
201+
Tags:
202+
- Key: Name
203+
Value: JailData Batch Processing Dead Letter Queue
204+
- Key: Environment
205+
Value: ${self:provider.stage}
206+
- Key: Service
207+
Value: JailData
208+
172209
# DynamoDB table for error cache and deduplication
173210
ErrorCacheTable:
174211
Type: AWS::DynamoDB::Table
@@ -213,37 +250,151 @@ resources:
213250
Name: ${self:service}-${self:provider.stage}-CommunityUsagePlanId
214251

215252
functions:
216-
# Scheduled data collection function
217-
dataCollection:
218-
handler: handlers/data-collection.execute
253+
# Manual data collection trigger
254+
dataCollectionManual:
255+
handler: handlers/data-collection.collect
256+
memorySize: 1024
257+
timeout: 600 # 10 minutes
258+
events:
259+
- http:
260+
path: /collect/{facilityId}
261+
method: post
262+
private: true
263+
264+
# Scheduled data collection functions for different facilities
265+
# To add a new facility: copy a function, change the name, set the facility ID in the input, and pick a unique schedule
266+
267+
# Wake County - 10:00 AM UTC daily
268+
dataCollectionWake:
269+
handler: handlers/data-collection.collectScheduled
219270
memorySize: 1024
220271
timeout: 600 # 10 minutes
221272
events:
222-
# Default collection at 10 AM UTC
223273
- schedule:
224274
rate: cron(0 10 * * ? *)
225-
input: '{"countyId": "wake", "source": "wake-county"}'
226-
# Additional configurable collections can be added here
227-
# Example: 10:30 AM UTC for Mecklenburg County
228-
# - schedule:
229-
# rate: cron(30 10 * * ? *)
230-
# input: '{"countyId": "mecklenburg", "source": "mecklenburg-county"}'
231-
232-
# Get detainee data
233-
getDetainee:
234-
handler: handlers/detainee.get
275+
enabled: true
276+
name: jaildata-collection-wake-${self:provider.stage}
277+
description: "Daily Wake County jail data collection"
278+
input: '{"facilityId": "wake"}'
279+
280+
# Buncombe County - 10:15 AM UTC daily
281+
dataCollectionBuncombe:
282+
handler: handlers/data-collection.collectScheduled
283+
memorySize: 1024
284+
timeout: 600 # 10 minutes
285+
events:
286+
- schedule:
287+
rate: cron(15 10 * * ? *)
288+
enabled: true
289+
name: jaildata-collection-buncombe-${self:provider.stage}
290+
description: "Daily Buncombe County jail data collection"
291+
input: '{"facilityId": "buncombe"}'
292+
293+
# DISABLED: Mecklenburg County - Need API ID (currently 0)
294+
dataCollectionMecklenburg:
295+
handler: handlers/data-collection.collectScheduled
296+
memorySize: 1024
297+
timeout: 600 # 10 minutes
298+
events:
299+
- schedule:
300+
rate: cron(30 10 * * ? *)
301+
enabled: false # DISABLED: Need API ID
302+
name: jaildata-collection-mecklenburg-${self:provider.stage}
303+
description: "Daily Mecklenburg County jail data collection"
304+
input: '{"facilityId": "mecklenburg"}'
305+
306+
# DISABLED: Durham County - Need API ID (currently 0)
307+
dataCollectionDurham:
308+
handler: handlers/data-collection.collectScheduled
309+
memorySize: 1024
310+
timeout: 600 # 10 minutes
311+
events:
312+
- schedule:
313+
rate: cron(0 11 * * ? *)
314+
enabled: false # DISABLED: Need API ID
315+
name: jaildata-collection-durham-${self:provider.stage}
316+
description: "Daily Durham County jail data collection"
317+
input: '{"facilityId": "durham"}'
318+
319+
# DISABLED: Orange County - Need API ID (currently 0)
320+
dataCollectionOrange:
321+
handler: handlers/data-collection.collectScheduled
322+
memorySize: 1024
323+
timeout: 600 # 10 minutes
324+
events:
325+
- schedule:
326+
rate: cron(30 11 * * ? *)
327+
enabled: false # DISABLED: Need API ID
328+
name: jaildata-collection-orange-${self:provider.stage}
329+
description: "Daily Orange County jail data collection"
330+
input: '{"facilityId": "orange"}'
331+
332+
# DISABLED: Guilford County - Need API ID (currently 0)
333+
dataCollectionGuilford:
334+
handler: handlers/data-collection.collectScheduled
335+
memorySize: 1024
336+
timeout: 600 # 10 minutes
337+
events:
338+
- schedule:
339+
rate: cron(0 12 * * ? *)
340+
enabled: false # DISABLED: Need API ID
341+
name: jaildata-collection-guilford-${self:provider.stage}
342+
description: "Daily Guilford County jail data collection"
343+
input: '{"facilityId": "guilford"}'
344+
345+
# Batch processing function (triggered by SQS)
346+
batchProcessing:
347+
handler: handlers/batch-processing.processBatch
348+
memorySize: 512
349+
timeout: 300 # 5 minutes
350+
events:
351+
- sqs:
352+
arn: !GetAtt BatchProcessingQueue.Arn
353+
batchSize: 10
354+
maximumBatchingWindowInSeconds: 30
355+
356+
# Get inmates by facility (with status filter)
357+
getInmatesByFacility:
358+
handler: handlers/detainee.getInmatesByFacility
359+
events:
360+
- http:
361+
path: inmates/{facilityId}
362+
method: get
363+
private: true
364+
365+
# Get all active inmates across facilities
366+
getAllActiveInmates:
367+
handler: handlers/detainee.getAllActiveInmates
368+
events:
369+
- http:
370+
path: inmates/active
371+
method: get
372+
private: true
373+
374+
# Search inmates by last name within a facility
375+
searchInmatesByName:
376+
handler: handlers/detainee.searchInmatesByName
377+
events:
378+
- http:
379+
path: inmates/{facilityId}/search
380+
method: get
381+
private: true
382+
383+
# Get specific inmate record
384+
getSpecificInmate:
385+
handler: handlers/detainee.getSpecificInmate
235386
events:
236387
- http:
237-
path: detainee/{detaineeId}
388+
path: inmates/{facilityId}/{lastName}/{firstName}/{recordDate}
238389
method: get
239390
private: true
240391

241-
# List active detainees
242-
listActiveDetainees:
243-
handler: handlers/detainee.listActive
392+
# Get specific inmate record with middle name
393+
getSpecificInmateWithMiddle:
394+
handler: handlers/detainee.getSpecificInmate
244395
events:
245396
- http:
246-
path: detainees/active
397+
path: inmates/{facilityId}/{lastName}/{firstName}/{middleName}/{recordDate}
247398
method: get
248399
private: true
249400

0 commit comments

Comments
 (0)