2026-09-21 17:50:57 +00:00
# HTTP API: Slack events, Paychex roster contract, and portal shift API.
2026-09-15 23:31:59 +00:00
resource " aws_apigatewayv2_api " " http " {
name = local . project
protocol_type = " HTTP "
2026-09-21 17:50:57 +00:00
description = " afterhours-shift-manager Slack, roster, and portal API "
cors_configuration {
allow_origins = [
" https://internal.seahaven.com " ,
" https://internal.dev.seahaven.com " ,
" http://localhost:5173 " ,
" http://localhost:4173 " ,
]
allow_methods = [ " GET " , " POST " , " DELETE " , " OPTIONS " ]
allow_headers = [ " Authorization " , " Content-Type " ]
allow_credentials = false
max_age = 3600
}
2026-09-15 23:31:59 +00:00
}
resource " aws_apigatewayv2_integration " " slack_bot " {
api_id = aws_apigatewayv2_api . http . id
integration_type = " AWS_PROXY "
integration_method = " POST "
integration_uri = aws_lambda_function . this [ " slack_bot " ] . invoke_arn
payload_format_version = " 2.0 "
timeout_milliseconds = 30000
}
resource " aws_apigatewayv2_integration " " roster_api " {
api_id = aws_apigatewayv2_api . http . id
integration_type = " AWS_PROXY "
integration_method = " POST "
integration_uri = aws_lambda_function . this [ " roster_api " ] . invoke_arn
payload_format_version = " 2.0 "
timeout_milliseconds = 30000
}
2026-09-21 17:50:57 +00:00
resource " aws_apigatewayv2_integration " " portal_api " {
api_id = aws_apigatewayv2_api . http . id
integration_type = " AWS_PROXY "
integration_method = " POST "
integration_uri = aws_lambda_function . this [ " portal_api " ] . invoke_arn
payload_format_version = " 2.0 "
timeout_milliseconds = 30000
}
2026-09-15 23:31:59 +00:00
resource " aws_apigatewayv2_route " " slack_events " {
api_id = aws_apigatewayv2_api . http . id
route_key = " POST /slack/events "
target = " integrations/ ${ aws_apigatewayv2_integration . slack_bot . id } "
}
resource " aws_apigatewayv2_route " " put_roster " {
api_id = aws_apigatewayv2_api . http . id
route_key = " PUT /roster "
target = " integrations/ ${ aws_apigatewayv2_integration . roster_api . id } "
}
resource " aws_apigatewayv2_route " " delete_roster " {
api_id = aws_apigatewayv2_api . http . id
route_key = " DELETE /roster/{extension} "
target = " integrations/ ${ aws_apigatewayv2_integration . roster_api . id } "
}
2026-09-21 17:50:57 +00:00
resource " aws_apigatewayv2_route " " portal_shifts " {
api_id = aws_apigatewayv2_api . http . id
route_key = " ANY /api/shifts "
target = " integrations/ ${ aws_apigatewayv2_integration . portal_api . id } "
}
resource " aws_apigatewayv2_route " " portal_shifts_proxy " {
api_id = aws_apigatewayv2_api . http . id
route_key = " ANY /api/shifts/{proxy+} "
target = " integrations/ ${ aws_apigatewayv2_integration . portal_api . id } "
}
2026-09-15 23:31:59 +00:00
resource " aws_apigatewayv2_stage " " default " {
api_id = aws_apigatewayv2_api . http . id
name = " $ default "
auto_deploy = true
access_log_settings {
destination_arn = aws_cloudwatch_log_group . api_access . arn
format = " { \ " requestId \ " : \ " $ context . requestId \ " , \ " ip \ " : \ " $ context . identity . sourceIp \ " , \ " requestTime \ " : \ " $ context . requestTime \ " , \ " method \ " : \ " $ context . httpMethod \ " , \ " routeKey \ " : \ " $ context . routeKey \ " , \ " status \ " : \ " $ context . status \ " , \ " protocol \ " : \ " $ context . protocol \ " , \ " responseLength \ " : \ " $ context . responseLength \ " , \ " integrationError \ " : \ " $ context . integrationErrorMessage \ " } "
}
default_route_settings {
throttling_burst_limit = 50
throttling_rate_limit = 100
}
depends_on = [
aws_apigatewayv2_route . slack_events ,
aws_apigatewayv2_route . put_roster ,
aws_apigatewayv2_route . delete_roster ,
2026-09-21 17:50:57 +00:00
aws_apigatewayv2_route . portal_shifts ,
aws_apigatewayv2_route . portal_shifts_proxy ,
2026-09-15 23:31:59 +00:00
aws_iam_role_policy . hcptf_apply_services ,
]
}
resource " aws_lambda_permission " " api_slack_bot " {
statement_id = " AllowApiGatewayInvokeSlackBot "
action = " lambda:InvokeFunction "
function_name = aws_lambda_function . this [ " slack_bot " ] . function_name
principal = " apigateway.amazonaws.com "
source_arn = " ${ aws_apigatewayv2_api . http . execution_arn } /*/* "
}
resource " aws_lambda_permission " " api_roster_api " {
statement_id = " AllowApiGatewayInvokeRosterApi "
action = " lambda:InvokeFunction "
function_name = aws_lambda_function . this [ " roster_api " ] . function_name
principal = " apigateway.amazonaws.com "
source_arn = " ${ aws_apigatewayv2_api . http . execution_arn } /*/* "
}
2026-09-21 17:50:57 +00:00
resource " aws_lambda_permission " " api_portal_api " {
statement_id = " AllowApiGatewayInvokePortalApi "
action = " lambda:InvokeFunction "
function_name = aws_lambda_function . this [ " portal_api " ] . function_name
principal = " apigateway.amazonaws.com "
source_arn = " ${ aws_apigatewayv2_api . http . execution_arn } /*/* "
}