v0.2.1: request logging, 404 handler, permissions-policy, SEO improvements, typo fix
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 20s

This commit is contained in:
DocFast CEO 2026-02-16 08:32:57 +00:00
parent 210e71e3d8
commit 86f8da62ec
5 changed files with 45 additions and 8 deletions

View file

@ -27,11 +27,24 @@ const PORT = parseInt(process.env.PORT || "3100", 10);
app.use(helmet({ crossOriginResourcePolicy: { policy: "cross-origin" } }));
// Request ID middleware
// Request ID + request logging middleware
app.use((req, res, next) => {
const requestId = (req.headers["x-request-id"] as string) || randomUUID();
(req as any).requestId = requestId;
res.setHeader("X-Request-Id", requestId);
const start = Date.now();
res.on("finish", () => {
const ms = Date.now() - start;
if (req.path !== "/health") {
logger.info({ method: req.method, path: req.path, status: res.statusCode, ms, requestId }, "request");
}
});
next();
});
// Permissions-Policy header
app.use((_req, res, next) => {
res.setHeader("Permissions-Policy", "camera=(), microphone=(), geolocation=(), payment=(self)");
next();
});
@ -150,7 +163,7 @@ p{color:#7a8194;margin-bottom:24px;line-height:1.6}
<h1>${title}</h1>
<p>${message}</p>
${apiKey ? `
<div class="warning"> Save your API key securely. You can recover it via email if needed..</div>
<div class="warning"> Save your API key securely. You can recover it via email if needed.</div>
<div class="key-box" onclick="navigator.clipboard.writeText('${apiKey}');this.style.borderColor='#5eead4';setTimeout(()=>this.style.borderColor='#34d399',1500)">${apiKey}</div>
<div class="links">100 free PDFs/month · <a href="/docs">Read the docs </a></div>
` : `<div class="links"><a href="/"> Back to DocFast</a></div>`}
@ -231,6 +244,26 @@ app.use((req, res) => {
}
});
// 404 handler — must be after all routes
app.use((req, res) => {
if (req.path.startsWith("/v1/")) {
res.status(404).json({ error: "Not found" });
} else {
const accepts = req.headers.accept || "";
if (accepts.includes("text/html")) {
res.status(404).send(`<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>404 DocFast</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>⚡</text></svg>">
<style>*{margin:0;padding:0;box-sizing:border-box}body{font-family:'Inter',-apple-system,sans-serif;background:#0b0d11;color:#e4e7ed;min-height:100vh;display:flex;align-items:center;justify-content:center}
.c{text-align:center}.c h1{font-size:4rem;font-weight:800;color:#34d399;margin-bottom:12px}.c p{color:#7a8194;margin-bottom:24px}.c a{color:#34d399;text-decoration:none}.c a:hover{color:#5eead4}</style>
</head><body><div class="c"><h1>404</h1><p>Page not found.</p><p><a href="/"> Back to DocFast</a> · <a href="/docs">API Docs</a></p></div></body></html>`);
} else {
res.status(404).json({ error: "Not found" });
}
}
});
async function start() {
// Initialize PostgreSQL
await initDatabase();