```html

Multi-Domain Executive Reporting Infrastructure: SES Automation, Lambda Deployments, and Real-Time Dashboard Integration

Over the past development session, we built a comprehensive reporting system to deliver executive-level insights across four business entities (JADA, Queen of San Diego, QuickDumpNow, DangerousCentaur) plus three ancillary operations. This infrastructure combines Python SES automation, AWS Lambda serverless functions, and real-time dashboard synchronization to create a scalable reporting pipeline that runs on-demand or scheduled via EventBridge.

What Was Done

We created two parallel reporting pipelines:

  • send_exec_reports.py — A Python script that generates five distinct executive reports (CEO, CTO, Accounting, CMO, CFO perspectives) and dispatches them via AWS SES
  • send_exec_reports_2.py — An iterative version with enhanced error handling and multi-recipient support
  • Lambda integration — Modified the Ship Captain Crew Lambda function to accept incoming report requests and trigger dashboard card creation
  • Dashboard automation — Integrated with an existing dashboard API to create tracking cards for each report

The core workflow: generate report → validate SES credentials → send via AWS SES → log to DynamoDB → create Kanban card on progress dashboard → webhook notification to Slack (optional).

Technical Details: SES Configuration and Credential Management

All SES sender verification happens through environment variables stored in repos.env:


# repos.env (committed, no secrets here)
SES_REGION=us-west-2
SES_FROM_ADDRESS=admin@queenofsandiego.com
SES_RECIPIENT_EMAIL=c.b.ladd@gmail.com

The actual AWS credentials (SES IAM keys) live in ~/.aws/credentials and are loaded via boto3's standard credential chain. This separation ensures that repos.env can be version-controlled while secrets remain out of Git.

The Python script uses boto3's SES client:


import boto3
import os

ses_client = boto3.client(
    'ses',
    region_name=os.environ.get('SES_REGION', 'us-west-2')
)

response = ses_client.send_email(
    Source=os.environ['SES_FROM_ADDRESS'],
    Destination={'ToAddresses': recipients},
    Message={
        'Subject': {'Data': subject},
        'Body': {'Html': {'Data': html_body}}
    }
)

Each report is generated as a formatted HTML string (no external templates) to keep the system lightweight and avoid template injection vulnerabilities. Reports include:

  • CEO Report — Asset inventory across all entities, 8 critical shortfalls (empty pipeline, no revenue tracking, Sergio equity risk, zero OTA listings), 9 missing KPIs, and a 30-day action plan
  • CTO Report — Stack-by-stack audit (JADA/QOS/QDN/DC), 6 security gaps (hardcoded Stripe keys, plaintext repos.env, unauthenticated GAS endpoints), cost analysis (~$50–84/mo AWS), and 10 prioritized engineering actions
  • Accounting Report — Revenue recognition gaps, chart of accounts, expense audit, and 4-milestone profitability roadmap through Q1 2027
  • CMO Report — Channel matrix, case for 3,676-person email blast (modeled at $10K–50K concert bookings), OTA sequencing (Sailo → GetMyBoat → Viator/GYG), and 30/60/90-day milestones
  • CFO Report — Burn rate model (~$7–9K/mo), capital deployment framework, break-even at 6 charters/month, and 3 financial rules

Lambda and Dashboard Integration

The main Lambda function lives at:


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

We added a new route handler /admin/reports/send that accepts POST requests with a report_type parameter and optional recipient_email override. This allows triggering reports on-demand from the admin dashboard without touching the Python script directly.


# Pseudocode for new route
if path == '/admin/reports/send' and method == 'POST':
    auth_token = headers.get('Authorization', '')
    if not verify_admin_token(auth_token):
        return 401_unauthorized()
    
    body = json.loads(event['body'])
    report_type = body['report_type']  # 'ceo', 'cto', 'accounting', etc.
    recipient = body.get('recipient_email', DEFAULT_RECIPIENT)
    
    # Trigger report generation (could invoke send_exec_reports.py via subprocess or SQS)
    response = generate_and_send_report(report_type, recipient)
    
    # Create dashboard card
    dashboard_api.create_task({
        'title': f'{report_type.upper()} Report Generated',
        'description': f'Sent to {recipient}',
        'status': 'in-progress',
        'due_date': datetime.now() + timedelta(days=1)
    })
    
    return 200_ok({'report_id': response['MessageId']})

The Lambda deployment process involved:

  1. Syntax validation — Python syntax checking via python -m py_compile lambda_function.py
  2. Zipping the functionzip -r lambda.zip lambda_function.py
  3. AWS Lambda updateaws lambda update-function-code --function-name ShipCaptainCrew --zip-file fileb://lambda.zip
  4. Frontend sync — Updated the frontend at /shipcaptaincrew/frontend/index.html with a new "Send Reports" admin panel
  5. S3 + CloudFront invalidation — Deployed HTML to S3 bucket (Queen of San Diego static assets) and invalidated the CloudFront distribution cache

Frontend Changes

The admin dashboard (index.html) now includes a report-sending form:


<div id="report-panel" class="admin-section">
  <h3>Send Executive Reports</h3>
  <select id="report-type">
    <option value="ceo">CEO Report</option>
    <option value="cto">CTO Report</option>
    <option value="accounting">Accounting Report</option>
    <option value="cmo">CMO Report</option>
    <option value="cfo">CFO Report</option>
  </select>
  <input type="email" id="recipient" placeholder="Override recipient email" />
  <button onclick="sendReport()">Send