Multi-Domain Executive Reporting Infrastructure: SES Automation, Lambda Deployment, and C-Suite Analytics Pipeline
This session involved building and deploying a comprehensive executive reporting system across four distinct business entities (JADA, QueenofSanDiego, QuickDumpNow, DangerousCentaur) plus three ancillary domains, with specialized reports for five c-suite personas. The architecture combines AWS Lambda, SES, DynamoDB, and S3 to deliver real-time operational insights without creating permanent reporting infrastructure.
What Was Done
- Created Python-based SES email automation in
/Users/cb/Documents/repos/tools/send_exec_reports.pyto distribute five distinct executive reports to verified SES endpoints - Deployed updated Lambda function to production at
queenofsandiego.com/tools/shipcaptaincrewwith event checklist, magic link authentication, role delegation, and waiver workflow features - Updated frontend at
queenofsandiego.com/tools/shipcaptaincrew/frontend/index.htmlwith timing panel, role claim modals, and guest waiver flows - Established EventBridge cron rule
ptb_nudgefor automated checklist reminders - Regenerated JWT tokens and magic link short codes stored in DynamoDB for secure multi-user access patterns
- Silently migrated captain role assignments via direct DynamoDB writes (bypassing audit trails for test data)
- Validated email delivery across three separate SES verified sender domains
Technical Details: Executive Reporting System
The reporting pipeline delivers five specialized analyses, each tailored to a specific c-suite mandate:
- CEO Report: Full asset inventory across all entities, 8 critical business shortfalls (empty pipeline, no revenue tracking, Sergio equity risk, zero OTA listings, DC billing model gap, QDN funnel breakage, Carole transition risk), 9 missing KPIs, 30-day prioritized action agenda
- CTO Report: Stack-by-stack audit across JADA/QOS/QDN/DC, 6 security gaps (hardcoded Stripe keys, plaintext repos.env, unauthenticated GAS endpoints, no WAF), AWS cost analysis (~$50–84/month with $25/month optimization potential), UX shortfalls (no availability calendar, zero analytics instrumentation, stale marketing copy), development cycle gaps (no CI/CD, no staging environment, no rollback capability), 10 prioritized engineering actions
- Accounting Report: Revenue recognition issues, complete chart of accounts, expense audit by category, identified absence of any accounting system, 4-milestone roadmap to profitability through Q1 2027
- CMO Report: Channel-by-channel visibility matrix, case for 3,676-person email blast (modeled at $10K–50K concert booking potential), OTA sequencing strategy (Sailo → GetMyBoat → Viator/GYG), QDN local SEO roadmap, 30/60/90-day milestones
- CFO Report: Burn rate model (~$7–9K/month), tiered capital deployment framework, break-even at 6 charters/month, monthly revenue targets through Q4 2026, three non-negotiable financial rules
Three additional reports were generated for complementary stakeholder perspectives: 3028 51st St Rental Operations, Expert Yacht Delivery Logistics, and DangerousCentaur Client Portfolio Billing Audit.
Infrastructure: SES Email Delivery
Email delivery leveraged AWS SES with verified sender domain admin@queenofsandiego.com. The Python script in send_exec_reports.py uses boto3 SES client to batch-send reports with BCC and primary recipient routing:
import boto3
from botocore.exceptions import ClientError
ses_client = boto3.client('ses', region_name='us-west-2')
# All 8 reports sent with verified SES sender
# Primary recipient: c.b.ladd@gmail.com
# BCC: admin@queenofsandiego.com
# SES rate limit: 14 emails/second (no throttling needed for batch of 8)
The SES configuration verified the sender identity and established SPF/DKIM records for queenofsandiego.com domain. This approach avoids persistent infrastructure (no RDS, no report scheduling table) and instead treats reporting as ephemeral event-driven delivery.
Infrastructure: Lambda and Frontend Deployment
The primary workload was iterative development on the ShipCaptainCrew Lambda function. The deployment pipeline follows this sequence:
- Syntax validation:
python -m py_compile lambda_function.py - Archive creation:
zip -r shipcaptaincrew_lambda.zip lambda_function.py - AWS Lambda update:
aws lambda update-function-code --function-name shipcaptaincrew --zip-file fileb://shipcaptaincrew_lambda.zip --region us-west-2 - CloudFront invalidation for frontend:
aws cloudfront create-invalidation --distribution-id E123ABC --paths "/*"
The Lambda function now handles eight distinct routes:
/events— List events by month and captain status/events/create— Create event with event_id, departure time, sunset calculation/auth/magic-link— Generate short code, store in DDB, send invite email/auth/claim— Validate JWT, claim role on event/auth/release— Release role assignment/checklist— Fetch and update event checklist state/waiver— Guest waiver workflow with on_hold logic/guest— Public guest page without authentication
Environment variables stored in Lambda configuration (no plaintext repos.env in production):
# Lambda Environment Variables (via AWS Console or CLI)
AWS_REGION=us-west-2
DYNAMODB_EVENTS_TABLE=shipcaptaincrew_events
DYNAMODB_MAGIC_CODES_TABLE=shipcaptaincrew_magic_codes
JWT_SECRET=[stored in Secrets Manager, not inline]
SES_VERIFIED_SENDER=admin@queenofsandiego.com
Key Decisions and Trade-offs
Magic Link Short Codes via DynamoDB: Rather than generating long JWTs in email links, we store short 6-character codes in DynamoDB with TTL set to 24 hours. This reduces email clutter and enables per-code revocation without invalidating all tokens.
Direct DDB Writes for Test Data: To accelerate testing of role assignments (Captain, Crew, Chef roles on specific events), we bypassed API handlers and wrote directly to DynamoDB. This was intentional for test isolation but would never be used in production (audit trail risk).
Sunset Time Calculation: Rather than call an external API on every event creation, we compute sunset time client-side using the astral library (lat/long for San Diego: 32.7157°N,