feat(platform): checkpoint current implementation state

This commit is contained in:
2026-04-01 07:42:03 +02:00
parent 3e53471f05
commit 8c5be51251
125 changed files with 10269 additions and 17808 deletions
+151
View File
@@ -1345,6 +1345,15 @@ function getTrpcValidationIssues(error: TRPCError): Array<{
function toAssistantUserResourceLinkError(
error: unknown,
): AssistantToolErrorResult | null {
if (error instanceof TRPCError && error.code === "CONFLICT") {
if (error.message.includes("already linked")) {
return { error: "Resource is already linked to another user." };
}
if (error.message.includes("changed during update")) {
return { error: "Resource link changed during update. Please retry." };
}
}
if (error instanceof TRPCError && error.code === "NOT_FOUND") {
if (error.message.includes("Resource")) {
return { error: "Resource not found with the given criteria." };
@@ -1478,6 +1487,9 @@ function toAssistantTaskActionError(
if (error.message.includes("already completed")) {
return { error: "Task is already completed." };
}
if (error.message.includes("dismissed")) {
return { error: "Task has been dismissed and cannot be executed." };
}
}
if (error instanceof TRPCError && error.code === "BAD_REQUEST") {
@@ -1812,6 +1824,14 @@ function toAssistantNotificationCreationError(
return { error: "No recipients matched the broadcast target." };
}
if (
context === "broadcast"
&& trpcError?.code === "BAD_REQUEST"
&& trpcError.message === "Scheduled broadcasts with task metadata are not supported yet."
) {
return { error: "Scheduled broadcasts with task metadata are not supported yet." };
}
if (trpcError?.code === "NOT_FOUND") {
if (trpcError.message.includes("broadcast")) {
return { error: "Broadcast not found with the given criteria." };
@@ -2048,6 +2068,128 @@ export const TOOL_DEFINITIONS: ToolDef[] = withToolAccess([
...settingsAdminToolDefinitions,
], LEGACY_MONOLITHIC_TOOL_ACCESS);
const TOOL_DEFINITIONS_BY_NAME = new Map(
TOOL_DEFINITIONS.map((tool) => [tool.function.name, tool]),
);
type AssistantToolAccessEvaluationContext = Pick<ToolContext, "permissions" | "userRole">;
type AssistantToolAccessFailure =
| { type: "role" }
| {
type: "permission";
permission?: PermissionKey;
message?: string;
};
function hasAssistantResourceOverviewAccess(
permissions: Set<PermissionKey>,
): boolean {
return permissions.has(PermissionKey.VIEW_ALL_RESOURCES)
|| permissions.has(PermissionKey.MANAGE_RESOURCES);
}
function getAssistantToolAccessRequirements(
tool: ToolDef,
): ToolAccessRequirements | undefined {
return tool.access ?? LEGACY_MONOLITHIC_TOOL_ACCESS[tool.function.name];
}
function getAssistantToolAccessFailure(
tool: ToolDef,
ctx: AssistantToolAccessEvaluationContext,
): AssistantToolAccessFailure | null {
const access = getAssistantToolAccessRequirements(tool);
if (!access) {
return null;
}
if (
access.allowedSystemRoles
&& !access.allowedSystemRoles.includes(ctx.userRole as SystemRole)
) {
return { type: "role" };
}
const missingRequiredPermission = access.requiredPermissions?.find(
(permission) => !ctx.permissions.has(permission),
);
if (missingRequiredPermission) {
return {
type: "permission",
permission: missingRequiredPermission,
};
}
if (access.requiresPlanningRead && !ctx.permissions.has(PermissionKey.VIEW_PLANNING)) {
return {
type: "permission",
permission: PermissionKey.VIEW_PLANNING,
};
}
if (access.requiresCostView && !ctx.permissions.has(PermissionKey.VIEW_COSTS)) {
return {
type: "permission",
permission: PermissionKey.VIEW_COSTS,
};
}
if (
access.requiresAdvancedAssistant
&& !ctx.permissions.has(PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS)
) {
return {
type: "permission",
permission: PermissionKey.USE_ASSISTANT_ADVANCED_TOOLS,
};
}
if (
access.requiresResourceOverview
&& !hasAssistantResourceOverviewAccess(ctx.permissions)
) {
return {
type: "permission",
message: "Permission denied: you need resource overview access to perform this action.",
};
}
return null;
}
function toAssistantToolAccessError(
failure: AssistantToolAccessFailure,
): AssistantVisibleError {
if (failure.type === "role") {
return new AssistantVisibleError("You do not have permission to perform this action.");
}
if (failure.permission) {
return new AssistantVisibleError(
`Permission denied: you need the "${failure.permission}" permission to perform this action.`,
);
}
return new AssistantVisibleError(
failure.message ?? "You do not have permission to perform this action.",
);
}
export function canAccessAssistantTool(
tool: ToolDef,
ctx: AssistantToolAccessEvaluationContext,
): boolean {
return getAssistantToolAccessFailure(tool, ctx) === null;
}
export function getAvailableAssistantToolsForContext(
permissions: Set<PermissionKey>,
userRole: string,
): ToolDef[] {
return TOOL_DEFINITIONS.filter((tool) => canAccessAssistantTool(tool, { permissions, userRole }));
}
// ─── Helpers ────────────────────────────────────────────────────────────────
/** Resolve a responsible person name against existing resources. Returns the exact displayName or an error object. */
@@ -2285,6 +2427,7 @@ const executors = {
...createUserSelfServiceExecutors({
createUserCaller,
createScopedCallerContext,
toAssistantCurrentUserError: toAssistantUserMutationError,
toAssistantTotpEnableError,
}),
...createNotificationsTasksExecutors({
@@ -2352,6 +2495,14 @@ export async function executeTool(
if (!executor) return { content: JSON.stringify({ error: `Unknown tool: ${name}` }) };
try {
const toolDefinition = TOOL_DEFINITIONS_BY_NAME.get(name);
const accessFailure = toolDefinition
? getAssistantToolAccessFailure(toolDefinition, ctx)
: null;
if (accessFailure) {
throw toAssistantToolAccessError(accessFailure);
}
const params = JSON.parse(args);
// Audit-log all mutation tool executions (EGAI 4.1.3.1 / IAAI 3.6.26)