Initial MVP: DocFast PDF API

- HTML/Markdown to PDF conversion via Puppeteer
- Invoice and receipt templates
- API key auth + rate limiting
- Dockerfile for deployment
This commit is contained in:
DocFast Bot 2026-02-14 12:38:06 +00:00
commit feee0317ae
14 changed files with 4529 additions and 0 deletions

66
src/index.ts Normal file
View file

@ -0,0 +1,66 @@
import express from "express";
import helmet from "helmet";
import rateLimit from "express-rate-limit";
import { convertRouter } from "./routes/convert.js";
import { templatesRouter } from "./routes/templates.js";
import { healthRouter } from "./routes/health.js";
import { authMiddleware } from "./middleware/auth.js";
import { initBrowser, closeBrowser } from "./services/browser.js";
const app = express();
const PORT = parseInt(process.env.PORT || "3100", 10);
app.use(helmet());
app.use(express.json({ limit: "2mb" }));
app.use(express.text({ limit: "2mb", type: "text/*" }));
// Rate limiting: 100 req/min for free tier
const limiter = rateLimit({
windowMs: 60_000,
max: 100,
standardHeaders: true,
legacyHeaders: false,
});
app.use(limiter);
// Public
app.use("/health", healthRouter);
// Authenticated
app.use("/v1/convert", authMiddleware, convertRouter);
app.use("/v1/templates", authMiddleware, templatesRouter);
// Root
app.get("/", (_req, res) => {
res.json({
name: "DocFast API",
version: "0.1.0",
docs: "/health",
endpoints: [
"POST /v1/convert/html",
"POST /v1/convert/markdown",
"POST /v1/templates/:id/render",
"GET /v1/templates",
],
});
});
async function start() {
await initBrowser();
app.listen(PORT, () => console.log(`DocFast API running on :${PORT}`));
const shutdown = async () => {
console.log("Shutting down...");
await closeBrowser();
process.exit(0);
};
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);
}
start().catch((err) => {
console.error("Failed to start:", err);
process.exit(1);
});
export { app };