feat(lanes): per-lane database, Redis, and .env isolation (A1+A2)
Gives each lane its own slot-derived runtime (ports, detached process lifecycle, profile-driven hooks) and its own database/Redis logical index/.env file, so two lanes running the same repo's stack at once no longer share state. Machine-level DB/Redis credentials live at ~/.ccam/secrets.env (mode 0600, never returned by any route); a hook's output is redacted of that password (raw and URL-encoded forms) before it reaches a log file or the lane_hook_output websocket broadcast. Wired into provision/up/reset/remove; reset accepts --keep-db to skip the drop/recreate/migrate/reseed block entirely.
This commit is contained in:
@@ -10,6 +10,8 @@ const fs = require("node:fs");
|
||||
const { db } = require("../db");
|
||||
const wt = require("./worktree");
|
||||
const lanesLib = require("./lanes");
|
||||
const { resolveProfile } = require("./lane-profile");
|
||||
const { dbName } = require("./lane-slots");
|
||||
|
||||
/**
|
||||
* Preflight for reset, remove, or purge. Returns an object describing what will happen:
|
||||
@@ -74,6 +76,14 @@ async function preflight(lane, action) {
|
||||
}
|
||||
}
|
||||
|
||||
// The database name this action would drop (reset unless --keep-db,
|
||||
// remove always) — echoed the same way `head`/`dirty` are, so the
|
||||
// confirmation dialog names the destructive fact rather than leaving it a
|
||||
// surprise. Null when the lane has no slot yet or the profile declares no
|
||||
// DB_PREFIX — nothing has been derived to drop.
|
||||
const profile = resolveProfile(lane);
|
||||
const database = profile && lane.slot ? dbName(profile, lane.slot) : null;
|
||||
|
||||
return {
|
||||
action,
|
||||
lane: lane.id,
|
||||
@@ -83,6 +93,7 @@ async function preflight(lane, action) {
|
||||
untracked,
|
||||
unpushed,
|
||||
head: head || null,
|
||||
database,
|
||||
blocked,
|
||||
warnings,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user