Files
tech-log-frontend/tests/helpers/external-contract-fixture.ts
T
DongHyeonkaandClaude Opus 5 4bff9ca151 chore: sync the frontend template from 4dc033c to 8157ad4
The product was materialized from the template at `4dc033c` and has stayed
on it through 43 template commits, so it was missing all three rounds of
adapter remediation — including files it never had, such as the shared
`abortable-operation` primitive and the `exact-snapshot` decoder that
later fixes are written against. Taking only the newest round was not
possible for that reason: the delta is coherent only as a whole.

The product had not touched `src/adapters` at all since materialization,
so the 140-file delta applied with a three-way merge and no conflicts.
`package.json` was the single overlap and merged cleanly: the product owns
`name`, the template contributed `check:adapter-inventory`,
`check:remediation-ledger` and the image-resolve-signal type fixture.
All 24 product-owned files — README, index.html, CI workflow, i18n
catalog, home page, generated schemas, evidence scripts, component and
visual snapshots — are byte-identical to `main`.

`template.lock.json` now pins the synced revision and tree.

Verified in this repository, not inherited from the template: six type
projects, lint, nine gates (adapter inventory, remediation ledger,
registries, diagnostics, realtime boundaries, architecture, browser
file/storage boundaries, optional recipes, documentation), the production
build, and 2,054 of 2,073 tests. The 19 failures are all in
`tests/unit/ci-artifact-contract.test.ts` and are the same pre-existing
sandbox RLIMIT, EMFILE, umask and `/tmp` permission behaviour the template
records; four suites that failed once under parallel load pass in
isolation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 12:04:58 +09:00

221 lines
6.2 KiB
TypeScript

