```html

Building a Multi-Stakeholder Executive Intelligence System: Automated Report Generation via AWS Lambda and SES

Over the past development session, we built and deployed an automated executive reporting infrastructure capable of generating stakeholder-specific intelligence reports and delivering them via Amazon SES. This system addresses a critical gap: organizational leaders across different domains (operations, technology, finance, marketing) need customized views of the same underlying asset portfolio, but manually synthesizing those views is brittle and non-scalable.

What Was Done

We created a two-phase reporting system:

  • Phase 1 (Local Execution): Built /Users/cb/Documents/repos/tools/send_exec_reports.py and a parallel iteration send_exec_reports_2.py to generate five domain-specific reports from a unified project knowledge base.
  • Phase 2 (Deployment): Integrated report generation triggers into the Ship Captain Crew Lambda function at /Users/cb/Documents/repos/sites/queenofsandiego.com/tools/shipcaptaincrew/lambda_function.py so reports can be generated on-demand or on a schedule via EventBridge.

The five initial reports target these personas:

  • CEO/Executive: Asset inventory, profitability gaps, KPI definitions, 30-day action items across JADA, QuickDumpNow, DangerousCentaur, and QueenofSanDiego entities.
  • CTO/Engineering: Techstack audit, security hardening roadmap, cost optimization analysis, development cycle gaps, prioritized engineering actions.
  • Chief Accounting Officer: Revenue recognition model, chart of accounts, expense audit, financial system roadmap.
  • CMO/Marketing: Channel visibility matrix, customer acquisition sequencing, OTA strategy, local SEO roadmap.
  • CFO/Finance: Burn rate modeling, capital deployment framework, break-even analysis, monthly revenue targets.

An additional three reports were identified as necessary but not yet generated: 3028 51st St Rental, Expert Yacht Delivery, and DangerousCentaur Client Portfolio (billing audit).

Technical Details

Report Generation Architecture

The reporting system reads from a canonical project knowledge base and applies domain-specific filters and calculations:


# Pseudocode structure (actual implementation in send_exec_reports.py)
load_all_projects()  # From repos.env, agent_handoffs/projects/*.md
load_financial_data()  # From CFO tracking
load_asset_inventory()  # From site repos
load_dev_artifacts()  # From lambda_function.py, frontend/index.html edits

for persona in [CEO, CTO, ACCOUNTING, CMO, CFO]:
    report = generate_report(
        persona=persona,
        projects=projects,
        financial_data=financial_data,
        assets=assets,
        dev_metrics=dev_metrics
    )
    send_via_ses(
        to=persona_email,
        subject=report.title,
        body=report.html,
        bcc='admin@queenofsandiego.com'
    )

Each report is generated as structured HTML (not plain text) to preserve formatting and enable click-through analytics if integrated with SES event publishing later.

SES Integration

Reports are sent via AWS SES (Simple Email Service) using the verified sender address admin@queenofsandiego.com. The SES configuration lives in:

  • Sender identity: Verified in AWS SES console for admin@queenofsandiego.com
  • Region: us-east-1 (standard for this infrastructure)
  • Credentials: Pulled from repos.env (IAM user with SES:SendEmail permission)
  • Recipient tracking: BCC to admin inbox for archival; primary to c.b.ladd@gmail.com for initial validation

The reason for BCC rather than explicit CC is auditability without polluting stakeholder inboxes during the pilot phase.

Lambda Integration

The Ship Captain Crew Lambda function was modified to include report-generation hooks. Key changes:

  • File: /Users/cb/Documents/repos/sites/queenofsandiego.com/tools/shipcaptaincrew/lambda_function.py
  • New endpoint: POST /generate-reports (requires admin JWT token)
  • Trigger: Can be called directly via API or scheduled via EventBridge cron rule (e.g., monthly on the 1st at 08:00 UTC)
  • Idempotency: Reports include a timestamp to prevent duplicate processing if Lambda retries occur

The Lambda function imports the report generation logic as a module, avoiding code duplication between local and cloud execution paths.

Infrastructure

File Structure:


/Users/cb/Documents/repos/
├── tools/
│   ├── send_exec_reports.py          # Main report generator
│   └── send_exec_reports_2.py        # Secondary version (iteration)
├── sites/queenofsandiego.com/
│   └── tools/shipcaptaincrew/
│       ├── lambda_function.py         # AWS Lambda handler (modified)
│       └── frontend/index.html        # Dashboard frontend (unchanged)
└── agent_handoffs/projects/
    └── shipcaptaincrew.md            # Project context and handoffs

AWS Resources:

  • Lambda Function: arn:aws:lambda:us-east-1:*:function:ship-captain-crew (modified to support report generation)
  • SES: Verified sender admin@queenofsandiego.com in us-east-1
  • EventBridge (Future): Rule name ptb_monthly_exec_reports (not yet created, but infrastructure is ready)
  • IAM Role: Lambda execution role must include ses:SendEmail and ses:SendRawEmail permissions

Deployment Process:

  1. Local testing: Run send_exec_reports.py with --dry-run flag to preview emails without sending
  2. Syntax validation: python -m py_compile lambda_function.py
  3. Package Lambda: zip -r lambda.zip . -x '*.git*' '*.env*'
  4. Deploy: aws lambda update-function-code --function-name ship-captain-crew --zip-file fileb://lambda.zip
  5. Verify: Call the new endpoint with an admin JWT token to test report generation

Key Decisions

Why SES instead of Send