playbook/antigravity-awesome-skills/plugins/antigravity-awesome-skills-.../skills/vercel-optimize/lib/gates/uncached-route.mjs

94 lines
3.9 KiB
JavaScript

// getShare>0.20 filter WHY: a route that's >80% POST/PUT/DELETE is a mutation endpoint
// where 0% cache is correct — recommending caching there is wrong.
// cache_result values STALE/REVALIDATED/BYPASS fold into "total but not HIT" — matches the "uncached" framing.
import { withRouteShapeWarnings } from '../route-normalize.mjs';
const MIN_GET_SHARE = 0.20;
/** @type {import('./types.d.ts').GateMetadata} */
export const metadata = {
id: 'uncached_route',
threshold: `requests > 500 AND hitRate < 0.5 AND getShare > ${MIN_GET_SHARE} (missing getShare is gated)`,
billingDimension: 'edge-requests',
scope: 'route',
sourceCitation: 'vercel-optimize gate threshold',
description:
'Routes serving > 500 requests/period at < 50% cache hit AND at least 20% GET traffic. Each uncached GET request reaches the function, costing edge requests + function duration. Routes that are mostly POST/PUT/DELETE (Server Actions, mutations) are skipped — 0% cache is correct behavior there. Routes with missing method-share data are gated instead of launched. Auth-gated routes are disqualified separately.',
};
/**
* @param {import('./types.d.ts').Signals} signals
* @returns {import('./types.d.ts').Candidate[]}
*/
export function gate(signals) {
const rates = extractCacheHitRates(signals);
const methods = extractMethodShares(signals);
return rates
.map((r) => ({ ...r, getShare: methods.get(r.route) ?? null }))
.filter((r) => r.requests > 500 && r.hitRate < 0.5)
.filter((r) => r.getShare === null || r.getShare > MIN_GET_SHARE)
.map((r) => {
const candidate = withRouteShapeWarnings({
kind: metadata.id,
scope: 'route',
route: r.route,
files: [],
priority: Math.round(r.requests * (1 - r.hitRate)),
confidence: r.getShare === null ? 0.5 : 0.92,
o11ySignal: `requests=${r.requests},cache=${(r.hitRate * 100).toFixed(0)}%${r.getShare !== null ? `,get=${(r.getShare * 100).toFixed(0)}%` : ''}`,
reason: 'uncached high-traffic route',
question: `Why does ${r.route} have ${(r.hitRate * 100).toFixed(0)}% cache hit rate on ${r.requests} requests in this metrics window, and is it safe to cache at the edge?`,
evidence: { metric: 'requestsByRouteCache', route: r.route, requests: r.requests, hitRate: r.hitRate, getShare: r.getShare },
}, signals);
if (r.getShare !== null) return candidate;
return {
...candidate,
disqualified: true,
disqualifyReason: 'missing GET-share data — route method mix is required before recommending edge caching',
warnings: [...new Set([...(candidate.warnings ?? []), 'method-share:missing'])],
};
});
}
function extractCacheHitRates(signals) {
const m = signals.metrics?.requestsByRouteCache;
if (!m?.ok && !Array.isArray(m?.rows)) return [];
const perRoute = new Map();
for (const row of (m?.rows ?? [])) {
const route = row.route;
if (!route) continue;
const value = row.value ?? 0;
const prior = perRoute.get(route) ?? { route, hits: 0, total: 0 };
if (row.cache_result === 'HIT') prior.hits += value;
prior.total += value;
perRoute.set(route, prior);
}
return [...perRoute.values()].map((r) => ({
route: r.route,
requests: r.total,
hitRate: r.total > 0 ? r.hits / r.total : 0,
}));
}
function extractMethodShares(signals) {
const m = signals.metrics?.requestsByRouteMethod;
const out = new Map();
if (!Array.isArray(m?.rows)) return out;
const perRoute = new Map();
for (const row of m.rows) {
if (!row?.route) continue;
const v = row.value ?? 0;
const prior = perRoute.get(row.route) ?? { gets: 0, total: 0 };
if ((row.request_method ?? '').toUpperCase() === 'GET') prior.gets += v;
prior.total += v;
perRoute.set(row.route, prior);
}
for (const [route, r] of perRoute) {
if (r.total > 0) out.set(route, r.gets / r.total);
}
return out;
}