import { z } from "zod";
import type {
CommandEffectDescriptor,
InstalledContractContribution,
InstalledHttpContract,
RuntimeValidator,
} from "../../src/contracts/external-contract-runtime.ts";
function zodValidator<T>(
schemaId: string,
schema: z.ZodType<T>,
): RuntimeValidator<T> {
return Object.freeze({
schemaId,
safeParse(value: unknown) {
const result = schema.safeParse(value);
if (result.success) {
return Object.freeze({ success: true as const, data: result.data });
}
return Object.freeze({
success: false as const,
issues: Object.freeze(
result.error.issues.map((issue) =>
Object.freeze({
path: Object.freeze(
issue.path.map((segment) =>
typeof segment === "number" ? segment : String(segment),
),
),
code: String(issue.code),
}),
),
),
});
},
});
}
const entitySchema = z
.object({
id: z.string().min(1),
name: z.string().min(1),
})
.strip();
const problemSchema = z
.object({
type: z.string().min(1),
title: z.string().min(1),
status: z.int().min(100).max(599),
})
.strip();
type TestProblem = z.output<typeof problemSchema>;
const problemValidator = zodValidator("TestProblem", problemSchema);
const readPolicy = Object.freeze({
policyId: "TEST_READ_V1",
requestByteLimit: 0,
responseByteLimit: 32_768,
totalDeadlineMs: 10_000,
retryBudget: 2 as const,
authProfileId: "ANONYMOUS",
diagnosticsOperation: "test.read",
});
export const TEST_LIST_HTTP_CONTRACT: InstalledHttpContract<
Readonly<{ limit: number }>,
readonly z.output<typeof entitySchema>[],
TestProblem
> = Object.freeze({
contract: Object.freeze({
operationId: "TEST_LIST_ENTITIES",
method: "GET" as const,
pathTemplate: "/api/test-entities",
inputValidator: zodValidator(
"TestEntityListQuery",
z
.object({
limit: z.coerce.number().int().min(1).max(100).default(20),
})
.strict(),
),
outputValidator: zodValidator(
"TestEntityListPayload",
z.array(entitySchema).max(100),
),
problemValidator,
acceptedStatuses: Object.freeze([200]),
emptyBodyStatuses: Object.freeze([]),
retrySemantics: "SAFE" as const,
requestBody: "NONE" as const,
responseBody: "REQUIRED_JSON" as const,
commandRecovery: null,
commandEffect: null,
projectRequest(input: Readonly<{ limit: number }>) {
return Object.freeze({
pathValues: Object.freeze({}),
queryEntries: Object.freeze([
Object.freeze(["limit", String(input.limit)] as const),
]),
body: null,
});
},
}),
frontend: readPolicy,
});
export const TEST_DETAIL_HTTP_CONTRACT: InstalledHttpContract<
Readonly<{ entityId: string }>,
z.output<typeof entitySchema>,
TestProblem
> = Object.freeze({
contract: Object.freeze({
operationId: "TEST_GET_ENTITY",
method: "GET" as const,
pathTemplate: "/api/test-entities/{entityId}",
inputValidator: zodValidator(
"TestEntityParams",
z.object({ entityId: z.string().min(1) }).strict(),
),
outputValidator: zodValidator("TestEntityPayload", entitySchema),
problemValidator,
acceptedStatuses: Object.freeze([200]),
emptyBodyStatuses: Object.freeze([]),
retrySemantics: "SAFE" as const,
requestBody: "NONE" as const,
responseBody: "REQUIRED_JSON" as const,
commandRecovery: null,
commandEffect: null,
projectRequest(input: Readonly<{ entityId: string }>) {
return Object.freeze({
pathValues: Object.freeze({ entityId: input.entityId }),
queryEntries: Object.freeze([]),
body: null,
});
},
}),
frontend: Object.freeze({
...readPolicy,
policyId: "TEST_DETAIL_V1",
diagnosticsOperation: "test.detail",
}),
});
const commandEffect: CommandEffectDescriptor<TestProblem> = Object.freeze({
successEffect: "APPLIED_CONFIRMED" as const,
classifyProblem({
status,
}: Readonly<{ status: number; problem: TestProblem }>) {
return status === 400 ? "NOT_APPLIED" : "MAYBE_APPLIED";
},
});
export const TEST_CREATE_HTTP_CONTRACT: InstalledHttpContract<
Readonly<{ name: string }>,
z.output<typeof entitySchema>,
TestProblem
> = Object.freeze({
contract: Object.freeze({
operationId: "TEST_CREATE_ENTITY",
method: "POST" as const,
pathTemplate: "/api/test-entities",
inputValidator: zodValidator(
"TestCreateEntityCommand",
z.object({ name: z.string().trim().min(1) }).strict(),
),
outputValidator: zodValidator("TestEntityPayload", entitySchema),
problemValidator,
acceptedStatuses: Object.freeze([201]),
emptyBodyStatuses: Object.freeze([]),
retrySemantics: "KEYED" as const,
requestBody: "JSON" as const,
responseBody: "REQUIRED_JSON" as const,
commandRecovery: Object.freeze({
mode: "IDEMPOTENCY_REPLAY" as const,
operationIdentityField: "idempotencyKey",
}),
commandEffect,
projectRequest(input: Readonly<{ name: string }>) {
return Object.freeze({
pathValues: Object.freeze({}),
queryEntries: Object.freeze([]),
body: Object.freeze({ ...input }),
});
},
}),
frontend: Object.freeze({
policyId: "TEST_CREATE_V1",
requestByteLimit: 32_768,
responseByteLimit: 32_768,
totalDeadlineMs: 10_000,
retryBudget: 0 as const,
authProfileId: "ANONYMOUS",
diagnosticsOperation: "test.create",
}),
});
export const TEST_CONTRACT_CONTRIBUTION: InstalledContractContribution =
Object.freeze({
contributionId: "test-http-v1",
featureId: "test-feature",
source: Object.freeze({
kind: "EXTERNAL_PACKAGE" as const,
package: Object.freeze({
packageId: "@test/contracts",
version: "1.0.0",
digest: `sha256:${"a".repeat(64)}`,
runtimeProtocolVersion: 1 as const,
sourceRevision: "abcdef1",
}),
}),
http: Object.freeze([
TEST_LIST_HTTP_CONTRACT,
TEST_DETAIL_HTTP_CONTRACT,
TEST_CREATE_HTTP_CONTRACT,
]) as readonly InstalledHttpContract<unknown, unknown, unknown>[],
events: Object.freeze([]),
});