feat: complete TASK-WP0-02 contract baseline

This commit is contained in:
suyx
2026-07-27 17:49:24 +08:00
parent ae20eaf01f
commit dbe3e73b91
28 changed files with 2540 additions and 23 deletions
+126 -3
View File
@@ -1,17 +1,140 @@
import { randomUUID } from "node:crypto";
import {
BootstrapResponseSchema,
CorrelationIdSchema,
ErrorDetailsSchema,
ErrorEnvelopeSchema,
GenerationErrorCategorySchema,
ModelConfigSseEventSchema,
ModelRuntimeSseEventSchema,
SseEventSchema,
StableEngineeringErrorCodeSchema,
StateSseEventSchema,
isCorrelationId,
type BootstrapResponse,
} from "@dada/shared-contracts";
import swagger from "@fastify/swagger";
import Fastify from "fastify";
export function createApp() {
const app = Fastify({ logger: false });
import { EventHub } from "./event-hub.js";
void app.register(swagger, {
const defaultBootstrap: BootstrapResponse = {
app_version: "0.0.0",
dependencies: [],
model_summary: {
config_set_version: null,
configured_default_model_id: null,
recommended_model_id: null,
runtime_availability_version: null,
},
public_features: [],
};
export interface CreateAppOptions {
bootstrap?: () => BootstrapResponse | Promise<BootstrapResponse>;
eventHub?: EventHub;
}
function requestCorrelationId(headers: Record<string, string | string[] | undefined>) {
const header = headers["x-correlation-id"];
const candidate = Array.isArray(header) ? header[0] : header;
return isCorrelationId(candidate) ? candidate : randomUUID();
}
export async function createApp(options: CreateAppOptions = {}) {
const eventHub = options.eventHub ?? new EventHub();
const bootstrap = options.bootstrap ?? (() => defaultBootstrap);
const app = Fastify({
genReqId: (request) => requestCorrelationId(request.headers),
logger: false,
});
await app.register(swagger, {
openapi: {
info: {
title: "Dada P0-A",
version: "0.0.0",
},
openapi: "3.1.0",
},
refResolver: {
buildLocalReference: (schema, _baseUri, _fragment, index) =>
typeof schema.$id === "string" ? schema.$id : `schema-${index}`,
},
});
for (const schema of [
CorrelationIdSchema,
GenerationErrorCategorySchema,
StableEngineeringErrorCodeSchema,
ErrorDetailsSchema,
ErrorEnvelopeSchema,
BootstrapResponseSchema,
StateSseEventSchema,
ModelConfigSseEventSchema,
ModelRuntimeSseEventSchema,
SseEventSchema,
]) {
app.addSchema(schema);
}
app.addHook("onRequest", (request, reply, done) => {
reply.header("X-Correlation-Id", request.id);
done();
});
app.get(
"/api/v1/bootstrap",
{
schema: {
operationId: "getBootstrap",
response: {
200: BootstrapResponseSchema,
},
tags: ["Bootstrap"],
},
},
async () => bootstrap(),
);
app.get(
"/api/v1/events",
{
schema: {
operationId: "getEvents",
response: {
200: {
content: {
"text/event-stream": {
schema: SseEventSchema,
},
},
description: "Non-sensitive state change hints. REST remains authoritative.",
},
},
tags: ["State events"],
},
},
(request, reply) => {
reply.hijack();
reply.raw.setHeader("Cache-Control", "no-store");
reply.raw.setHeader("Connection", "keep-alive");
reply.raw.setHeader("Content-Type", "text/event-stream; charset=utf-8");
reply.raw.setHeader("X-Correlation-Id", request.id);
reply.raw.writeHead(200);
reply.raw.write(": connected\n\n");
const unsubscribe = eventHub.connect(
(event) => {
reply.raw.write(`id: ${event.event_id}\n`);
reply.raw.write(`data: ${JSON.stringify(event)}\n\n`);
},
() => reply.raw.end(),
);
request.raw.once("close", unsubscribe);
},
);
return app;
}