Add URL→PDF endpoint, usage tracking middleware, free tier limits
This commit is contained in:
parent
8e03b8ab3c
commit
6896b72e0c
5 changed files with 158 additions and 4 deletions
68
src/middleware/usage.ts
Normal file
68
src/middleware/usage.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import { Request, Response, NextFunction } from "express";
|
||||
|
||||
interface UsageRecord {
|
||||
count: number;
|
||||
monthKey: string;
|
||||
}
|
||||
|
||||
// In-memory usage tracking (replace with Redis/DB for production)
|
||||
const usage = new Map<string, UsageRecord>();
|
||||
|
||||
const FREE_TIER_LIMIT = 50; // 50 PDFs/month for free tier
|
||||
const PRO_KEYS = new Set(
|
||||
(process.env.PRO_KEYS || "").split(",").map((k) => k.trim()).filter(Boolean)
|
||||
);
|
||||
|
||||
function getMonthKey(): string {
|
||||
const d = new Date();
|
||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
export function usageMiddleware(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): void {
|
||||
const key = req.headers.authorization?.slice(7) || "unknown";
|
||||
const monthKey = getMonthKey();
|
||||
|
||||
// Pro keys have no limit
|
||||
if (PRO_KEYS.has(key)) {
|
||||
trackUsage(key, monthKey);
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// Free tier limit check
|
||||
const record = usage.get(key);
|
||||
if (record && record.monthKey === monthKey && record.count >= FREE_TIER_LIMIT) {
|
||||
res.status(429).json({
|
||||
error: "Free tier limit reached",
|
||||
limit: FREE_TIER_LIMIT,
|
||||
used: record.count,
|
||||
upgrade: "Upgrade to Pro for unlimited conversions: https://docfast.dev/pricing",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
trackUsage(key, monthKey);
|
||||
next();
|
||||
}
|
||||
|
||||
function trackUsage(key: string, monthKey: string): void {
|
||||
const record = usage.get(key);
|
||||
if (!record || record.monthKey !== monthKey) {
|
||||
usage.set(key, { count: 1, monthKey });
|
||||
} else {
|
||||
record.count++;
|
||||
}
|
||||
}
|
||||
|
||||
export function getUsageStats(): Record<string, { count: number; month: string }> {
|
||||
const stats: Record<string, { count: number; month: string }> = {};
|
||||
for (const [key, record] of usage) {
|
||||
const masked = key.slice(0, 8) + "...";
|
||||
stats[masked] = { count: record.count, month: record.monthKey };
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue