feat(approvals): tenant-scoped queue (no cross-tenant work-items)

Plumbed me.tenant_id through api.ping + loginAs into the store as
tenantId. Approvals.loadQueue filters /api/ea2/work-items by
tenant_id matching the signed-in user so the queue only shows
actionable rows. Probe of EA2 work-items returned 73/80 in canvas's
tenant (a0000000-...), 6 in hms_dev, 1 in hub-cnt-f56ce0 -- those
7 are now hidden.
This commit is contained in:
2026-06-14 16:01:54 +04:00
parent 224c259bfd
commit 071166cae1
4 changed files with 65 additions and 3 deletions
+4
View File
@@ -94,6 +94,7 @@ interface AppState {
actor: Actor | null;
userEmail: string;
userDisplayName: string | null;
tenantId: string | null;
isAuthed: boolean;
setUserEmail: (e: string) => void;
loginAs: (email: string, password?: string, options?: { method?: "password" | "dev" }) => Promise<void>;
@@ -141,6 +142,7 @@ async function runLiveFetch(
set({
actor: { mode: "direct_user", user_id: ping.user_id },
userEmail: ping.user ?? get().userEmail,
tenantId: ping.tenant_id ?? get().tenantId,
});
}
const { scenarios, workItems, distinctDefs } = await buildLiveScenariosFromApi();
@@ -256,6 +258,7 @@ export const useApp = create<AppState>((set, get) => {
actor: null,
userEmail: prefs.email ?? "dev@flow-master.ai",
userDisplayName: null,
tenantId: null,
isAuthed: typeof sessionStorage !== "undefined" && !!sessionStorage.getItem("fm.mc.token.v1"),
setUserEmail: (e) => { set({ userEmail: e }); persist(); },
loginAs: async (email, password, options) => {
@@ -274,6 +277,7 @@ export const useApp = create<AppState>((set, get) => {
set({
actor: { mode: "direct_user", user_id: me.user_id },
userDisplayName: me.display_name ?? null,
tenantId: me.tenant_id ?? null,
isAuthed: true,
});
get().pushToast("ok", `Signed in as ${me.email}`);