Building a Multi-Domain Executive Intelligence System: Lambda, SES, and Real-Time Reporting Architecture
Over the past development session, I built and deployed a comprehensive executive reporting infrastructure that synthesizes operational, technical, financial, and marketing intelligence across a four-domain portfolio (JADA, QueenofSanDiego, QuickDumpNow, DangerousCentaur). This post details the architecture, deployment strategy, and key decisions that enabled near-real-time C-suite visibility.
What Was Done
The core objective was to eliminate information silos across disconnected business entities. Rather than building a monolithic reporting engine, I created a modular system where domain-specific Lambda functions synthesize data into five specialized executive reports, each written from a distinct stakeholder perspective:
- CEO Report — Asset inventory, revenue tracking gaps, equity/liability risks, KPI framework
- CTO Report — Stack audits, security posture, infrastructure costs, UX/dev cycle bottlenecks
- Accounting Report — Chart of accounts, expense audit, revenue recognition issues
- CMO Report — Channel matrix, launch sequencing, OTA deployment roadmap
- CFO Report — Burn rate models, capital deployment framework, break-even analysis
Three additional reports were generated for specialized portfolios: 3028 51st St Rental, Expert Yacht Delivery, and DangerousCentaur Client Portfolio (billing audit).
Technical Architecture
Email Delivery Infrastructure
The reporting system is built on Amazon SES (Simple Email Service) for reliable, scalable email delivery. The implementation uses verified sender addresses stored in environment variables:
# repos.env configuration (not shown with values for security)
SES_FROM_ADDRESS=admin@queenofsandiego.com
AWS_REGION=us-west-2
RECIPIENT_EMAIL=c.b.ladd@gmail.com
The Python implementation in /Users/cb/Documents/repos/tools/send_exec_reports.py uses boto3's SES client to send HTML-formatted reports with BCC routing for audit trails:
import boto3
import os
from botocore.exceptions import ClientError
ses_client = boto3.client('ses', region_name=os.getenv('AWS_REGION'))
def send_report(subject, body, recipient):
try:
response = ses_client.send_email(
Source=os.getenv('SES_FROM_ADDRESS'),
Destination={
'ToAddresses': [recipient],
'BccAddresses': ['admin@queenofsandiego.com']
},
Message={
'Subject': {'Data': subject},
'Body': {'Html': {'Data': body}}
}
)
return response['MessageId']
except ClientError as e:
print(f"SES Error: {e.response['Error']['Message']}")
raise
This design pattern allows sender address rotation and audit logging without hardcoding credentials in application code.
Lambda Function Integration
The primary reporting Lambda (`/Users/cb/Documents/repos/sites/queenofsandiego.com/tools/shipcaptaincrew/lambda_function.py`) was extended with multiple new handler routes to support report generation. The function follows a unified routing pattern:
def lambda_handler(event, context):
path = event.get('path', '')
method = event.get('httpMethod', 'GET')
# Report generation endpoints
if path == '/api/reports/executive' and method == 'POST':
return handle_executive_reports(event)
elif path == '/api/reports/cto' and method == 'POST':
return handle_cto_audit(event)
elif path == '/api/reports/accounting' and method == 'POST':
return handle_accounting_report(event)
# ... additional routes
Each handler validates authentication (JWT token verification), synthesizes data from project handoffs and infrastructure queries, and dispatches reports via SES. The Lambda maintains under 50MB uncompressed size through judicious use of external imports and lazy-loading of heavy libraries.
Frontend Integration
The ShipCaptainCrew frontend (`/Users/cb/Documents/repos/sites/queenofsandiego.com/tools/shipcaptaincrew/frontend/index.html`) was updated to include a reporting dashboard. This required careful consideration of token passing and CORS configuration:
- Magic link authentication generates JWT tokens valid for report generation
- Report submission buttons serialize form state and POST to Lambda endpoints
- Response handling displays confirmation or error states without exposing sensitive report contents to the UI
Deployment Pipeline
The deployment process involves three sequential steps:
- Lambda Syntax Validation — Python AST parsing and import verification before deployment
- AWS Lambda Update — Zip archive creation and function code update via AWS CLI
- Frontend Deployment — S3 upload to the static assets bucket with CloudFront cache invalidation
Lambda deployment command pattern:
# Create deployment package
zip -r lambda_deployment.zip lambda_function.py
# Deploy to AWS Lambda
aws lambda update-function-code \
--function-name shipcaptaincrew \
--zip-file fileb://lambda_deployment.zip \
--region us-west-2
# Invalidate CloudFront distribution
aws cloudfront create-invalidation \
--distribution-id E1234ABCD5678 \
--paths "/*" \
--region us-west-2
Frontend deployment combines S3 sync with targeted invalidation to minimize cache pollution:
aws s3 sync frontend/ s3://queenofsandiego-shipcaptaincrew/ \
--region us-west-2 \
--delete
aws cloudfront create-invalidation \
--distribution-id E1234ABCD5678 \
--paths "/index.html" "/styles/*" \
--region us-west-2
Key Architectural Decisions
Why SES over SNS/SMS: SES provides rich HTML formatting, reliable delivery tracking via Message IDs, and native BCC support for compliance auditing. For executive audiences expecting professional formatting, SMS was insufficient.
Why Lambda instead of scheduled EventBridge: Report generation is on-demand from the frontend, not scheduled. However, future EventBridge integration for periodic digest emails is planned (ptb_nudge pattern already established in the codebase).
Why JWT-gated endpoints: Magic link authentication creates time-bound tokens that prevent unauthorized report generation and establish audit trails. Each report dispatch logs the token subject (user identifier) to DynamoDB for compliance.
Why modular report handlers: Each C-suite role requires different data queries and presentation logic. Separating CEO, CTO, Accounting, CMO, and CFO handlers into discrete functions enables independent scaling and testing of domain-specific logic.
Infrastructure Changes
The following AWS resources were created or modified:
- DynamoDB Table —
shipcaptaincrew_reportsfor audit logging report generation events - Lambda Environment Variables — Added
SES_FROM_ADDRESS,REPORT_RECIPIENT