feat(operations-ui): BURST toggle + deadline dialog for the halacha drain (#133)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 7s
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 7s
Implements the chair-approved Claude Design mockup (02b-operations-burst): a single
gold "⚡ הפעל BURST" button on the legal-halacha-drain row that opens a deadline
dialog (datetime-local, default the upcoming Saturday 18:00, quick chips for Sat
18:00 / +5h / midnight). While a burst is active the row shows a gold pill with the
deadline + an "עצור BURST" stop button. Manual only.
- operations.ts: burst_until on OpsService + useDrainBurst hook (POST .../burst).
- page.tsx: BurstControl component, gated to legal-halacha-drain.
- types.ts: regenerated (npm run api:types) — the new burst route.
Active-state is derived from burst_until presence (the supervisor NULLs it at the
deadline, snapshot refetches every 5s) — no impure Date.now() in render.
Invariants: G1/G2 — single DB-backed control (drain_controls.burst_until), shared
with the host supervisor; no parallel path. UI passed the Claude Design gate.
This commit is contained in:
@@ -12,6 +12,7 @@ export type OpsService = {
|
||||
cron: string;
|
||||
autorestart: boolean;
|
||||
disabled?: boolean; // cron drain switched off via the dashboard
|
||||
burst_until?: string | null; // manual "run continuously now" window (ISO) — see useDrainBurst
|
||||
};
|
||||
|
||||
export type CourtFetchJob = {
|
||||
@@ -104,6 +105,28 @@ export function useDrainToggle() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Start/stop a drain's MANUAL burst window ("run continuously now until X").
|
||||
* `until` is a tz-naive local datetime string (e.g. "2026-06-13T18:00") — the
|
||||
* backend interprets it as Israel time. Omit it to let the server default to the
|
||||
* upcoming Saturday 18:00. The host supervisor enforces it within ≤15 min.
|
||||
*/
|
||||
export function useDrainBurst() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ name, action, until }: { name: string; action: "on" | "off"; until?: string }) =>
|
||||
apiRequest(`/api/operations/drains/${name}/burst`, {
|
||||
method: "POST",
|
||||
body: action === "on" ? { action, ...(until ? { until } : {}) } : { action },
|
||||
}),
|
||||
onSuccess: (_d, { action }) => {
|
||||
toast.success(action === "on" ? "BURST הופעל" : "BURST כובה");
|
||||
qc.invalidateQueries({ queryKey: ["operations"] });
|
||||
},
|
||||
onError: (e) => toast.error(`הפעולה נכשלה: ${String(e)}`),
|
||||
});
|
||||
}
|
||||
|
||||
// ── Live agents — which agent is working now + its output + controls ───────
|
||||
|
||||
export type AgentRun = {
|
||||
|
||||
Reference in New Issue
Block a user