feat: add Swagger/OpenAPI documentation at /api/docs

Registers @fastify/swagger and @fastify/swagger-ui, adds /api/docs to
public auth paths, and wires up static serving + cleanup cron in
index.ts.
This commit is contained in:
Siddharth Kumar Sah
2026-03-22 03:09:33 +08:00
parent 8bda22033f
commit 4069f4db42
2 changed files with 29 additions and 1 deletions
+28
View File
@@ -1,10 +1,14 @@
import Fastify from "fastify";
import cors from "@fastify/cors";
import rateLimit from "@fastify/rate-limit";
import swagger from "@fastify/swagger";
import swaggerUi from "@fastify/swagger-ui";
import { env } from "./config.js";
import { APP_VERSION } from "@stirling-image/shared";
import { runMigrations } from "./db/migrate.js";
import { ensureDefaultAdmin, authRoutes, authMiddleware } from "./plugins/auth.js";
import { registerStatic } from "./plugins/static.js";
import { startCleanupCron } from "./lib/cleanup.js";
// Run before anything else
runMigrations();
@@ -25,6 +29,22 @@ await app.register(rateLimit, {
timeWindow: "1 minute",
});
// Swagger / OpenAPI documentation
await app.register(swagger, {
openapi: {
info: {
title: "Stirling Image API",
description: "API for Stirling Image — self-hosted image processing suite",
version: APP_VERSION,
},
servers: [{ url: `http://localhost:${env.PORT}` }],
},
});
await app.register(swaggerUi, {
routePrefix: "/api/docs",
});
// Auth middleware (must be registered before routes it protects)
await authMiddleware(app);
@@ -41,6 +61,14 @@ app.get("/api/v1/health", async () => ({
ai: {},
}));
// Serve SPA in production
if (process.env.NODE_ENV === "production") {
await registerStatic(app);
}
// Start workspace cleanup cron
startCleanupCron();
// Start
try {
await app.listen({ port: env.PORT, host: "0.0.0.0" });
+1 -1
View File
@@ -176,7 +176,7 @@ function extractToken(request: FastifyRequest): string | null {
// ── Auth middleware ────────────────────────────────────────────────
const PUBLIC_PATHS = ["/api/v1/health", "/api/auth/"];
const PUBLIC_PATHS = ["/api/v1/health", "/api/auth/", "/api/docs"];
function isPublicRoute(url: string): boolean {
return PUBLIC_PATHS.some((path) => url.startsWith(path));