fix: authenticate field performance evidence context
This commit is contained in:
@@ -4,23 +4,19 @@ import {
|
||||
evaluateFieldBudget,
|
||||
percentile75,
|
||||
} from "../src/application/policies/performance-budgets.js";
|
||||
import { validateFieldEvidenceInput } from "./lib/field-vitals-evidence.mjs";
|
||||
|
||||
const inputPath =
|
||||
process.env.FIELD_WEB_VITALS_INPUT ??
|
||||
"config/performance/field-input.example.json";
|
||||
const input =
|
||||
/** @type {{
|
||||
* releaseId: string,
|
||||
* samples: Array<{
|
||||
* timestamp: string,
|
||||
* consent: boolean,
|
||||
* releaseId: string,
|
||||
* routeId: string,
|
||||
* lcpMs: number,
|
||||
* cls: number,
|
||||
* inpMs: number
|
||||
* }>
|
||||
* }} */ (JSON.parse(await readFile(inputPath, "utf8")));
|
||||
const rawInput = JSON.parse(await readFile(inputPath, "utf8"));
|
||||
const now = new Date();
|
||||
const validation = validateFieldEvidenceInput(
|
||||
rawInput,
|
||||
process.env.MIN_ELIGIBLE_SAMPLES,
|
||||
now,
|
||||
);
|
||||
const input = validation.data;
|
||||
const configured =
|
||||
/** @type {{
|
||||
* p75LcpMs: number,
|
||||
@@ -30,17 +26,17 @@ const configured =
|
||||
* }} */ (
|
||||
JSON.parse(await readFile("config/performance/budgets.json", "utf8")).field
|
||||
);
|
||||
const minimumEligibleSamples = process.env.MIN_ELIGIBLE_SAMPLES
|
||||
? Number(process.env.MIN_ELIGIBLE_SAMPLES)
|
||||
: configured.minimumEligibleSamples;
|
||||
const end = new Date();
|
||||
const start = new Date(end);
|
||||
start.setUTCDate(start.getUTCDate() - 28);
|
||||
const eligible = input.samples.filter((sample) => {
|
||||
const minimumEligibleSamples = validation.minimumEligibleSamples;
|
||||
const fallbackEnd = now;
|
||||
const fallbackStart = new Date(fallbackEnd);
|
||||
fallbackStart.setUTCDate(fallbackStart.getUTCDate() - 28);
|
||||
const start = input ? new Date(input.window.start) : fallbackStart;
|
||||
const end = input ? new Date(input.window.end) : fallbackEnd;
|
||||
const eligible = (input?.samples ?? []).filter((sample) => {
|
||||
const timestamp = new Date(sample.timestamp);
|
||||
return (
|
||||
sample.consent === true &&
|
||||
sample.releaseId === input.releaseId &&
|
||||
sample.releaseId === input?.releaseId &&
|
||||
timestamp >= start &&
|
||||
timestamp <= end
|
||||
);
|
||||
@@ -55,6 +51,8 @@ const result = evaluateFieldBudget(
|
||||
{ metrics, eligibleSamples: eligible.length },
|
||||
thresholds,
|
||||
);
|
||||
const passed = validation.passed && result.passed;
|
||||
const status = validation.passed ? result.status : "FAIL_UNVERIFIED";
|
||||
const routeSamples = Object.fromEntries(
|
||||
Object.entries(
|
||||
eligible.reduce(
|
||||
@@ -68,24 +66,30 @@ const routeSamples = Object.fromEntries(
|
||||
);
|
||||
const report = {
|
||||
schemaVersion: 1,
|
||||
generatedAt: end.toISOString(),
|
||||
generatedAt: now.toISOString(),
|
||||
window: { days: 28, start: start.toISOString(), end: end.toISOString() },
|
||||
context: {
|
||||
source: inputPath,
|
||||
sourceSystem: input?.source.system ?? null,
|
||||
exportId: input?.source.exportId ?? null,
|
||||
network: "production-real-user",
|
||||
routeAggregation: "route-id-only",
|
||||
releaseId: input.releaseId,
|
||||
releaseId: input?.releaseId ?? null,
|
||||
privacyApprovalRef: input?.privacy.approvalRef ?? null,
|
||||
thresholdDecisionRef: input?.thresholdDecision.evidenceRef ?? null,
|
||||
validationFailures: validation.failures,
|
||||
},
|
||||
metrics,
|
||||
thresholds,
|
||||
eligibility: {
|
||||
consentRequired: true,
|
||||
totalSamples: input?.samples.length ?? 0,
|
||||
eligibleSamples: eligible.length,
|
||||
minimumEligibleSamples,
|
||||
routeSamples,
|
||||
},
|
||||
status: result.status,
|
||||
passed: result.passed,
|
||||
status,
|
||||
passed,
|
||||
};
|
||||
|
||||
await mkdir("artifacts/performance", { recursive: true });
|
||||
@@ -93,9 +97,9 @@ await writeFile(
|
||||
"artifacts/performance/field-web-vitals.json",
|
||||
`${JSON.stringify(report, null, 2)}\n`,
|
||||
);
|
||||
if (!result.passed) {
|
||||
if (!passed) {
|
||||
process.stderr.write(
|
||||
`Field Web Vitals: ${result.status} (minimum eligible sample threshold and 28-day production data are required)\n`,
|
||||
`Field Web Vitals: ${status} (approved threshold decision and valid 28-day production evidence are required)\n`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user