playbook/antigravity-awesome-skills/plugins/antigravity-awesome-skills-.../skills/vercel-optimize/lib/cost-coverage.mjs

146 lines
8.4 KiB
JavaScript

// Maps billing line items to gate coverage so report surfaces uncovered dimensions (Sandbox, AI Gateway, Build, …) as blind spots.
import { escapeMarkdownTableCell } from './util.mjs';
// Service → billing dimension. dim=null means uncovered. Substring match — Vercel billing names are stable but untyped.
const SERVICE_DIMENSION = [
{ match: /^Function Duration$/i, dim: 'function-duration' },
{ match: /^Function Invocations$/i, dim: 'function-duration' },
{ match: /^Fluid Active CPU$/i, dim: 'function-duration' },
{ match: /^Fluid Provisioned Memory$/i, dim: 'function-duration' },
{ match: /^Edge Requests$/i, dim: 'edge-requests' },
{ match: /^Edge Requests.*Additional CPU Duration/i, dim: 'edge-requests' },
{ match: /^Edge Function Execution Units$/i, dim: 'edge-requests' },
{ match: /^Edge Middleware Invocations$/i, dim: 'edge-requests' },
{ match: /^ISR (Reads|Writes)$/i, dim: 'isr' },
{ match: /^Speed Insights( Data Points)?$/i, dim: 'speed-insights' },
{ match: /^Image Optimization/i, dim: 'image-optimization' },
// Indirect: bot-protection gate addresses bandwidth/edge spend.
{ match: /^Fast Data Transfer$/i, dim: 'edge-requests' },
{ match: /^Fast Origin Transfer$/i, dim: 'edge-requests' },
// Uncovered.
{ match: /^Sandbox/i, dim: null, family: 'sandbox' },
{ match: /^AI Gateway$/i, dim: null, family: 'ai-gateway' },
{ match: /^Build Minutes$/i, dim: 'build', family: 'build' },
{ match: /^Build CPU Minutes$/i, dim: 'build', family: 'build' },
{ match: /^Private Data Transfer$/i, dim: null, family: 'private-network' },
{ match: /^Secure Compute Network$/i, dim: null, family: 'private-network' },
{ match: /^Drains Volume$/i, dim: null, family: 'drains' },
{ match: /^Observability Events$/i, dim: 'observability-events', family: 'observability-events' },
{ match: /^Blob/i, dim: null, family: 'blob' },
{ match: /^Edge Config (Reads|Writes)$/i, dim: null, family: 'edge-config' },
{ match: /^Runtime Cache/i, dim: null, family: 'runtime-cache' },
{ match: /^Microfrontends/i, dim: null, family: 'microfrontends' },
{ match: /^Workflow/i, dim: null, family: 'workflow' },
{ match: /^Queue/i, dim: null, family: 'queues' },
{ match: /^Flag Requests$/i, dim: null, family: 'flags' },
{ match: /^Flags Explorer/i, dim: null, family: 'flags' },
{ match: /^BotID/i, dim: null, family: 'botid' },
{ match: /^Firewall/i, dim: null, family: 'firewall' },
{ match: /^Vercel Agent$/i, dim: null, family: 'vercel-agent' },
// Fixed costs (seats, contracts) — not actionable.
{ match: /^v0 /i, dim: null, family: 'fixed', actionable: false },
{ match: /^Additional Team Seats$/i, dim: null, family: 'fixed', actionable: false },
{ match: /^SAML$/i, dim: null, family: 'fixed', actionable: false },
{ match: /^HIPAA BAA$/i, dim: null, family: 'fixed', actionable: false },
{ match: /^SIEM Integration$/i, dim: null, family: 'fixed', actionable: false },
{ match: /^Web Analytics/i, dim: null, family: 'fixed', actionable: false },
{ match: /^Static IPs$/i, dim: null, family: 'fixed', actionable: false },
{ match: /^Bulk Redirects$/i, dim: null, family: 'fixed', actionable: false },
{ match: /^Preview Deployment Suffix$/i, dim: null, family: 'fixed', actionable: false },
{ match: /^Rolling Releases$/i, dim: null, family: 'fixed', actionable: false },
{ match: /^Observability Plus$/i, dim: null, family: 'fixed', actionable: false },
{ match: /^Platform Customer Usage$/i, dim: null, family: 'fixed', actionable: false },
{ match: /^Advanced Deployment Protection$/i, dim: null, family: 'fixed', actionable: false },
];
export function classifyService(serviceName, activeDims) {
if (!serviceName) return { covered: false, family: 'unknown' };
for (const e of SERVICE_DIMENSION) {
if (e.match.test(serviceName)) {
if (e.dim && activeDims.has(e.dim)) return { covered: true, dim: e.dim };
return { covered: false, family: e.family ?? 'unknown', actionable: e.actionable ?? true };
}
}
return { covered: false, family: 'unknown', actionable: true };
}
export function computeCostCoverage(usage, gates) {
const services = Array.isArray(usage?.services) ? usage.services : [];
const activeDims = new Set(
(gates ?? [])
.map((g) => g?.metadata?.billingDimension)
.filter((d) => typeof d === 'string' && d !== 'mixed')
);
let total = 0;
let covered = 0;
let uncovered = 0;
const byFamily = new Map();
for (const s of services) {
const billed = Number(s.billedCost ?? 0);
if (!Number.isFinite(billed) || billed <= 0) continue;
total += billed;
const c = classifyService(s.name, activeDims);
if (c.covered) {
covered += billed;
continue;
}
uncovered += billed;
const key = c.family;
const prev = byFamily.get(key) ?? { family: key, billed: 0, services: [], actionable: c.actionable !== false };
prev.billed += billed;
prev.services.push({ name: s.name, billed });
prev.actionable = prev.actionable && (c.actionable !== false);
byFamily.set(key, prev);
}
const uncoveredByFamily = [...byFamily.values()]
.sort((a, b) => b.billed - a.billed)
.map((f) => ({ ...f, services: f.services.sort((a, b) => b.billed - a.billed) }));
// Pick top gaps globally so multiple families surface (Sandbox + AI Gateway + Build, not 5 Sandbox sub-services). Exclude fixed costs — seats aren't actionable workload.
const allActionableServices = [];
for (const family of uncoveredByFamily) {
if (!family.actionable) continue;
for (const s of family.services) {
allActionableServices.push({ name: s.name, billed: s.billed, family: family.family });
}
}
allActionableServices.sort((a, b) => b.billed - a.billed);
const topGaps = allActionableServices.slice(0, 5).map((s) => ({
...s,
share: total > 0 ? s.billed / total : 0,
}));
return { totalBilled: total, coveredBilled: covered, uncoveredBilled: uncovered, uncoveredByFamily, topGaps };
}
export function renderCostCoverageMarkdown(coverage) {
if (!coverage || !Number.isFinite(coverage.totalBilled) || coverage.totalBilled <= 0) return [];
const { totalBilled, coveredBilled, uncoveredBilled, topGaps } = coverage;
const actionableGaps = topGaps.filter((g) => g.share >= 0.01); // 1%+ share
if (actionableGaps.length === 0) return [];
const lines = [];
lines.push('');
lines.push('### Coverage gaps');
lines.push('');
const coveredPct = totalBilled > 0 ? (coveredBilled / totalBilled) * 100 : 0;
const uncoveredPct = totalBilled > 0 ? (uncoveredBilled / totalBilled) * 100 : 0;
lines.push(`This audit has metric coverage for **$${coveredBilled.toFixed(0)} (${coveredPct.toFixed(0)}%)** of this bill via function-duration, edge-requests, ISR, middleware, and image-optimization dimensions. **$${uncoveredBilled.toFixed(0)} (${uncoveredPct.toFixed(0)}%)** sits in billed areas this run cannot analyze safely, including the top actionable items below:`);
lines.push('');
lines.push('| Service | Billed | Share | Family | Coverage |');
lines.push('|---|---|---|---|---|');
for (const g of actionableGaps) {
lines.push(`| ${escapeCell(g.name)} | $${g.billed.toFixed(2)} | ${(g.share * 100).toFixed(1)}% | ${g.family} | _not analyzed in this run_ |`);
}
lines.push('');
lines.push('_Recommendations in this report address the covered dimensions. The uncovered rows are not ignored; they need a separate investigation before we can make safe recommendations._');
return lines;
}
function escapeCell(s) {
return escapeMarkdownTableCell(s);
}