7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
# File 'lib/fast_exists/intelligence/report/html.rb', line 7
def self.render(data, comparison: nil)
hit_pct = (data.stats[:hit_ratio] * 100).round(1)
miss_pct = (data.stats[:miss_ratio] * 100).round(1)
" <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>FastExists Performance & Architecture Report</title>\n <style>\n :root {\n --bg: #0f172a;\n --card-bg: #1e293b;\n --text: #f8fafc;\n --text-muted: #94a3b8;\n --accent: #38bdf8;\n --border: #334155;\n --pass: #22c55e;\n --warn: #eab308;\n --fail: #ef4444;\n }\n @media print {\n body { background: #fff !important; color: #000 !important; }\n .card { border: 1px solid #ccc !important; background: #fff !important; color: #000 !important; }\n }\n body { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif; background: var(--bg); color: var(--text); margin: 0; padding: 2.5rem; line-height: 1.5; }\n .header { border-bottom: 1px solid var(--border); padding-bottom: 1.5rem; margin-bottom: 2rem; }\n .title { font-size: 2.25rem; font-weight: 800; color: var(--accent); margin: 0 0 0.5rem 0; display: flex; align-items: center; gap: 0.5rem; }\n .subtitle { color: var(--text-muted); font-size: 1rem; margin: 0; }\n .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.5rem; margin-bottom: 2.5rem; }\n .card { background: var(--card-bg); border-radius: 0.75rem; padding: 1.5rem; border: 1px solid var(--border); box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1); }\n .card-title { color: var(--text-muted); font-size: 0.875rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.5rem; }\n .card-val { font-size: 2.25rem; font-weight: 800; color: var(--accent); }\n .badge { display: inline-block; padding: 0.25rem 0.75rem; border-radius: 9999px; font-weight: 700; font-size: 0.875rem; text-transform: uppercase; }\n .badge-pass { background: rgba(34, 197, 94, 0.2); color: var(--pass); border: 1px solid var(--pass); }\n .badge-warn { background: rgba(234, 179, 8, 0.2); color: var(--warn); border: 1px solid var(--warn); }\n .badge-fail { background: rgba(239, 68, 68, 0.2); color: var(--fail); border: 1px solid var(--fail); }\n section { margin-bottom: 3rem; }\n h2 { font-size: 1.5rem; border-bottom: 1px solid var(--border); padding-bottom: 0.5rem; margin-bottom: 1.5rem; color: var(--text); }\n table { width: 100%; border-collapse: collapse; margin-top: 1rem; }\n th, td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid var(--border); }\n th { background: rgba(255,255,255,0.03); color: var(--text-muted); font-weight: 600; }\n pre { background: #090d16; padding: 1rem; border-radius: 0.5rem; overflow-x: auto; color: #a5f3fc; border: 1px solid var(--border); font-family: monospace; }\n .chart-bar { background: var(--border); height: 1.25rem; border-radius: 0.25rem; overflow: hidden; display: flex; margin-top: 0.5rem; }\n .chart-fill-hit { background: var(--accent); height: 100%; width: \#{hit_pct}%; }\n .chart-fill-miss { background: #64748b; height: 100%; width: \#{miss_pct}%; }\n </style>\n </head>\n <body>\n <div class=\"header\">\n <h1 class=\"title\">\u26A1 FastExists Performance Intelligence Report</h1>\n <p class=\"subtitle\">Generated on \#{data.timestamp} \u2022 Ruby \#{data.environment[:ruby_version]} \u2022 Rails \#{data.environment[:rails_version]} \u2022 Backend: <strong>\#{data.environment[:backend]}</strong></p>\n </div>\n\n <div class=\"grid\">\n <div class=\"card\">\n <div class=\"card-title\">Overall Health</div>\n <div class=\"card-val\"><span class=\"badge badge-\#{data.health[:overall_status] == :healthy ? 'pass' : 'warn'}\">\#{data.health[:overall_status]}</span></div>\n </div>\n <div class=\"card\">\n <div class=\"card-title\">Architecture Grade</div>\n <div class=\"card-val\">\#{data.audit[:grade]} <span style=\"font-size:1.1rem; color:var(--text-muted)\">( \#{data.audit[:audit_score]}/100 )</span></div>\n </div>\n <div class=\"card\">\n <div class=\"card-title\">Queries Avoided</div>\n <div class=\"card-val\">\#{data.stats[:queries_avoided]}</div>\n </div>\n <div class=\"card\">\n <div class=\"card-title\">Database Lookups</div>\n <div class=\"card-val\">\#{data.stats[:database_lookups]}</div>\n </div>\n </div>\n\n <section>\n <h2>\u{1F4CA} Query Distribution & Bloom Hit Ratio</h2>\n <p>Hit Ratio: <strong>\#{hit_pct}%</strong> | Miss Ratio: <strong>\#{miss_pct}%</strong></p>\n <div class=\"chart-bar\">\n <div class=\"chart-fill-hit\" title=\"Hits: \#{hit_pct}%\"></div>\n <div class=\"chart-fill-miss\" title=\"Avoided: \#{miss_pct}%\"></div>\n </div>\n </section>\n\n <section>\n <h2>\u{1FA7A} Operational Health Checks</h2>\n <table>\n <thead>\n <tr><th>Check Name</th><th>Status</th><th>Message</th></tr>\n </thead>\n <tbody>\n \#{data.health[:checks].map { |c| \"<tr><td><strong>\#{c[:name]}</strong></td><td><span class=\\\"badge badge-\#{c[:status] == :pass ? 'pass' : 'warn'}\\\">\#{c[:status]}</span></td><td>\#{c[:message]}</td></tr>\" }.join(\"\\n\")}\n </tbody>\n </table>\n </section>\n\n <section>\n <h2>\u{1F50D} Architectural Audit Findings</h2>\n \#{data.audit[:findings].map { |f| \"<div class=\\\"card\\\" style=\\\"margin-bottom:1rem;\\\"><div style=\\\"display:flex; justify-between; align-items:center;\\\"><strong>[\#{f[:severity].to_s.upcase}] \#{f[:location]}</strong></div><p style=\\\"color:var(--text-muted)\\\">\#{f[:problem]}</p><p><strong>Recommendation:</strong> \#{f[:recommendation]}</p></div>\" }.join(\"\\n\")}\n </section>\n </body>\n </html>\n HTML\nend\n"
|