chore(dev): add pnpm dev hot-reload workflow for local development

Replace full docker compose rebuild during development with:
- pnpm dev / dev:backend (air hot-reload control-plane) / dev:frontend (vite HMR) / dev:deps
- compose.dev.yaml: postgres+docker-gateway only, host port mapping (5432/8081), container control-plane disabled via profile
- scripts/dev-backend.mjs: read .env, fill dev defaults (login admin/admin123, listen :8082, 32-byte dev master key with explicit warning on invalid .env value), ensure dep containers, run air
- vite: fixed port 5173, /api proxy to local control-plane (8082)
- README: document hot-reload dev workflow

Verified: pnpm dev end-to-end (login/API/frontend/proxy 200), Go+JSX edit hot-reload, compose config --quiet, go build ./..., web tests 65 passed, npm --prefix web run build.
This commit is contained in:
2026-09-02 14:38:44 +08:00
parent 2676df12c2
commit 208f6766af
8 changed files with 192 additions and 9 deletions
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env node
// dev: 同时跑 dev:backendair 热加载 control-plane)与 dev:frontendvite HMR)。
// Ctrl-C 结束两个子进程。
import { spawn } from "node:child_process";
import path from "node:path";
import { fileURLToPath } from "node:url";
const root = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
const pnpm = process.env.npm_execpath || "pnpm";
const procs = [
spawn(pnpm, ["run", "dev:backend"], { cwd: root, stdio: "inherit" }),
spawn(pnpm, ["run", "dev:frontend"], { cwd: root, stdio: "inherit" }),
];
for (const signal of ["SIGINT", "SIGTERM"]) {
process.on(signal, () => {
for (const p of procs) p.kill(signal);
});
}
let remaining = procs.length;
for (const p of procs) {
p.on("exit", (code) => {
if (--remaining === 0) process.exit(code ?? 0);
});
}