Files
16gagent/cases/bookshelf/backend/src/index.ts
T
2026-06-06 10:40:48 +08:00

68 lines
1.9 KiB
TypeScript

// NoteApp — Fastify Backend Server
import Fastify from "fastify";
import cors from "@fastify/cors";
import fjwt from "@fastify/jwt";
import { initDb, closeDb } from "./db/client.js";
import { authRoutes } from "./routes/auth.js";
import { usersRoutes } from "./routes/users.js";
import { notesRoutes } from "./routes/notes.js";
import { tagsRoutes } from "./routes/tags.js";
import { note_tagsRoutes } from "./routes/note_tags.js";
const JWT_SECRET = process.env.JWT_SECRET || "change-me-in-production-57f6354b";
export async function buildApp() {
const app = Fastify({
logger: {
level: process.env.LOG_LEVEL || "info",
transport: process.env.NODE_ENV !== "production"
? { target: "pino-pretty", options: { colorize: true } }
: undefined,
},
});
// Init database
await initDb();
// Plugins
await app.register(cors, {
origin: process.env.CORS_ORIGIN || "*",
methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
});
await app.register(fjwt, { secret: JWT_SECRET });
// Routes
await app.register(authRoutes, { prefix: "/api/auth" });
await app.register(usersRoutes, { prefix: "/api/users" });
await app.register(notesRoutes, { prefix: "/api/notes" });
await app.register(tagsRoutes, { prefix: "/api/tags" });
await app.register(note_tagsRoutes, { prefix: "/api/note_tags" });
// Health check
app.get("/api/health", async () => ({ status: "ok", timestamp: new Date().toISOString() }));
// Graceful shutdown
app.addHook("onClose", async () => {
closeDb();
});
return app;
}
// Start server if called directly
const port = parseInt(process.env.PORT || "3001", 10);
const host = process.env.HOST || "0.0.0.0";
async function main() {
const app = await buildApp();
try {
await app.listen({ port, host });
} catch (err) {
app.log.error(err);
process.exit(1);
}
}
main();