FIX - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: МАТРИЦА ДОСТУПОВ OPERATIONAL CORE

This commit is contained in:
DCCONSTRUCTIONS
2026-05-08 08:59:52 +03:00
parent 784b3ca5c3
commit 652a6ef0c5
7 changed files with 588 additions and 91 deletions
+49 -2
View File
@@ -1147,15 +1147,62 @@ function normalizeClientIntegrations(payload, fallback = {}) {
const taskManager = typeof integrations.taskManager === "object" && integrations.taskManager !== null ? integrations.taskManager : {};
const fallbackTaskManager =
typeof fallbackIntegrations.taskManager === "object" && fallbackIntegrations.taskManager !== null ? fallbackIntegrations.taskManager : {};
const workspaces = normalizeTaskManagerWorkspaces(taskManager, fallbackTaskManager);
const primaryWorkspace = workspaces.find((workspace) => workspace.isPrimary) ?? workspaces[0] ?? null;
return {
taskManager: {
workspaceSlug: nullableStringWithFallback(taskManager.workspaceSlug, fallbackTaskManager.workspaceSlug ?? null),
workspaceName: nullableStringWithFallback(taskManager.workspaceName, fallbackTaskManager.workspaceName ?? null),
workspaceSlug: primaryWorkspace?.slug ?? null,
workspaceName: primaryWorkspace?.name ?? null,
workspaces,
},
};
}
function normalizeTaskManagerWorkspaces(taskManager, fallbackTaskManager = {}) {
const sourceWorkspaces = Array.isArray(taskManager.workspaces)
? taskManager.workspaces
: Array.isArray(fallbackTaskManager.workspaces)
? fallbackTaskManager.workspaces
: [];
const legacySlug = nullableStringWithFallback(taskManager.workspaceSlug, fallbackTaskManager.workspaceSlug ?? null);
const legacyName = nullableStringWithFallback(taskManager.workspaceName, fallbackTaskManager.workspaceName ?? null);
const bySlug = new Map();
for (const item of sourceWorkspaces) {
if (typeof item !== "object" || item === null) continue;
const slug = nullableString(item.slug);
if (!slug) continue;
bySlug.set(slug, {
slug,
name: nullableStringWithFallback(item.name, null),
isPrimary: item.isPrimary === true,
});
}
if (legacySlug && !bySlug.has(legacySlug)) {
bySlug.set(legacySlug, { slug: legacySlug, name: legacyName, isPrimary: true });
}
const workspaces = [...bySlug.values()];
if (!workspaces.length) return [];
if (!workspaces.some((workspace) => workspace.isPrimary)) {
workspaces[0].isPrimary = true;
}
let primarySeen = false;
return workspaces.map((workspace) => {
const isPrimary = workspace.isPrimary && !primarySeen;
if (isPrimary) primarySeen = true;
return {
slug: workspace.slug,
name: workspace.name ?? null,
isPrimary,
};
});
}
function normalizeTaskManagerMembershipRole(value) {
return value === "guest" || value === "admin" || value === "member" ? value : "member";
}
+1 -1
View File
@@ -610,7 +610,7 @@ app.post("/api/admin/task-manager/workspace-memberships/remove", requireLauncher
}
const membership = snapshot.data.memberships.find((candidate) => candidate.clientId === client.id && candidate.userId === user.id);
const workspaceSlug = client.integrations?.taskManager?.workspaceSlug ?? null;
const workspaceSlug = normalizeOptionalText(req.body?.workspaceSlug) ?? client.integrations?.taskManager?.workspaceSlug ?? null;
if (!workspaceSlug) {
res.status(400).json({ ok: false, error: "task_manager_workspace_not_configured" });