## Summary Task cards now remove the overseer eye as soon as their workflow's effective oversight becomes `off`, instead of reusing an active value cached before the setting changed. The invalidation covers card remounts as well as mounted cards, and authoritative writes from the dashboard, agents, and configuration rollback reach the board through the existing project-scoped SSE stream. Older in-flight responses cannot restore the eye after a newer `off` value wins, while unrelated workflow-setting saves leave active indicators undisturbed. ## Validation - 99 focused dashboard regression tests passed across selected and aggregate cards, desktop and mobile, SSE delivery, and out-of-order responses - Core and dashboard typechecks passed - `pnpm lint` and `pnpm check:changesets` passed - `pnpm verify:fast` passed production builds and the CLI/server boot smoke <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Planner-overseer eye badges now disappear immediately when workflow oversight is turned off. - Prevented stale or out-of-order updates from displaying incorrect oversight status. - Oversight indicators now remain hidden when the effective setting cannot be confirmed. - Live workflow setting changes now update task cards without requiring a page refresh. - **Documentation** - Clarified eye badge visibility rules, tooltip meaning, and active oversight states in the dashboard guide. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
60 lines
2.4 KiB
TypeScript
60 lines
2.4 KiB
TypeScript
export const WORKFLOW_SETTING_VALUES_UPDATED_EVENT = "fusion:workflow-setting-values-updated";
|
|
|
|
export interface WorkflowSettingValuesUpdatedDetail {
|
|
workflowId: string;
|
|
projectId?: string;
|
|
}
|
|
|
|
const revisions = new Map<string, number>();
|
|
const handledServerMutationIds = new Set<string>();
|
|
const MAX_HANDLED_SERVER_MUTATIONS = 100;
|
|
|
|
export function getWorkflowSettingValuesKey(workflowId: string, projectId?: string): string {
|
|
return `${projectId ?? "default"}::${workflowId}`;
|
|
}
|
|
|
|
export function getWorkflowSettingValuesRevision(workflowId: string, projectId?: string): number {
|
|
return revisions.get(getWorkflowSettingValuesKey(workflowId, projectId)) ?? 0;
|
|
}
|
|
|
|
export function notifyWorkflowSettingValuesUpdated(workflowId: string, projectId?: string): void {
|
|
const key = getWorkflowSettingValuesKey(workflowId, projectId);
|
|
revisions.set(key, (revisions.get(key) ?? 0) + 1);
|
|
if (typeof window !== "undefined") {
|
|
window.dispatchEvent(new CustomEvent<WorkflowSettingValuesUpdatedDetail>(WORKFLOW_SETTING_VALUES_UPDATED_EVENT, {
|
|
detail: { workflowId, projectId },
|
|
}));
|
|
}
|
|
}
|
|
|
|
export interface WorkflowSettingValuesSsePayload {
|
|
workflowId?: unknown;
|
|
projectId?: unknown;
|
|
settingIds?: unknown;
|
|
mutationId?: unknown;
|
|
}
|
|
|
|
/** FNXC:PlannerOversight 2026-07-18-13:35: Bridge an authoritative store/SSE mutation into the card-local revision event.
|
|
* Duplicate dashboard consumers may receive the same multiplexed SSE message, so
|
|
* mutation IDs are bounded and de-duplicated before advancing the revision. */
|
|
export function notifyWorkflowSettingValuesUpdatedFromSse(payload: WorkflowSettingValuesSsePayload): void {
|
|
if (typeof payload.workflowId !== "string" || typeof payload.mutationId !== "string") return;
|
|
if (!Array.isArray(payload.settingIds) || !payload.settingIds.includes("plannerOversightLevel")) return;
|
|
if (handledServerMutationIds.has(payload.mutationId)) return;
|
|
handledServerMutationIds.add(payload.mutationId);
|
|
if (handledServerMutationIds.size > MAX_HANDLED_SERVER_MUTATIONS) {
|
|
const oldest = handledServerMutationIds.values().next().value;
|
|
if (typeof oldest === "string") handledServerMutationIds.delete(oldest);
|
|
}
|
|
notifyWorkflowSettingValuesUpdated(
|
|
payload.workflowId,
|
|
typeof payload.projectId === "string" ? payload.projectId : undefined,
|
|
);
|
|
}
|
|
|
|
/** @internal Test helper */
|
|
export function __test_clearWorkflowSettingValuesRevisions(): void {
|
|
revisions.clear();
|
|
handledServerMutationIds.clear();
|
|
}
|