feat: complete TASK-WP0-02 contract baseline
This commit is contained in:
+126
-3
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user