From b09de85c6f832f1912df98cd445e1a49dfda7880 Mon Sep 17 00:00:00 2001 From: mptyl Date: Sat, 27 Jun 2026 20:46:08 +0200 Subject: [PATCH] feat(backend): scaffold Fastify+TS + /health Co-Authored-By: Claude Sonnet 4.6 --- backend/package.json | 13 +++++++++++++ backend/src/app.ts | 7 +++++++ backend/src/config.ts | 17 +++++++++++++++++ backend/src/server.ts | 6 ++++++ backend/test/health.test.ts | 10 ++++++++++ backend/tsconfig.json | 3 +++ backend/vitest.config.ts | 2 ++ 7 files changed, 58 insertions(+) create mode 100644 backend/package.json create mode 100644 backend/src/app.ts create mode 100644 backend/src/config.ts create mode 100644 backend/src/server.ts create mode 100644 backend/test/health.test.ts create mode 100644 backend/tsconfig.json create mode 100644 backend/vitest.config.ts diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 00000000..92b32ae4 --- /dev/null +++ b/backend/package.json @@ -0,0 +1,13 @@ +{ + "name": "thothii-backend", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx watch src/server.ts", + "build": "tsc -p tsconfig.json", + "test": "vitest run", + "start": "node dist/server.js" + }, + "dependencies": { "fastify": "^5.0.0" }, + "devDependencies": { "typescript": "^5.6.0", "tsx": "^4.19.0", "vitest": "^2.1.0", "@types/node": "^22.0.0" } +} diff --git a/backend/src/app.ts b/backend/src/app.ts new file mode 100644 index 00000000..5bbdcdcb --- /dev/null +++ b/backend/src/app.ts @@ -0,0 +1,7 @@ +import Fastify, { type FastifyInstance } from "fastify"; +import type { AppConfig } from "./config.js"; +export function buildApp(_config: AppConfig): FastifyInstance { + const app = Fastify({ logger: false }); + app.get("/health", async () => ({ status: "ok" })); + return app; +} diff --git a/backend/src/config.ts b/backend/src/config.ts new file mode 100644 index 00000000..a2be6c4e --- /dev/null +++ b/backend/src/config.ts @@ -0,0 +1,17 @@ +export interface AppConfig { + port: number; harnessDir: string; thtBin: string; piBin: string; + authMode: "none" | "mock" | "oidc"; + defaults: { provider?: string; model?: string; thinking?: string }; + maxPiProcesses: number; +} +export function loadConfig(env: Record): AppConfig { + return { + port: Number(env.PORT ?? 8787), + harnessDir: env.THT_HARNESS_DIR ?? "../harness", + thtBin: env.THT_BIN ?? "tht", + piBin: env.PI_BIN ?? "pi", + authMode: (env.AUTH_MODE as AppConfig["authMode"]) ?? "none", + defaults: { provider: env.PI_PROVIDER, model: env.PI_MODEL, thinking: env.PI_THINKING }, + maxPiProcesses: Number(env.MAX_PI_PROCESSES ?? 4), + }; +} diff --git a/backend/src/server.ts b/backend/src/server.ts new file mode 100644 index 00000000..ffc62349 --- /dev/null +++ b/backend/src/server.ts @@ -0,0 +1,6 @@ +import { buildApp } from "./app.js"; +import { loadConfig } from "./config.js"; +const config = loadConfig(process.env); +const app = buildApp(config); +app.listen({ port: config.port, host: "127.0.0.1" }) + .then((addr) => console.log(`backend listening on ${addr}`)); diff --git a/backend/test/health.test.ts b/backend/test/health.test.ts new file mode 100644 index 00000000..d94c24c4 --- /dev/null +++ b/backend/test/health.test.ts @@ -0,0 +1,10 @@ +import { test, expect } from "vitest"; +import { buildApp } from "../src/app.js"; +import { loadConfig } from "../src/config.js"; + +test("GET /health ritorna ok", async () => { + const app = buildApp(loadConfig({ THT_HARNESS_DIR: "/tmp/h" })); + const res = await app.inject({ method: "GET", url: "/health" }); + expect(res.statusCode).toBe(200); + expect(res.json()).toEqual({ status: "ok" }); +}); diff --git a/backend/tsconfig.json b/backend/tsconfig.json new file mode 100644 index 00000000..8761a0fa --- /dev/null +++ b/backend/tsconfig.json @@ -0,0 +1,3 @@ +{ "compilerOptions": { "target": "ES2022", "module": "ES2022", "moduleResolution": "Bundler", + "strict": true, "outDir": "dist", "rootDir": "src", "esModuleInterop": true, "skipLibCheck": true }, + "include": ["src"] } diff --git a/backend/vitest.config.ts b/backend/vitest.config.ts new file mode 100644 index 00000000..84aa1e74 --- /dev/null +++ b/backend/vitest.config.ts @@ -0,0 +1,2 @@ +import { defineConfig } from "vitest/config"; +export default defineConfig({ test: { environment: "node", include: ["test/**/*.test.ts"] } });