mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-10-06 15:51:57 +00:00
chore(meals): delete email_report handler and SAM resources
Remove the leftover SES Lambda source so it cannot be redeployed from template.yaml.
This commit is contained in:
parent
fa0ef6b567
commit
fd03c745f2
5 changed files with 17 additions and 173 deletions
|
|
@ -1,58 +0,0 @@
|
||||||
import os
|
|
||||||
from email.mime.application import MIMEApplication
|
|
||||||
from email.mime.multipart import MIMEMultipart
|
|
||||||
from email.mime.text import MIMEText
|
|
||||||
|
|
||||||
import boto3
|
|
||||||
|
|
||||||
from shared.db import get_summary, previous_week
|
|
||||||
|
|
||||||
_ses = boto3.client("ses")
|
|
||||||
_s3 = boto3.client("s3")
|
|
||||||
|
|
||||||
|
|
||||||
def lambda_handler(event, context):
|
|
||||||
week = event.get("week", previous_week())
|
|
||||||
|
|
||||||
summary = get_summary(week)
|
|
||||||
if not summary:
|
|
||||||
return {"status": "no_summary", "week": week}
|
|
||||||
|
|
||||||
payroll_key = summary.get("payroll_csv_s3_key")
|
|
||||||
if not payroll_key:
|
|
||||||
return {"status": "no_payroll_csv", "week": week}
|
|
||||||
|
|
||||||
bucket = os.environ["REPORTS_BUCKET"]
|
|
||||||
csv_obj = _s3.get_object(Bucket=bucket, Key=payroll_key)
|
|
||||||
csv_content = csv_obj["Body"].read()
|
|
||||||
|
|
||||||
total_employees = int(summary.get("total_employees", 0))
|
|
||||||
grand_total = float(summary.get("grand_total", 0))
|
|
||||||
|
|
||||||
msg = MIMEMultipart("mixed")
|
|
||||||
msg["Subject"] = f"Meal Order Payroll Deductions — {week}"
|
|
||||||
msg["From"] = os.environ["SENDER_EMAIL"]
|
|
||||||
msg["To"] = os.environ["PAYROLL_EMAIL"]
|
|
||||||
|
|
||||||
body = MIMEText(
|
|
||||||
f"Attached is the meal order payroll deduction report for {week}.\n\n"
|
|
||||||
f"Employees: {total_employees}\n"
|
|
||||||
f"Total deductions: ${grand_total:.2f}\n\n"
|
|
||||||
f"Please apply these deductions in the next pay period.\n",
|
|
||||||
"plain",
|
|
||||||
)
|
|
||||||
msg.attach(body)
|
|
||||||
|
|
||||||
attachment = MIMEApplication(csv_content)
|
|
||||||
attachment.add_header(
|
|
||||||
"Content-Disposition", "attachment", filename=f"payroll-deductions-{week}.csv"
|
|
||||||
)
|
|
||||||
msg.attach(attachment)
|
|
||||||
|
|
||||||
_ses.send_raw_email(
|
|
||||||
Source=os.environ["SENDER_EMAIL"],
|
|
||||||
Destinations=[os.environ["PAYROLL_EMAIL"]],
|
|
||||||
RawMessage={"Data": msg.as_string()},
|
|
||||||
)
|
|
||||||
|
|
||||||
return {"status": "sent", "week": week, "to": os.environ["PAYROLL_EMAIL"]}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
boto3==1.43.78
|
|
||||||
|
|
@ -7,4 +7,4 @@ s3_prefix = "meal-order-manager"
|
||||||
region = "us-east-1"
|
region = "us-east-1"
|
||||||
confirm_changeset = true
|
confirm_changeset = true
|
||||||
capabilities = "CAPABILITY_IAM"
|
capabilities = "CAPABILITY_IAM"
|
||||||
parameter_overrides = "CustomDomain=orders.seahaven.com CertificateArn=arn:aws:acm:us-east-1:328440206208:certificate/CHANGE-ME PayrollEmail=payroll@seahavenind.com SenderEmail=adam@seahavenind.com"
|
parameter_overrides = "CustomDomain=orders.seahaven.com CertificateArn=arn:aws:acm:us-east-1:328440206208:certificate/CHANGE-ME"
|
||||||
|
|
|
||||||
111
template.yaml
111
template.yaml
|
|
@ -13,14 +13,6 @@ Parameters:
|
||||||
Type: String
|
Type: String
|
||||||
Default: ''
|
Default: ''
|
||||||
Description: ACM certificate ARN for the custom domain (us-east-1)
|
Description: ACM certificate ARN for the custom domain (us-east-1)
|
||||||
PayrollEmail:
|
|
||||||
Type: String
|
|
||||||
Default: payroll@seahavenind.com
|
|
||||||
Description: Email address for payroll deduction reports
|
|
||||||
SenderEmail:
|
|
||||||
Type: String
|
|
||||||
Default: adam@seahavenind.com
|
|
||||||
Description: SES verified sender email for payroll reports
|
|
||||||
# Shared CloudFront WAF WebACL ARN (audit M-17), published to SSM by
|
# Shared CloudFront WAF WebACL ARN (audit M-17), published to SSM by
|
||||||
# seahaven-account-baseline. Resolved at deploy time.
|
# seahaven-account-baseline. Resolved at deploy time.
|
||||||
WebAclArn:
|
WebAclArn:
|
||||||
|
|
@ -543,42 +535,6 @@ Resources:
|
||||||
Description: 'Sync roster Monday 6:55am EDT (10:55 UTC) — before menu publish'
|
Description: 'Sync roster Monday 6:55am EDT (10:55 UTC) — before menu publish'
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
EmailReportFunction:
|
|
||||||
Type: AWS::Serverless::Function
|
|
||||||
Properties:
|
|
||||||
FunctionName: meal-order-manager-email-report
|
|
||||||
Handler: handler.lambda_handler
|
|
||||||
CodeUri: functions/email_report/
|
|
||||||
MemorySize: 128
|
|
||||||
Timeout: 30
|
|
||||||
Environment:
|
|
||||||
Variables:
|
|
||||||
PAYROLL_EMAIL: !Ref PayrollEmail
|
|
||||||
SENDER_EMAIL: !Ref SenderEmail
|
|
||||||
Policies:
|
|
||||||
- DynamoDBReadPolicy:
|
|
||||||
TableName: !Ref OrdersTable
|
|
||||||
- S3ReadPolicy:
|
|
||||||
BucketName: !Ref ReportsBucket
|
|
||||||
- Statement:
|
|
||||||
- Effect: Allow
|
|
||||||
Action:
|
|
||||||
- ses:SendRawEmail
|
|
||||||
Resource: '*'
|
|
||||||
Events:
|
|
||||||
PayrollEmailEST:
|
|
||||||
Type: Schedule
|
|
||||||
Properties:
|
|
||||||
Schedule: cron(0 12 ? * MON *)
|
|
||||||
Description: 'Email payroll deductions Monday 7am EST (12:00 UTC)'
|
|
||||||
Enabled: true
|
|
||||||
PayrollEmailEDT:
|
|
||||||
Type: Schedule
|
|
||||||
Properties:
|
|
||||||
Schedule: cron(0 11 ? * MON *)
|
|
||||||
Description: 'Email payroll deductions Monday 7am EDT (11:00 UTC)'
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# ─── CloudWatch Log Groups (60-day retention) ──────────────────
|
# ─── CloudWatch Log Groups (60-day retention) ──────────────────
|
||||||
|
|
||||||
SubmitOrderLogGroup:
|
SubmitOrderLogGroup:
|
||||||
|
|
@ -605,12 +561,6 @@ Resources:
|
||||||
LogGroupName: !Sub '/aws/lambda/${SlackNotifierFunction}'
|
LogGroupName: !Sub '/aws/lambda/${SlackNotifierFunction}'
|
||||||
RetentionInDays: 60
|
RetentionInDays: 60
|
||||||
|
|
||||||
EmailReportLogGroup:
|
|
||||||
Type: AWS::Logs::LogGroup
|
|
||||||
Properties:
|
|
||||||
LogGroupName: !Sub '/aws/lambda/${EmailReportFunction}'
|
|
||||||
RetentionInDays: 60
|
|
||||||
|
|
||||||
SyncRosterLogGroup:
|
SyncRosterLogGroup:
|
||||||
Type: AWS::Logs::LogGroup
|
Type: AWS::Logs::LogGroup
|
||||||
Properties:
|
Properties:
|
||||||
|
|
@ -744,25 +694,6 @@ Resources:
|
||||||
AlarmActions:
|
AlarmActions:
|
||||||
- arn:aws:sns:us-east-1:328440206208:site-alerts
|
- arn:aws:sns:us-east-1:328440206208:site-alerts
|
||||||
|
|
||||||
EmailReportErrorsAlarm:
|
|
||||||
Type: AWS::CloudWatch::Alarm
|
|
||||||
Properties:
|
|
||||||
AlarmName: meal-order-manager-email-report-errors
|
|
||||||
AlarmDescription: email-report Lambda reported one or more errors in 5 minutes.
|
|
||||||
Namespace: AWS/Lambda
|
|
||||||
MetricName: Errors
|
|
||||||
Dimensions:
|
|
||||||
- Name: FunctionName
|
|
||||||
Value: !Ref EmailReportFunction
|
|
||||||
Statistic: Sum
|
|
||||||
Period: 300
|
|
||||||
EvaluationPeriods: 1
|
|
||||||
Threshold: 0
|
|
||||||
ComparisonOperator: GreaterThanThreshold
|
|
||||||
TreatMissingData: notBreaching
|
|
||||||
AlarmActions:
|
|
||||||
- arn:aws:sns:us-east-1:328440206208:site-alerts
|
|
||||||
|
|
||||||
# Lambda Throttles (Sum, 5min, any throttle breaches)
|
# Lambda Throttles (Sum, 5min, any throttle breaches)
|
||||||
SubmitOrderThrottlesAlarm:
|
SubmitOrderThrottlesAlarm:
|
||||||
Type: AWS::CloudWatch::Alarm
|
Type: AWS::CloudWatch::Alarm
|
||||||
|
|
@ -878,25 +809,6 @@ Resources:
|
||||||
AlarmActions:
|
AlarmActions:
|
||||||
- arn:aws:sns:us-east-1:328440206208:site-alerts
|
- arn:aws:sns:us-east-1:328440206208:site-alerts
|
||||||
|
|
||||||
EmailReportThrottlesAlarm:
|
|
||||||
Type: AWS::CloudWatch::Alarm
|
|
||||||
Properties:
|
|
||||||
AlarmName: meal-order-manager-email-report-throttles
|
|
||||||
AlarmDescription: email-report Lambda was throttled in the last 5 minutes.
|
|
||||||
Namespace: AWS/Lambda
|
|
||||||
MetricName: Throttles
|
|
||||||
Dimensions:
|
|
||||||
- Name: FunctionName
|
|
||||||
Value: !Ref EmailReportFunction
|
|
||||||
Statistic: Sum
|
|
||||||
Period: 300
|
|
||||||
EvaluationPeriods: 1
|
|
||||||
Threshold: 0
|
|
||||||
ComparisonOperator: GreaterThanThreshold
|
|
||||||
TreatMissingData: notBreaching
|
|
||||||
AlarmActions:
|
|
||||||
- arn:aws:sns:us-east-1:328440206208:site-alerts
|
|
||||||
|
|
||||||
# Lambda Duration p99 (~80% of timeout)
|
# Lambda Duration p99 (~80% of timeout)
|
||||||
# Synchronous (API-fronted) functions: eval 3 / datapoints 3.
|
# Synchronous (API-fronted) functions: eval 3 / datapoints 3.
|
||||||
SubmitOrderDurationAlarm:
|
SubmitOrderDurationAlarm:
|
||||||
|
|
@ -1020,26 +932,6 @@ Resources:
|
||||||
AlarmActions:
|
AlarmActions:
|
||||||
- arn:aws:sns:us-east-1:328440206208:site-alerts
|
- arn:aws:sns:us-east-1:328440206208:site-alerts
|
||||||
|
|
||||||
EmailReportDurationAlarm:
|
|
||||||
Type: AWS::CloudWatch::Alarm
|
|
||||||
Properties:
|
|
||||||
AlarmName: meal-order-manager-email-report-duration
|
|
||||||
AlarmDescription: email-report p99 duration exceeded 24000ms (80% of 30s timeout).
|
|
||||||
Namespace: AWS/Lambda
|
|
||||||
MetricName: Duration
|
|
||||||
Dimensions:
|
|
||||||
- Name: FunctionName
|
|
||||||
Value: !Ref EmailReportFunction
|
|
||||||
ExtendedStatistic: p99
|
|
||||||
Period: 300
|
|
||||||
EvaluationPeriods: 1
|
|
||||||
DatapointsToAlarm: 1
|
|
||||||
Threshold: 24000
|
|
||||||
ComparisonOperator: GreaterThanThreshold
|
|
||||||
TreatMissingData: notBreaching
|
|
||||||
AlarmActions:
|
|
||||||
- arn:aws:sns:us-east-1:328440206208:site-alerts
|
|
||||||
|
|
||||||
# DynamoDB orders table.
|
# DynamoDB orders table.
|
||||||
# NOTE: DynamoDB does NOT publish ThrottledRequests or SystemErrors at the
|
# NOTE: DynamoDB does NOT publish ThrottledRequests or SystemErrors at the
|
||||||
# TableName-only dimension (verified via cloudwatch list-metrics on
|
# TableName-only dimension (verified via cloudwatch list-metrics on
|
||||||
|
|
@ -1202,6 +1094,3 @@ Outputs:
|
||||||
SyncRosterFunctionArn:
|
SyncRosterFunctionArn:
|
||||||
Description: Sync Roster Lambda ARN
|
Description: Sync Roster Lambda ARN
|
||||||
Value: !GetAtt SyncRosterFunction.Arn
|
Value: !GetAtt SyncRosterFunction.Arn
|
||||||
EmailReportFunctionArn:
|
|
||||||
Description: Email Report Lambda ARN
|
|
||||||
Value: !GetAtt EmailReportFunction.Arn
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
"""email_report is removed from the live Terraform config (PLAT-135)."""
|
"""email_report is removed from Terraform, SAM, and the functions tree (PLAT-135)."""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
TERRAFORM = Path(__file__).resolve().parents[1] / "terraform"
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
TERRAFORM = ROOT / "terraform"
|
||||||
|
|
||||||
|
|
||||||
def _read(name: str) -> str:
|
def _read(name: str) -> str:
|
||||||
return (TERRAFORM / name).read_text()
|
return (TERRAFORM / name).read_text()
|
||||||
|
|
||||||
|
|
||||||
|
def test_email_report_handler_removed():
|
||||||
|
assert not (ROOT / "functions" / "email_report").exists()
|
||||||
|
|
||||||
|
|
||||||
def test_email_report_not_in_function_packages():
|
def test_email_report_not_in_function_packages():
|
||||||
locals_tf = _read("locals.tf")
|
locals_tf = _read("locals.tf")
|
||||||
assert '"email_report"' not in locals_tf
|
assert '"email_report"' not in locals_tf
|
||||||
|
|
@ -36,3 +41,12 @@ def test_email_report_lambda_and_role_removed():
|
||||||
assert "email_report" not in outputs
|
assert "email_report" not in outputs
|
||||||
assert "payroll_email" not in variables
|
assert "payroll_email" not in variables
|
||||||
assert "sender_email" not in variables
|
assert "sender_email" not in variables
|
||||||
|
|
||||||
|
|
||||||
|
def test_email_report_removed_from_sam_template():
|
||||||
|
template = (ROOT / "template.yaml").read_text()
|
||||||
|
assert "EmailReportFunction" not in template
|
||||||
|
assert "functions/email_report/" not in template
|
||||||
|
assert "PayrollEmail" not in template
|
||||||
|
assert "SenderEmail" not in template
|
||||||
|
assert "ses:SendRawEmail" not in template
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue