Files
TallyNote/server/index.ts
T
Qiufeng 9719429f4a
TallyNote release / linux-x64 (push) Failing after 2m41s
feat: add TallyNote local reimbursement ledger
2026-08-29 01:02:29 +08:00

55 lines
2.4 KiB
TypeScript

import { cleanupOrphanedFiles, cleanupStaging, processFileDeletions } from "./files.js";
import { loadConfig, prepareDataDirectories, acquireInstanceLock } from "./config.js";
import { openDatabase } from "./db/index.js";
import { buildApp } from "./app.js";
import { cleanupOrphanedExports, expireExports, resumeExports } from "./exporter.js";
const config = loadConfig();
prepareDataDirectories(config);
const releaseLock = acquireInstanceLock(config);
const database = openDatabase(config);
async function start() {
await cleanupStaging(config);
await cleanupOrphanedFiles(database.sqlite, config);
database.sqlite.prepare("DELETE FROM login_attempts WHERE window_start < ? AND (blocked_until IS NULL OR blocked_until < ?)").run(Date.now() - 24 * 60 * 60 * 1000, Date.now());
database.sqlite.prepare("DELETE FROM sessions WHERE idle_expires_at <= ? OR absolute_expires_at <= ?").run(Date.now(), Date.now());
await processFileDeletions(database.sqlite, config);
await expireExports(database.sqlite, config);
await cleanupOrphanedExports(database.sqlite, config);
await resumeExports(database.sqlite, config);
const app = await buildApp(database, config);
const janitor = setInterval(() => {
void cleanupStaging(config);
void cleanupOrphanedFiles(database.sqlite, config);
database.sqlite.prepare("DELETE FROM login_attempts WHERE window_start < ? AND (blocked_until IS NULL OR blocked_until < ?)").run(Date.now() - 24 * 60 * 60 * 1000, Date.now());
database.sqlite.prepare("DELETE FROM sessions WHERE idle_expires_at <= ? OR absolute_expires_at <= ?").run(Date.now(), Date.now());
void processFileDeletions(database.sqlite, config);
void expireExports(database.sqlite, config);
void cleanupOrphanedExports(database.sqlite, config);
}, 60_000);
const shutdown = async () => {
clearInterval(janitor);
await app.close().catch(() => undefined);
database.sqlite.close();
releaseLock();
};
process.once("SIGINT", () => void shutdown().finally(() => process.exit(0)));
process.once("SIGTERM", () => void shutdown().finally(() => process.exit(0)));
try {
await app.listen({ host: config.host, port: config.port });
} catch (error) {
clearInterval(janitor);
await app.close().catch(() => undefined);
throw error;
}
app.log.info(`TallyNote running at ${config.publicOrigin}`);
}
start().catch((error) => {
console.error(error);
database.sqlite.close();
releaseLock();
process.exitCode = 1;
});