from fpdf import FPDF class DeploymentReport(FPDF): def header(self): self.set_fill_color(20, 40, 80) # Navy Blue self.rect(0, 0, 210, 40, 'F') self.set_text_color(255, 255, 255) self.set_font('Arial', 'B', 16) self.cell(0, 20, 'Deployment Analysis Report', ln=True, align='C') self.set_font('Arial', '', 12) self.cell(0, 10, 'Tillo - Canteen Automation Ecosystem', ln=True, align='C') self.ln(20) def footer(self): self.set_y(-15) self.set_font('Arial', 'I', 8) self.set_text_color(128, 128, 128) self.cell(0, 10, f'Page {self.page_no()} | Generated by Claude Code', align='C') def section_title(self, title): self.ln(5) self.set_font('Arial', 'B', 14) self.set_text_color(20, 40, 80) self.cell(0, 10, title, ln=True) self.ln(2) self.set_draw_color(20, 40, 80) self.line(self.get_x(), self.get_y(), self.get_x() + 190, self.get_y()) self.ln(5) def section_body(self, text): self.set_font('Arial', '', 11) self.set_text_color(0, 0, 0) self.multi_cell(0, 7, text) self.ln(3) def create_table(self, header, data): self.ln(5) self.set_font('Arial', 'B', 10) self.set_fill_color(230, 230, 230) col_width = 190 / len(header) for i, h in enumerate(header): self.cell(col_width, 10, h, 1, 0, 'C', fill=True) self.ln() self.set_font('Arial', '', 9) for row in data: for item in row: self.cell(col_width, 10, str(item), 1) self.ln() self.ln(5) pdf = DeploymentReport() pdf.add_page() # Section 1: Infrastructure Analysis pdf.section_title("1. Infrastructure Analysis & Resource Requirements") infra_text = ( "The system follows a Hub-and-Spoke architecture with a central Java backend and three React frontends.\n\n" "Backend (Java 17 / Spring Boot):\n" "- CPU: 4 vCPUs recommended for high-concurrency request processing.\n" "- RAM: 8GB RAM is the critical baseline to avoid Out-Of-Memory (OOM) crashes during peak hours.\n\n" "Database (PostgreSQL):\n" "- High-performance NVMe SSD is essential to prevent I/O bottlenecks, especially during daily archival tasks.\n" "- Recommended: 2 vCPUs / 4GB RAM.\n\n" "Frontends (React/Vite):\n" "- Purely static assets; should be served via a Global CDN for low latency." ) pdf.section_body(infra_text) # Section 2: Deployment Options pdf.section_title("2. Deployment Options") pdf.set_font('Arial', 'B', 12) pdf.cell(0, 10, "Option A: The Managed Powerhouse (GCP/AWS)", ln=True) pdf.section_body("Best for Enterprise reliability and automatic scaling. Use Cloud Run/Fargate for Backend, Managed SQL for DB, and S3/CloudFront for Frontends. Pros: Highest reliability. Cons: Highest cost.") pdf.set_font('Arial', 'B', 12) pdf.cell(0, 10, "Option B: The Developer's Balance (DigitalOcean/Railway)", ln=True) pdf.section_body("Recommended. Best balance of cost, ease of use, and stability. Use Premium Droplets (4vCPU/8GB) and Managed PostgreSQL. Frontends on Vercel/Netlify. Pros: Predictable pricing, fast setup.") pdf.set_font('Arial', 'B', 12) pdf.cell(0, 10, "Option C: The Budget Optimizer (Hetzner/OVH)", ln=True) pdf.section_body("Best for minimum cost. Single powerful VPS hosting both API and DB via Docker Compose. Frontends on Cloudflare Pages. Pros: Lowest cost. Cons: High maintenance burden.") # Section 3: Comparison Matrix pdf.section_title("3. Comparison Matrix") header = ["Dimension", "Option A", "Option B", "Option C"] data = [ ["Monthly Cost", "High (~$150+)", "Medium (~$60-90)", "Low (~$20-40)"], ["Setup Effort", "Medium", "Low", "High"], ["Scalability", "Automatic", "Manual/Vertical", "Manual/Vertical"], ["Reliability", "99.99%", "99.9%", "Moderate"], ["Maintenance", "Near Zero", "Low", "High"] ] pdf.create_table(header, data) # Section 4: Operational Strategy pdf.section_title("4. Operational Strategy") ops_text = ( "CI/CD Flow: GitHub Actions -> Maven/Vite Build -> Docker Image -> Rolling Update.\n\n" "Security:\n" "- Secret Management: Use environment variable managers; never commit .env files.\n" "- CORS Strategy: Set APP_CORS_ORIGINS to allow only the three specific production frontend domains.\n" "- Backups: Automated daily snapshots via managed database providers.\n\n" "Monitoring: Implement Spring Boot Actuator to monitor JVM heap and thread counts in real-time." ) pdf.section_body(ops_text) pdf.output("Deployment_Report_Tillo.pdf")