Files
HiveGrid-Wireframes/hivegrid-cloud/packages/cli/src/commands/feature-flags/toggle.ts
T

61 lines
2.1 KiB
TypeScript

/**
* `feature-flags enable` / `feature-flags disable` — flip a flag's
* boolean `enabled` and write an audit row, then publish a one-shot
* invalidation on the `feature-flags:invalidate` pub/sub channel so
* every long-lived web replica drops its L1 eval cache for this flag
* immediately rather than serving stale evaluations until the per-key
* TTL expires (#39 cross-process publisher).
*/
import { defineCommand } from "citty";
import consola from "consola";
import { broadcastFlagInvalidation } from "./invalidate.js";
async function toggleFlag(name: string, target: boolean): Promise<void> {
const { getDbClient } = await import("@toolctrl/db/client.server");
const prisma = getDbClient();
const existing = await prisma.featureFlag.findFirst({ where: { name } });
if (!existing) {
consola.error(`Flag "${name}" not found.`);
process.exitCode = 1;
return;
}
if (existing.enabled === target) {
consola.info(`Flag "${name}" is already ${target ? "enabled" : "disabled"}; no-op.`);
return;
}
await prisma.$transaction([
prisma.featureFlag.update({ where: { id: existing.id }, data: { enabled: target } }),
prisma.featureFlagAudit.create({
data: {
flagId: existing.id,
actorUserId: null,
action: "toggle",
oldValue: { enabled: existing.enabled },
newValue: { enabled: target },
},
}),
]);
await broadcastFlagInvalidation(name);
consola.success(`Flag "${name}" → ${target ? "enabled" : "disabled"}.`);
}
export const featureFlagsEnableCommand = defineCommand({
meta: { name: "enable", description: "Enable a feature flag by name." },
args: {
name: { type: "positional", required: true, description: "Flag name." },
},
async run({ args }) {
await toggleFlag(String(args.name), true);
},
});
export const featureFlagsDisableCommand = defineCommand({
meta: { name: "disable", description: "Disable a feature flag by name." },
args: {
name: { type: "positional", required: true, description: "Flag name." },
},
async run({ args }) {
await toggleFlag(String(args.name), false);
},
});