feat: initial commit — site + admin panel + Postgres content pipeline

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
AyrisAI
2026-07-21 01:24:47 +03:00
co-authored by Claude Fable 5
commit 3420d32271
188 changed files with 25053 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
// server/publish.mjs — "Yayınla" pipeline: DB -> JSON files -> vite-ssg build -> dist swap
import fs from "node:fs";
import path from "node:path";
import { spawn } from "node:child_process";
import { fileURLToPath } from "node:url";
import { exportToFiles } from "./db.mjs";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(__dirname, "..");
export const DIST_DIR = path.join(ROOT, "dist");
const STAGING_DIR = path.join(ROOT, ".dist-staging");
const LOG_LIMIT = 60_000;
const job = {
running: false,
startedAt: null,
finishedAt: null,
ok: null,
log: "",
};
function append(text) {
job.log = (job.log + text).slice(-LOG_LIMIT);
}
function run(cmd, args, opts = {}) {
return new Promise((resolve, reject) => {
const child = spawn(cmd, args, {
cwd: ROOT,
env: { ...process.env, ...opts.env },
shell: false,
});
child.stdout.on("data", (d) => append(d.toString()));
child.stderr.on("data", (d) => append(d.toString()));
child.on("error", reject);
child.on("close", (code) => {
code === 0
? resolve()
: reject(new Error(`${cmd} exited with code ${code}`));
});
});
}
export function getPublishState() {
return { ...job };
}
// Kick off the publish pipeline in the background. Returns false if already running.
export function startPublish() {
if (job.running) return false;
job.running = true;
job.ok = null;
job.log = "";
job.startedAt = new Date().toISOString();
job.finishedAt = null;
(async () => {
try {
append("[1/3] DB → JSON dosyaları aktarılıyor...\n");
const written = await exportToFiles();
append(` ${written.length} dosya yazıldı\n`);
append("[2/3] Site build ediliyor (vite-ssg)...\n");
fs.rmSync(STAGING_DIR, { recursive: true, force: true });
await run("npx", ["vite-ssg", "build"], {
env: { BUILD_OUT_DIR: STAGING_DIR },
});
append("[3/3] dist güncelleniyor...\n");
fs.rmSync(DIST_DIR, { recursive: true, force: true });
fs.renameSync(STAGING_DIR, DIST_DIR);
append("Tamamlandı ✓\n");
job.ok = true;
} catch (e) {
append(`\nHATA: ${e.message}\n`);
job.ok = false;
} finally {
job.running = false;
job.finishedAt = new Date().toISOString();
}
})();
return true;
}