mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
refactor(qa-lab): use native strict object schemas
This commit is contained in:
@@ -19,192 +19,151 @@ const qaEvidenceStatusSchema = z.enum(["pass", "fail", "blocked", "skipped"]);
|
||||
const nonEmptyStringSchema = z.string().trim().min(1);
|
||||
const nullableStringSchema = nonEmptyStringSchema.nullable();
|
||||
const qaEvidenceProfileIdSchema = nonEmptyStringSchema;
|
||||
const qaEvidenceIdSchema = z.object({ id: nonEmptyStringSchema });
|
||||
const qaEvidenceIdSchema = z.strictObject({ id: nonEmptyStringSchema });
|
||||
|
||||
const qaEvidenceProviderSchema = z
|
||||
.object({
|
||||
id: nonEmptyStringSchema,
|
||||
live: z.boolean(),
|
||||
model: z
|
||||
.object({
|
||||
name: nullableStringSchema,
|
||||
ref: nullableStringSchema,
|
||||
})
|
||||
.strict(),
|
||||
fixture: nonEmptyStringSchema.optional(),
|
||||
auth: nonEmptyStringSchema.optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
const qaEvidenceChannelSchema = z
|
||||
.object({
|
||||
id: nonEmptyStringSchema,
|
||||
live: z.boolean(),
|
||||
driver: nonEmptyStringSchema.optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
const qaEvidenceEnvironmentSchema = z
|
||||
.object({
|
||||
const qaEvidenceProviderSchema = z.strictObject({
|
||||
id: nonEmptyStringSchema,
|
||||
live: z.boolean(),
|
||||
model: z.strictObject({
|
||||
name: nullableStringSchema,
|
||||
ref: nullableStringSchema,
|
||||
os: nonEmptyStringSchema,
|
||||
nodeVersion: nonEmptyStringSchema,
|
||||
})
|
||||
.strict();
|
||||
}),
|
||||
fixture: nonEmptyStringSchema.optional(),
|
||||
auth: nonEmptyStringSchema.optional(),
|
||||
});
|
||||
|
||||
const qaEvidencePackageSourceSchema = z
|
||||
.object({
|
||||
kind: nonEmptyStringSchema,
|
||||
spec: nonEmptyStringSchema.optional(),
|
||||
sha: nonEmptyStringSchema.optional(),
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceChannelSchema = z.strictObject({
|
||||
id: nonEmptyStringSchema,
|
||||
live: z.boolean(),
|
||||
driver: nonEmptyStringSchema.optional(),
|
||||
});
|
||||
|
||||
const qaEvidenceFailureSchema = z
|
||||
.object({
|
||||
class: nonEmptyStringSchema.optional(),
|
||||
reason: nonEmptyStringSchema,
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceEnvironmentSchema = z.strictObject({
|
||||
ref: nullableStringSchema,
|
||||
os: nonEmptyStringSchema,
|
||||
nodeVersion: nonEmptyStringSchema,
|
||||
});
|
||||
|
||||
const qaEvidenceTimingSchema = z
|
||||
.object({
|
||||
wallMs: z.number().finite().positive().optional(),
|
||||
rttMs: z.number().finite().positive().optional(),
|
||||
avgMs: z.number().finite().positive().optional(),
|
||||
p50Ms: z.number().finite().positive().optional(),
|
||||
p95Ms: z.number().finite().positive().optional(),
|
||||
maxMs: z.number().finite().positive().optional(),
|
||||
samples: z.number().int().positive().optional(),
|
||||
failedSamples: z.number().int().nonnegative().optional(),
|
||||
})
|
||||
.strict();
|
||||
const qaEvidencePackageSourceSchema = z.strictObject({
|
||||
kind: nonEmptyStringSchema,
|
||||
spec: nonEmptyStringSchema.optional(),
|
||||
sha: nonEmptyStringSchema.optional(),
|
||||
});
|
||||
|
||||
const qaEvidenceTestSchema = z
|
||||
.object({
|
||||
kind: nonEmptyStringSchema,
|
||||
id: nonEmptyStringSchema,
|
||||
title: nonEmptyStringSchema,
|
||||
source: z
|
||||
.object({
|
||||
path: nonEmptyStringSchema,
|
||||
})
|
||||
.strict()
|
||||
.optional(),
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceFailureSchema = z.strictObject({
|
||||
class: nonEmptyStringSchema.optional(),
|
||||
reason: nonEmptyStringSchema,
|
||||
});
|
||||
|
||||
const qaEvidenceRefSchema = z
|
||||
.object({
|
||||
kind: nonEmptyStringSchema,
|
||||
path: nonEmptyStringSchema,
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceTimingSchema = z.strictObject({
|
||||
wallMs: z.number().finite().positive().optional(),
|
||||
rttMs: z.number().finite().positive().optional(),
|
||||
avgMs: z.number().finite().positive().optional(),
|
||||
p50Ms: z.number().finite().positive().optional(),
|
||||
p95Ms: z.number().finite().positive().optional(),
|
||||
maxMs: z.number().finite().positive().optional(),
|
||||
samples: z.number().int().positive().optional(),
|
||||
failedSamples: z.number().int().nonnegative().optional(),
|
||||
});
|
||||
|
||||
const qaEvidenceCoverageSchema = qaEvidenceIdSchema
|
||||
.extend({
|
||||
role: nonEmptyStringSchema,
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceTestSchema = z.strictObject({
|
||||
kind: nonEmptyStringSchema,
|
||||
id: nonEmptyStringSchema,
|
||||
title: nonEmptyStringSchema,
|
||||
source: z
|
||||
.strictObject({
|
||||
path: nonEmptyStringSchema,
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
const qaEvidenceScorecardCountSchema = z
|
||||
.object({
|
||||
total: z.number().int().nonnegative(),
|
||||
fulfilled: z.number().int().nonnegative(),
|
||||
partial: z.number().int().nonnegative().optional(),
|
||||
missing: z.number().int().nonnegative(),
|
||||
fulfillmentPercent: z.number().finite().nonnegative(),
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceRefSchema = z.strictObject({
|
||||
kind: nonEmptyStringSchema,
|
||||
path: nonEmptyStringSchema,
|
||||
});
|
||||
|
||||
const qaEvidenceCoverageSchema = qaEvidenceIdSchema.extend({
|
||||
role: nonEmptyStringSchema,
|
||||
});
|
||||
|
||||
const qaEvidenceScorecardCountSchema = z.strictObject({
|
||||
total: z.number().int().nonnegative(),
|
||||
fulfilled: z.number().int().nonnegative(),
|
||||
partial: z.number().int().nonnegative().optional(),
|
||||
missing: z.number().int().nonnegative(),
|
||||
fulfillmentPercent: z.number().finite().nonnegative(),
|
||||
});
|
||||
|
||||
const qaEvidenceScorecardCoverageCountSchema = qaEvidenceScorecardCountSchema.extend({
|
||||
secondaryOnly: z.number().int().nonnegative(),
|
||||
});
|
||||
|
||||
const qaEvidenceScorecardCategorySchema = z
|
||||
.object({
|
||||
id: nonEmptyStringSchema,
|
||||
surfaceId: nonEmptyStringSchema,
|
||||
name: nonEmptyStringSchema,
|
||||
status: z.enum(["fulfilled", "partial", "missing"]),
|
||||
features: qaEvidenceScorecardCountSchema,
|
||||
coverageIds: qaEvidenceScorecardCoverageCountSchema,
|
||||
missingCoverageIds: z.array(nonEmptyStringSchema),
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceScorecardCategorySchema = z.strictObject({
|
||||
id: nonEmptyStringSchema,
|
||||
surfaceId: nonEmptyStringSchema,
|
||||
name: nonEmptyStringSchema,
|
||||
status: z.enum(["fulfilled", "partial", "missing"]),
|
||||
features: qaEvidenceScorecardCountSchema,
|
||||
coverageIds: qaEvidenceScorecardCoverageCountSchema,
|
||||
missingCoverageIds: z.array(nonEmptyStringSchema),
|
||||
});
|
||||
|
||||
const qaEvidenceScorecardSchema = z
|
||||
.object({
|
||||
filters: z
|
||||
.object({
|
||||
surface: nullableStringSchema,
|
||||
category: nullableStringSchema,
|
||||
})
|
||||
.strict(),
|
||||
run: z
|
||||
.object({
|
||||
evidenceEntryCount: z.number().int().nonnegative(),
|
||||
})
|
||||
.strict(),
|
||||
categories: qaEvidenceScorecardCountSchema,
|
||||
features: qaEvidenceScorecardCountSchema,
|
||||
coverageIds: qaEvidenceScorecardCountSchema,
|
||||
categoryReports: z.array(qaEvidenceScorecardCategorySchema),
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceScorecardSchema = z.strictObject({
|
||||
filters: z.strictObject({
|
||||
surface: nullableStringSchema,
|
||||
category: nullableStringSchema,
|
||||
}),
|
||||
run: z.strictObject({
|
||||
evidenceEntryCount: z.number().int().nonnegative(),
|
||||
}),
|
||||
categories: qaEvidenceScorecardCountSchema,
|
||||
features: qaEvidenceScorecardCountSchema,
|
||||
coverageIds: qaEvidenceScorecardCountSchema,
|
||||
categoryReports: z.array(qaEvidenceScorecardCategorySchema),
|
||||
});
|
||||
|
||||
const qaEvidenceArtifactSchema = z
|
||||
.object({
|
||||
kind: nonEmptyStringSchema,
|
||||
path: nonEmptyStringSchema,
|
||||
source: nonEmptyStringSchema,
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceArtifactSchema = z.strictObject({
|
||||
kind: nonEmptyStringSchema,
|
||||
path: nonEmptyStringSchema,
|
||||
source: nonEmptyStringSchema,
|
||||
});
|
||||
|
||||
const qaEvidenceExecutionSchema = z
|
||||
.object({
|
||||
runner: nonEmptyStringSchema,
|
||||
environment: qaEvidenceEnvironmentSchema,
|
||||
provider: qaEvidenceProviderSchema,
|
||||
channel: qaEvidenceChannelSchema.optional(),
|
||||
packageSource: qaEvidencePackageSourceSchema,
|
||||
artifacts: z.array(qaEvidenceArtifactSchema),
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceExecutionSchema = z.strictObject({
|
||||
runner: nonEmptyStringSchema,
|
||||
environment: qaEvidenceEnvironmentSchema,
|
||||
provider: qaEvidenceProviderSchema,
|
||||
channel: qaEvidenceChannelSchema.optional(),
|
||||
packageSource: qaEvidencePackageSourceSchema,
|
||||
artifacts: z.array(qaEvidenceArtifactSchema),
|
||||
});
|
||||
|
||||
const qaEvidenceResultSchema = z
|
||||
.object({
|
||||
status: qaEvidenceStatusSchema,
|
||||
failure: qaEvidenceFailureSchema.optional(),
|
||||
timing: qaEvidenceTimingSchema.optional(),
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceResultSchema = z.strictObject({
|
||||
status: qaEvidenceStatusSchema,
|
||||
failure: qaEvidenceFailureSchema.optional(),
|
||||
timing: qaEvidenceTimingSchema.optional(),
|
||||
});
|
||||
|
||||
const qaEvidencePostureSchema = z.enum(["direct-gateway", "native-approval", "user-path"]);
|
||||
|
||||
const qaEvidenceSummaryEntrySchema = z
|
||||
.object({
|
||||
test: qaEvidenceTestSchema,
|
||||
coverage: z.array(qaEvidenceCoverageSchema),
|
||||
posture: qaEvidencePostureSchema.optional(),
|
||||
refs: z.array(qaEvidenceRefSchema).optional(),
|
||||
runtimeParityTier: nonEmptyStringSchema.optional(),
|
||||
execution: qaEvidenceExecutionSchema.optional(),
|
||||
result: qaEvidenceResultSchema,
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceSummaryEntrySchema = z.strictObject({
|
||||
test: qaEvidenceTestSchema,
|
||||
coverage: z.array(qaEvidenceCoverageSchema),
|
||||
posture: qaEvidencePostureSchema.optional(),
|
||||
refs: z.array(qaEvidenceRefSchema).optional(),
|
||||
runtimeParityTier: nonEmptyStringSchema.optional(),
|
||||
execution: qaEvidenceExecutionSchema.optional(),
|
||||
result: qaEvidenceResultSchema,
|
||||
});
|
||||
|
||||
const qaEvidenceSummarySchema = z
|
||||
.object({
|
||||
kind: z.literal(QA_EVIDENCE_SUMMARY_KIND),
|
||||
schemaVersion: z.literal(QA_EVIDENCE_SUMMARY_SCHEMA_VERSION),
|
||||
generatedAt: nonEmptyStringSchema,
|
||||
evidenceMode: qaScorecardEvidenceModeSchema,
|
||||
entries: z.array(qaEvidenceSummaryEntrySchema),
|
||||
profile: qaEvidenceProfileIdSchema.optional(),
|
||||
scorecard: qaEvidenceScorecardSchema.optional(),
|
||||
})
|
||||
.strict();
|
||||
const qaEvidenceSummarySchema = z.strictObject({
|
||||
kind: z.literal(QA_EVIDENCE_SUMMARY_KIND),
|
||||
schemaVersion: z.literal(QA_EVIDENCE_SUMMARY_SCHEMA_VERSION),
|
||||
generatedAt: nonEmptyStringSchema,
|
||||
evidenceMode: qaScorecardEvidenceModeSchema,
|
||||
entries: z.array(qaEvidenceSummaryEntrySchema),
|
||||
profile: qaEvidenceProfileIdSchema.optional(),
|
||||
scorecard: qaEvidenceScorecardSchema.optional(),
|
||||
});
|
||||
|
||||
type QaEvidenceProfile = z.infer<typeof qaEvidenceProfileIdSchema>;
|
||||
export type QaEvidenceStatus = z.infer<typeof qaEvidenceStatusSchema>;
|
||||
@@ -800,4 +759,3 @@ export function buildLiveTransportEvidenceSummary(
|
||||
profile,
|
||||
});
|
||||
}
|
||||
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
|
||||
|
||||
@@ -59,11 +59,10 @@ function maturityScoreLabelForScore(score: number) {
|
||||
}
|
||||
|
||||
const qaMaturityScoreObjectSchema = z
|
||||
.object({
|
||||
.strictObject({
|
||||
score: z.number().int().min(0).max(100),
|
||||
label: z.enum(QA_MATURITY_SCORE_LABELS),
|
||||
})
|
||||
.strict()
|
||||
.superRefine((value, ctx) => {
|
||||
const expectedLabel = maturityScoreLabelForScore(value.score);
|
||||
if (value.label !== expectedLabel) {
|
||||
@@ -91,89 +90,69 @@ const qaMaturityLegacyCoverageShape = {
|
||||
coverage: qaMaturityScoreObjectSchema.optional(),
|
||||
} satisfies z.ZodRawShape;
|
||||
|
||||
const qaMaturityScoreBundleSchema = z
|
||||
.object({
|
||||
...qaMaturityLegacyCoverageShape,
|
||||
...qaMaturityScoreBundleShape,
|
||||
})
|
||||
.strict();
|
||||
const qaMaturityScoreBundleSchema = z.strictObject({
|
||||
...qaMaturityLegacyCoverageShape,
|
||||
...qaMaturityScoreBundleShape,
|
||||
});
|
||||
|
||||
const qaMaturityScoreLastRunSchema = z
|
||||
.object({
|
||||
status: z.string().trim().min(1).optional(),
|
||||
completed_at: z.string().trim().min(1).optional(),
|
||||
by: z.string().trim().min(1).optional(),
|
||||
source_ref: z.string().trim().min(1).nullable().optional(),
|
||||
process_version: z.number().int().positive().optional(),
|
||||
})
|
||||
.strict();
|
||||
const qaMaturityScoreLastRunSchema = z.strictObject({
|
||||
status: z.string().trim().min(1).optional(),
|
||||
completed_at: z.string().trim().min(1).optional(),
|
||||
by: z.string().trim().min(1).optional(),
|
||||
source_ref: z.string().trim().min(1).nullable().optional(),
|
||||
process_version: z.number().int().positive().optional(),
|
||||
});
|
||||
|
||||
const qaMaturityScoreCategoryLtsSchema = z
|
||||
.object({
|
||||
supported: z.boolean(),
|
||||
reason: z.string().trim().min(1).optional(),
|
||||
human_override: z.boolean(),
|
||||
})
|
||||
.strict();
|
||||
const qaMaturityScoreCategoryLtsSchema = z.strictObject({
|
||||
supported: z.boolean(),
|
||||
reason: z.string().trim().min(1).optional(),
|
||||
human_override: z.boolean(),
|
||||
});
|
||||
|
||||
const qaMaturityScoreSurfaceLtsSchema = z
|
||||
.object({
|
||||
supported_categories: z.number().int().nonnegative(),
|
||||
total_categories: z.number().int().nonnegative(),
|
||||
status: z.string().trim().min(1),
|
||||
})
|
||||
.strict();
|
||||
const qaMaturityScoreSurfaceLtsSchema = z.strictObject({
|
||||
supported_categories: z.number().int().nonnegative(),
|
||||
total_categories: z.number().int().nonnegative(),
|
||||
status: z.string().trim().min(1),
|
||||
});
|
||||
|
||||
const qaMaturityScoreCategorySchema = z
|
||||
.object({
|
||||
name: z.string().trim().min(1),
|
||||
...qaMaturityLegacyCoverageShape,
|
||||
...qaMaturityScoreBundleShape,
|
||||
lts: qaMaturityScoreCategoryLtsSchema,
|
||||
})
|
||||
.strict();
|
||||
const qaMaturityScoreCategorySchema = z.strictObject({
|
||||
name: z.string().trim().min(1),
|
||||
...qaMaturityLegacyCoverageShape,
|
||||
...qaMaturityScoreBundleShape,
|
||||
lts: qaMaturityScoreCategoryLtsSchema,
|
||||
});
|
||||
|
||||
const qaMaturityScoreSurfaceSchema = z
|
||||
.object({
|
||||
id: qaScorecardIdSchema,
|
||||
name: z.string().trim().min(1),
|
||||
family: z.string().trim().min(1).optional(),
|
||||
level: z.union([
|
||||
z.string().trim().min(1),
|
||||
z
|
||||
.object({
|
||||
id: z.string().trim().min(1).optional(),
|
||||
code: z.string().trim().min(1).optional(),
|
||||
label: z.string().trim().min(1).optional(),
|
||||
})
|
||||
.strict(),
|
||||
]),
|
||||
scores: qaMaturityScoreBundleSchema,
|
||||
categories: z.array(qaMaturityScoreCategorySchema),
|
||||
lts: qaMaturityScoreSurfaceLtsSchema,
|
||||
last_score_run: qaMaturityScoreLastRunSchema.optional(),
|
||||
})
|
||||
.strict();
|
||||
const qaMaturityScoreSurfaceSchema = z.strictObject({
|
||||
id: qaScorecardIdSchema,
|
||||
name: z.string().trim().min(1),
|
||||
family: z.string().trim().min(1).optional(),
|
||||
level: z.union([
|
||||
z.string().trim().min(1),
|
||||
z.strictObject({
|
||||
id: z.string().trim().min(1).optional(),
|
||||
code: z.string().trim().min(1).optional(),
|
||||
label: z.string().trim().min(1).optional(),
|
||||
}),
|
||||
]),
|
||||
scores: qaMaturityScoreBundleSchema,
|
||||
categories: z.array(qaMaturityScoreCategorySchema),
|
||||
lts: qaMaturityScoreSurfaceLtsSchema,
|
||||
last_score_run: qaMaturityScoreLastRunSchema.optional(),
|
||||
});
|
||||
|
||||
const qaMaturityScoresSchema = z
|
||||
.object({
|
||||
version: z.literal(1),
|
||||
process_version: z.number().int().positive(),
|
||||
counts: z
|
||||
.object({
|
||||
active_surfaces: z.number().int().nonnegative(),
|
||||
category_scores: z.number().int().nonnegative(),
|
||||
})
|
||||
.strict(),
|
||||
rollups: z
|
||||
.object({
|
||||
surface_average: qaMaturityScoreBundleSchema,
|
||||
category_average: qaMaturityScoreBundleSchema,
|
||||
})
|
||||
.strict(),
|
||||
surfaces: z.array(qaMaturityScoreSurfaceSchema),
|
||||
})
|
||||
.strict();
|
||||
const qaMaturityScoresSchema = z.strictObject({
|
||||
version: z.literal(1),
|
||||
process_version: z.number().int().positive(),
|
||||
counts: z.strictObject({
|
||||
active_surfaces: z.number().int().nonnegative(),
|
||||
category_scores: z.number().int().nonnegative(),
|
||||
}),
|
||||
rollups: z.strictObject({
|
||||
surface_average: qaMaturityScoreBundleSchema,
|
||||
category_average: qaMaturityScoreBundleSchema,
|
||||
}),
|
||||
surfaces: z.array(qaMaturityScoreSurfaceSchema),
|
||||
});
|
||||
|
||||
const qaMaturityFeatureSchema = z.object({
|
||||
name: z.string().trim().min(1),
|
||||
@@ -219,11 +198,10 @@ const qaMaturityTaxonomySchema = z
|
||||
title: z.string().trim().min(1),
|
||||
summary: z.string().trim().min(1).optional(),
|
||||
snapshot: z
|
||||
.object({
|
||||
.strictObject({
|
||||
date: z.string().trim().min(1).optional(),
|
||||
source_ref: z.string().trim().min(1).optional(),
|
||||
})
|
||||
.strict()
|
||||
.optional(),
|
||||
profiles: z.array(qaScorecardProfileSchema).default([]),
|
||||
levels: z.array(qaMaturityLevelSchema).default([]),
|
||||
|
||||
Reference in New Issue
Block a user