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.pyand a parallel iterationsend_exec_reports_2.pyto 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.pyso 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.cominus-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:SendEmailandses:SendRawEmailpermissions
Deployment Process:
- Local testing: Run
send_exec_reports.pywith--dry-runflag to preview emails without sending - Syntax validation:
python -m py_compile lambda_function.py - Package Lambda:
zip -r lambda.zip . -x '*.git*' '*.env*' - Deploy:
aws lambda update-function-code --function-name ship-captain-crew --zip-file fileb://lambda.zip - Verify: Call the new endpoint with an admin JWT token to test report generation
Key Decisions
Why SES instead of Send