Building a Multi-Domain Executive Reporting System: Infrastructure, Deployment, and Architectural Decisions
Over the past development session, we built and deployed a comprehensive executive reporting pipeline that analyzes four distinct business entities (JADA, QueenofSanDiego, QuickDumpNow, DangerousCentaur) from multiple C-suite perspectives. This article covers the technical architecture, infrastructure decisions, and deployment patterns that made this possible.
The Problem We Solved
Our organization needed rapid, perspective-driven analysis across multiple business units without building separate reporting tools for each stakeholder. A CEO, CTO, CFO, CMO, and Chief Accounting Officer all needed different cuts of the same underlying data—but generated independently, without manual consolidation.
The solution: a parameterized reporting system backed by AWS SES for delivery, with Python as the orchestration layer.
Architecture Overview
The reporting infrastructure consists of three layers:
- Data Collection Layer: Multiple source files across repositories (project handoffs, environment configs, site structures)
- Report Generation Layer: Python scripts that read sources and render perspective-specific analysis
- Delivery Layer: AWS SES integration for authenticated email distribution
This is deliberately kept simple—no databases, queues, or Lambda—because report generation is a batch process that runs on-demand, not in real-time.
Core Implementation: Report Generation
We created two main Python files during development:
/Users/cb/Documents/repos/tools/send_exec_reports.py
/Users/cb/Documents/repos/tools/send_exec_reports_2.py
The first file implements the core reporting logic. It reads from multiple sources:
repos.env— Environment variables including SES configuration/agent_handoffs/projects/*.md— Project status documents with financial and operational detail- Direct file system inspection of site structures under
/sites/queenofsandiego.com/,/sites/quickdumpnow/, etc.
The script instantiates five separate report generators, each with a distinct persona and analytical lens:
- CEO Report: Asset inventory, critical shortfalls, missing KPIs, 30-day action agenda
- CTO Report: Tech stack audit per domain, security gaps, cost analysis, UX gaps, dev cycle improvements
- Accounting Officer Report: Revenue recognition, chart of accounts, expense audit, profitability roadmap
- CMO Report: Channel visibility, blast campaign ROI modeling, OTA sequencing, local SEO roadmap
- CFO Report: Burn rate model, capital deployment framework, break-even analysis, financial rules
Each report is rendered as plain text and sent via SES to the primary recipient (BCC'd to an admin address for audit trail).
SES Integration and Authentication
AWS SES configuration is stored in repos.env with the following pattern:
SES_REGION=us-west-2
SES_ACCESS_KEY_ID=[REDACTED]
SES_SECRET_ACCESS_KEY=[REDACTED]
SES_FROM_ADDRESS=admin@queenofsandiego.com
SES_BCC_ADDRESS=admin@queenofsandiego.com
The admin@queenofsandiego.com address is a verified SES sender identity. We chose this hardcoded address rather than parameterizing it because:
- Audit trail: All system-generated reports flow through one verified sender, creating a clear chain of custody
- Reduced SES configuration: No need to verify additional sender identities; one verified address scales to all reports
- Security: Report delivery cannot be redirected to arbitrary addresses—the sender is fixed at the system level
The Python SES client initializes with explicit region and credential parameters, avoiding reliance on IAM role assumptions (which would couple this to specific EC2/Lambda contexts).
Data Sources and File Structure
Report generation required reading multiple file formats:
- Markdown handoffs:
/agent_handoffs/projects/shipcaptaincrew.mdand similar files contain structured project state - Environment files:
repos.envprovides system configuration without hardcoding - Lambda code inspection:
/sites/queenofsandiego.com/tools/shipcaptaincrew/lambda_function.pyanalyzed for tech stack inventory - Frontend inspection:
/sites/queenofsandiego.com/tools/shipcaptaincrew/frontend/index.htmlreviewed for UX and analytics presence
This multi-source approach avoids a single source of truth, which would require maintaining a central database. Instead, we treat the file system as the source of record and generate reports on-demand by synthesizing what's actually on disk.
Key Architectural Decisions
Decision 1: No Database
We could have built a central reporting database with normalized tables for revenue, expenses, and KPIs. Instead, we parse from existing markdown handoffs and config files. This trades query flexibility for operational simplicity—no schema migrations, no database credentials, no need to sync data across systems. Reports are slower but more maintainable.
Decision 2: Synchronous, On-Demand Execution
Reports are generated when explicitly requested, not on a schedule. This avoids false data freshness (if a report is 2 days old, everyone knows it) and eliminates cron job infrastructure. The trade-off is that report generation blocks until SES delivery completes, but SES latency is typically under 5 seconds.
Decision 3: Plain Text over HTML
Reports are formatted as plain text, not HTML email. This ensures readability across all clients (mobile, web, plain-text readers) and reduces email rendering bugs. The trade-off is less visual polish, but for C-suite reports, clarity and universality matter more than aesthetics.
Decision 4: Separate Role-Based Scripts
Rather than a single parameterized report engine, we have distinct script instances per role. This means duplicated code but maximum clarity for future maintainers—each script is self-contained and its analytical lens is explicit, not hidden in conditional logic.
Operational Patterns
The reporting system was tested through multiple execution cycles:
Send 5 executive reports via SES
Send 3 additional reports and create dashboard task
Verify Lambda deployment
Create test event with admin token
Each execution wrote logs to stdout and verified delivery by checking recipient inboxes. We used the AWS CLI to inspect SES send statistics but did not integrate detailed logging back into the codebase—reports either succeed (exit 0, email arrives) or fail (exception, logs to console).
Security Hardening
Several hardening measures were applied:
- SES credentials stored in
repos.env, which is git-ignored - No credentials logged; only metadata (recipient, subject line)
- All report content is read-only synthesis—no writes to external systems
- BCC verification ensures