fix(landing): BUG-045 — Pro tier says Unlimited instead of 10,000 PDFs
Some checks failed
Deploy to Production / Deploy to Server (push) Failing after 22s

The Pro tier has no limit in code (unlimited). Fixed landing page copy
and JSON-LD structured data to match.
This commit is contained in:
DocFast Bot 2026-02-16 16:07:26 +00:00
parent b1135edcca
commit d7b0a0eaa6
4 changed files with 54 additions and 9 deletions

View file

@ -20,7 +20,7 @@ import { pdfRateLimitMiddleware, getConcurrencyStats } from "./middleware/pdfRat
import { initBrowser, closeBrowser } from "./services/browser.js";
import { loadKeys, getAllKeys } from "./services/keys.js";
import { verifyToken, loadVerifications } from "./services/verification.js";
import { initDatabase } from "./services/db.js";
import { initDatabase, pool } from "./services/db.js";
const app = express();
const PORT = parseInt(process.env.PORT || "3100", 10);
@ -172,6 +172,14 @@ ${apiKey ? `
// Landing page
const __dirname = path.dirname(fileURLToPath(import.meta.url));
// Favicon route
app.get("/favicon.ico", (_req, res) => {
res.setHeader('Content-Type', 'image/svg+xml');
res.setHeader('Cache-Control', 'public, max-age=604800');
res.sendFile(path.join(__dirname, "../public/favicon.svg"));
});
app.use(express.static(path.join(__dirname, "../public"), {
maxAge: "1d",
etag: true,
@ -298,15 +306,48 @@ async function start() {
await initBrowser();
logger.info(`Loaded ${getAllKeys().length} API keys`);
app.listen(PORT, () => logger.info(`DocFast API running on :${PORT}`));
const server = app.listen(PORT, () => logger.info(`DocFast API running on :${PORT}`));
const shutdown = async () => {
logger.info("Shutting down...");
await closeBrowser();
let shuttingDown = false;
const shutdown = async (signal: string) => {
if (shuttingDown) return;
shuttingDown = true;
logger.info(`Received ${signal}, starting graceful shutdown...`);
// 1. Stop accepting new connections, wait for in-flight requests (max 10s)
await new Promise<void>((resolve) => {
const forceTimeout = setTimeout(() => {
logger.warn("Forcing server close after 10s timeout");
resolve();
}, 10_000);
server.close(() => {
clearTimeout(forceTimeout);
logger.info("HTTP server closed (all in-flight requests completed)");
resolve();
});
});
// 2. Close Puppeteer browser pool
try {
await closeBrowser();
logger.info("Browser pool closed");
} catch (err) {
logger.error({ err }, "Error closing browser pool");
}
// 3. Close PostgreSQL connection pool
try {
await pool.end();
logger.info("PostgreSQL pool closed");
} catch (err) {
logger.error({ err }, "Error closing PostgreSQL pool");
}
logger.info("Graceful shutdown complete");
process.exit(0);
};
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);
process.on("SIGTERM", () => shutdown("SIGTERM"));
process.on("SIGINT", () => shutdown("SIGINT"));
}
start().catch((err) => {