Migrate from JSON to PostgreSQL, update SLA to 99.5%

- Replace JSON file storage with PostgreSQL (pg package)
- Add db.ts service for connection pool and schema init
- Rewrite keys.ts, verification.ts, usage.ts for async PostgreSQL
- Update all routes for async function signatures
- Add migration script (scripts/migrate-to-postgres.mjs)
- Update docker-compose.yml with DATABASE_* env vars
- Change SLA from 99.9% to 99.5% in landing page
This commit is contained in:
DocFast Bot 2026-02-15 10:18:25 +00:00
parent bb1881af61
commit e9d16bf2a3
13 changed files with 395 additions and 198 deletions

View file

@ -15,7 +15,6 @@ const changeLimiter = rateLimit({
legacyHeaders: false,
});
// Step 1: Request email change — sends verification code to NEW email
router.post("/", changeLimiter, async (req: Request, res: Response) => {
const apiKey = req.headers.authorization?.replace(/^Bearer\s+/i, "") || req.body?.apiKey;
const newEmail = req.body?.newEmail;
@ -44,8 +43,7 @@ router.post("/", changeLimiter, async (req: Request, res: Response) => {
return;
}
const pending = createPendingVerification(cleanEmail);
(pending as any)._changeContext = { apiKey, newEmail: cleanEmail, oldEmail: userKey.email };
const pending = await createPendingVerification(cleanEmail);
sendVerificationEmail(cleanEmail, (pending as any).code).catch((err: Error) => {
console.error(`Failed to send email change verification to ${cleanEmail}:`, err);
@ -54,7 +52,6 @@ router.post("/", changeLimiter, async (req: Request, res: Response) => {
res.json({ status: "verification_sent", message: "Verification code sent to your new email address." });
});
// Step 2: Verify code — updates email
router.post("/verify", changeLimiter, async (req: Request, res: Response) => {
const apiKey = req.headers.authorization?.replace(/^Bearer\s+/i, "") || req.body?.apiKey;
const { newEmail, code } = req.body || {};
@ -74,11 +71,11 @@ router.post("/verify", changeLimiter, async (req: Request, res: Response) => {
return;
}
const result = verifyCode(cleanEmail, cleanCode);
const result = await verifyCode(cleanEmail, cleanCode);
switch (result.status) {
case "ok": {
const updated = updateKeyEmail(apiKey, cleanEmail);
const updated = await updateKeyEmail(apiKey, cleanEmail);
if (updated) {
res.json({ status: "updated", message: "Email address updated successfully.", newEmail: cleanEmail });
} else {