2026-02-16 13:31:58 -06:00
|
|
|
import express, { Router } from "express";
|
|
|
|
|
import path from "node:path";
|
2026-02-18 11:45:43 -06:00
|
|
|
import fs from "node:fs";
|
2026-02-16 13:31:58 -06:00
|
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
|
import type { Db } from "@paperclip/db";
|
|
|
|
|
import { httpLogger, errorHandler } from "./middleware/index.js";
|
Add server routes for companies, approvals, costs, and dashboard
New routes: companies, approvals, costs, dashboard, authz. New
services: companies, approvals, costs, dashboard, heartbeat,
activity-log. Add auth middleware and structured error handling.
Expand existing agent and issue routes with richer CRUD operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:27 -06:00
|
|
|
import { actorMiddleware } from "./middleware/auth.js";
|
2026-02-16 13:31:58 -06:00
|
|
|
import { healthRoutes } from "./routes/health.js";
|
Add server routes for companies, approvals, costs, and dashboard
New routes: companies, approvals, costs, dashboard, authz. New
services: companies, approvals, costs, dashboard, heartbeat,
activity-log. Add auth middleware and structured error handling.
Expand existing agent and issue routes with richer CRUD operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:27 -06:00
|
|
|
import { companyRoutes } from "./routes/companies.js";
|
2026-02-16 13:31:58 -06:00
|
|
|
import { agentRoutes } from "./routes/agents.js";
|
|
|
|
|
import { projectRoutes } from "./routes/projects.js";
|
|
|
|
|
import { issueRoutes } from "./routes/issues.js";
|
|
|
|
|
import { goalRoutes } from "./routes/goals.js";
|
Add server routes for companies, approvals, costs, and dashboard
New routes: companies, approvals, costs, dashboard, authz. New
services: companies, approvals, costs, dashboard, heartbeat,
activity-log. Add auth middleware and structured error handling.
Expand existing agent and issue routes with richer CRUD operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:27 -06:00
|
|
|
import { approvalRoutes } from "./routes/approvals.js";
|
|
|
|
|
import { costRoutes } from "./routes/costs.js";
|
2026-02-16 13:31:58 -06:00
|
|
|
import { activityRoutes } from "./routes/activity.js";
|
Add server routes for companies, approvals, costs, and dashboard
New routes: companies, approvals, costs, dashboard, authz. New
services: companies, approvals, costs, dashboard, heartbeat,
activity-log. Add auth middleware and structured error handling.
Expand existing agent and issue routes with richer CRUD operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:27 -06:00
|
|
|
import { dashboardRoutes } from "./routes/dashboard.js";
|
2026-02-16 13:31:58 -06:00
|
|
|
|
2026-02-18 11:45:43 -06:00
|
|
|
type UiMode = "none" | "static" | "vite-dev";
|
|
|
|
|
|
|
|
|
|
export async function createApp(db: Db, opts: { uiMode: UiMode }) {
|
2026-02-16 13:31:58 -06:00
|
|
|
const app = express();
|
|
|
|
|
|
|
|
|
|
app.use(express.json());
|
|
|
|
|
app.use(httpLogger);
|
Add server routes for companies, approvals, costs, and dashboard
New routes: companies, approvals, costs, dashboard, authz. New
services: companies, approvals, costs, dashboard, heartbeat,
activity-log. Add auth middleware and structured error handling.
Expand existing agent and issue routes with richer CRUD operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:27 -06:00
|
|
|
app.use(actorMiddleware(db));
|
2026-02-16 13:31:58 -06:00
|
|
|
|
|
|
|
|
// Mount API routes
|
|
|
|
|
const api = Router();
|
|
|
|
|
api.use("/health", healthRoutes());
|
Add server routes for companies, approvals, costs, and dashboard
New routes: companies, approvals, costs, dashboard, authz. New
services: companies, approvals, costs, dashboard, heartbeat,
activity-log. Add auth middleware and structured error handling.
Expand existing agent and issue routes with richer CRUD operations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:07:27 -06:00
|
|
|
api.use("/companies", companyRoutes(db));
|
|
|
|
|
api.use(agentRoutes(db));
|
|
|
|
|
api.use(projectRoutes(db));
|
|
|
|
|
api.use(issueRoutes(db));
|
|
|
|
|
api.use(goalRoutes(db));
|
|
|
|
|
api.use(approvalRoutes(db));
|
|
|
|
|
api.use(costRoutes(db));
|
|
|
|
|
api.use(activityRoutes(db));
|
|
|
|
|
api.use(dashboardRoutes(db));
|
2026-02-16 13:31:58 -06:00
|
|
|
app.use("/api", api);
|
|
|
|
|
|
2026-02-18 11:45:43 -06:00
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
|
if (opts.uiMode === "static") {
|
|
|
|
|
// Serve built UI from ui/dist in production.
|
2026-02-16 13:31:58 -06:00
|
|
|
const uiDist = path.resolve(__dirname, "../../ui/dist");
|
|
|
|
|
app.use(express.static(uiDist));
|
2026-02-18 11:45:43 -06:00
|
|
|
app.get(/.*/, (_req, res) => {
|
2026-02-16 13:31:58 -06:00
|
|
|
res.sendFile(path.join(uiDist, "index.html"));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-18 11:45:43 -06:00
|
|
|
if (opts.uiMode === "vite-dev") {
|
|
|
|
|
const uiRoot = path.resolve(__dirname, "../../ui");
|
|
|
|
|
const { createServer: createViteServer } = await import("vite");
|
|
|
|
|
const vite = await createViteServer({
|
|
|
|
|
root: uiRoot,
|
|
|
|
|
appType: "spa",
|
|
|
|
|
server: {
|
|
|
|
|
middlewareMode: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
app.use(vite.middlewares);
|
|
|
|
|
app.get(/.*/, async (req, res, next) => {
|
|
|
|
|
try {
|
|
|
|
|
const templatePath = path.resolve(uiRoot, "index.html");
|
|
|
|
|
const template = fs.readFileSync(templatePath, "utf-8");
|
|
|
|
|
const html = await vite.transformIndexHtml(req.originalUrl, template);
|
|
|
|
|
res.status(200).set({ "Content-Type": "text/html" }).end(html);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
next(err);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-16 13:31:58 -06:00
|
|
|
app.use(errorHandler);
|
|
|
|
|
|
|
|
|
|
return app;
|
|
|
|
|
}
|