```html

Building a Multi-Stakeholder Executive Intelligence System: Lambda, SES, and Automated Report Distribution

Over the past development session, we built and deployed a comprehensive executive reporting infrastructure that generates role-specific strategic analyses across four business entities (JADA, QueenofSanDiego, QuickDumpNow, DangerousCentaur) and distributes them via AWS SES. This post covers the technical architecture, deployment patterns, and infrastructure decisions that power this system.

What Was Done

We created an automated pipeline that generates five distinct executive reports—each tailored to a specific C-suite perspective (CEO, CTO, CFO, CMO, Accounting)—synthesizes cross-domain business data, and delivers them via email. The system also extended to three additional reporting domains (3028 51st St Rental, Expert Yacht Delivery, DangerousCentaur Client Portfolio), requiring a scalable architecture.

Technical Architecture

Report Generation and Email Distribution

Two Python scripts drive the reporting system:

  • /Users/cb/Documents/repos/tools/send_exec_reports.py — Primary report generator and SES dispatcher
  • /Users/cb/Documents/repos/tools/send_exec_reports_2.py — Secondary variant for A/B testing or role-specific report subsets

The architecture reads environment variables from repos.env to retrieve SES configuration:


# Pattern used in scripts
SES_REGION = os.getenv('AWS_REGION', 'us-west-2')
FROM_ADDRESS = os.getenv('SES_FROM_ADDRESS')
RECIPIENT_EMAIL = os.getenv('EXEC_REPORT_RECIPIENT')

Why this approach: Externalizing credentials and configuration prevents hardcoding secrets into source control and allows different environments (dev, staging, prod) to use separate SES senders and recipients without code changes.

SES Sender Verification

The system uses admin@queenofsandiego.com as the verified SES sender identity. In production AWS SES accounts operating in sandbox mode or with verified identities, only pre-registered addresses can send mail. The choice to anchor on QueenofSanDiego's admin address reflects that domain's maturity as the hub organization; future scaling would require registering additional sender identities (e.g., noreply@jada.com, finance@quickdumpnow.com) and corresponding Route53 DKIM records.

Lambda Integration and Deployment

The primary application receiving these reports is the ShipCaptainCrew tool, housed at:


/Users/cb/Documents/repos/sites/queenofsandiego.com/tools/shipcaptaincrew/

This directory contains:

  • lambda_function.py — Core event creation, checklist management, JWT token generation, and magic-link authentication
  • frontend/index.html — Client-side UI for event booking, crew assignment, and checklist tracking

During this session, we performed 10+ iterations on lambda_function.py, primarily refining:

  • Event creation handlers — Ensuring required fields (event_id, departure, return, event_type) are validated before DynamoDB writes
  • JWT secret management — Retrieving JWT_SECRET from Lambda environment variables and generating short-lived tokens for magic-link authentication
  • Checklist loading and timing hooks — Integrating departure/return timestamps with client-side countdown and event lifecycle states
  • Magic-link token generation — Creating admin-scoped and user-scoped tokens with role-based access control

Why multiple iterations: The Lambda function acts as the integration hub between the SES reporting pipeline, the event booking system, and frontend authentication. Each iteration tested and hardened JWT handling, validated the event schema against DynamoDB item expectations, and ensured magic links correctly embedded full user context (roles, email, event_id) for seamless onboarding.

Deployment Workflow

Deployment follows a two-stage pattern:

  1. Syntax and logic validation — Local checks before pushing to AWS
  2. Lambda + Frontend deployment — Package Lambda as a zip, deploy via AWS CLI; sync frontend to S3 and invalidate CloudFront

Example command sequence:


# Syntax check before deploy
python -m py_compile lambda_function.py

# Deploy Lambda (zipped)
zip -r shipcaptaincrew_lambda.zip lambda_function.py
aws lambda update-function-code \
  --function-name shipcaptaincrew \
  --zip-file fileb://shipcaptaincrew_lambda.zip \
  --region us-west-2

# Deploy frontend to S3 and invalidate CloudFront distribution
aws s3 sync frontend/ s3://queenofsandiego-shipcaptaincrew/ --delete
aws cloudfront create-invalidation \
  --distribution-id DISTRIBUTION_ID_HERE \
  --paths "/*"

Why this pattern: Zipping the Lambda function ensures dependencies and configuration are consistent. CloudFront invalidation forces edge caches to refresh, so users always fetch the latest HTML/CSS/JS immediately after deploy.

Event and Checklist Infrastructure

The ShipCaptainCrew tool manages sail events with time-sensitive checklists. During development, we:

  • Created test events with full JWT tokens, capturing event_id, departure time, return time, and checklist state
  • Integrated sunset time calculations (using San Diego location data) to set realistic departure windows
  • Wired up EventBridge cron rules (e.g., ptb_nudge) to trigger automated reminders and status updates
  • Generated magic-link short codes and stored them in DynamoDB for passwordless authentication

Magic links follow this flow:


User clicks email link with short_code
  → Lambda magic-auth handler receives request
  → DynamoDB lookup: short_code → user_email + role + event_id
  → Generate JWT with full context
  → Return JWT to frontend (via cookie or query param)
  → Frontend uses JWT for all subsequent API calls

Why short codes: Embedding full tokens in email links risks leakage via referrer headers or log files. Short codes are opaque, single-use, and tied to time windows. They decouple the UX (what users click) from the security mechanism (what the backend validates).

Multi-Domain Executive Reporting

The reporting system now covers eight reporting perspectives across seven business units:

  • JADA — CEO, CTO perspectives
  • QueenofSanDiego — CEO, CTO, CFO, CMO perspectives
  • QuickDumpNow — CEO perspective
  • DangerousCentaur — Client portfolio audit (accounting)
  • 3028 51st St Rental — Property revenue/expense tracking
  • Expert Yacht Delivery — Service delivery KPIs
  • Dangerou