feat: customers management UI with paginated table and full delete
All checks were successful
Build & Release / build (push) Successful in 12s
All checks were successful
Build & Release / build (push) Successful in 12s
- Fix SSH key missing trailing newline (error in libcrypto) - Pass env with SSH command through all git operations - Add customers table (modules, start/expiration dates, created/updated timestamps) - Idempotent ALTER TABLE for existing deployments - GET /customers with pagination, search, and sort - POST /customers persists slug with modules and dates to DB - DELETE /customers/:slug removes ArgoCD chart, DO DB, pgbouncer pool, and manager record - Redesigned frontend: dark slate theme, customers table page with search/sort/pagination, delete confirm dialog, module checkboxes, slate buttons
This commit is contained in:
@@ -4,11 +4,12 @@ import { tmpdir } from "os";
|
||||
import { join } from "path";
|
||||
import { config } from "../lib/config";
|
||||
|
||||
function withRepo<T>(fn: (dir: string) => T): T {
|
||||
function withRepo<T>(fn: (dir: string, env: NodeJS.ProcessEnv) => T): T {
|
||||
const keyPath = join(tmpdir(), `manager-ssh-key-${Date.now()}`);
|
||||
const dir = join(tmpdir(), `lunarfront-charts-${Date.now()}`);
|
||||
|
||||
writeFileSync(keyPath, config.gitSshKey, { mode: 0o600 });
|
||||
const keyContent = config.gitSshKey.endsWith("\n") ? config.gitSshKey : config.gitSshKey + "\n";
|
||||
writeFileSync(keyPath, keyContent, { mode: 0o600 });
|
||||
|
||||
const env = {
|
||||
...process.env,
|
||||
@@ -19,7 +20,7 @@ function withRepo<T>(fn: (dir: string) => T): T {
|
||||
execSync(`git clone ${config.gitRepoUrl} ${dir}`, { env, stdio: "pipe" });
|
||||
execSync(`git -C ${dir} config user.email "manager@lunarfront.tech"`, { env });
|
||||
execSync(`git -C ${dir} config user.name "lunarfront-manager"`, { env });
|
||||
const result = fn(dir);
|
||||
const result = fn(dir, env);
|
||||
execSync(`git -C ${dir} push origin main`, { env, stdio: "pipe" });
|
||||
return result;
|
||||
} finally {
|
||||
@@ -29,19 +30,19 @@ function withRepo<T>(fn: (dir: string) => T): T {
|
||||
}
|
||||
|
||||
export function addCustomerChart(slug: string, appVersion: string) {
|
||||
withRepo((dir) => {
|
||||
withRepo((dir, env) => {
|
||||
const manifest = buildArgoCDApp(slug, appVersion);
|
||||
writeFileSync(join(dir, "customers", `${slug}.yaml`), manifest);
|
||||
execSync(`git -C ${dir} add customers/${slug}.yaml`);
|
||||
execSync(`git -C ${dir} commit -m "feat: provision customer ${slug}"`, { env: process.env });
|
||||
execSync(`git -C ${dir} add customers/${slug}.yaml`, { env });
|
||||
execSync(`git -C ${dir} commit -m "feat: provision customer ${slug}"`, { env });
|
||||
});
|
||||
}
|
||||
|
||||
export function removeCustomerChart(slug: string) {
|
||||
withRepo((dir) => {
|
||||
withRepo((dir, env) => {
|
||||
rmSync(join(dir, "customers", `${slug}.yaml`), { force: true });
|
||||
execSync(`git -C ${dir} add customers/${slug}.yaml`);
|
||||
execSync(`git -C ${dir} commit -m "chore: deprovision customer ${slug}"`, { env: process.env });
|
||||
execSync(`git -C ${dir} add customers/${slug}.yaml`, { env });
|
||||
execSync(`git -C ${dir} commit -m "chore: deprovision customer ${slug}"`, { env });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user