Implement governed function assignment workflows
This commit is contained in:
@@ -99,10 +99,90 @@ export type OrganizationFunctionAssignmentPayload = {
|
||||
is_active?: boolean;
|
||||
settings?: Record<string, unknown>;
|
||||
change_request_id?: string | null;
|
||||
governance_override_reason?: string | null;
|
||||
governance_override_evidence?: string[];
|
||||
};
|
||||
|
||||
export type IdmSettingsPayload = Partial<Pick<IdmSettings, "require_assignment_change_requests" | "audit_detail_level" | "change_retention_days" | "settings">>;
|
||||
|
||||
export type FunctionAssignmentChangeKind = "request" | "grant";
|
||||
export type FunctionAssignmentChangeAction = "approve" | "reject" | "accept" | "request_changes" | "respond" | "withdraw" | "recover";
|
||||
|
||||
export type FunctionAssignmentChangeEvent = {
|
||||
id: string;
|
||||
sequence: number;
|
||||
action: string;
|
||||
from_state?: string | null;
|
||||
to_state: string;
|
||||
actor_account_id?: string | null;
|
||||
actor_identity_id?: string | null;
|
||||
comment?: string | null;
|
||||
evidence: string[];
|
||||
policy_decision: Record<string, unknown>;
|
||||
workflow_step_id?: string | null;
|
||||
details: Record<string, unknown>;
|
||||
created_at: string;
|
||||
};
|
||||
|
||||
export type FunctionAssignmentChange = {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
kind: FunctionAssignmentChangeKind;
|
||||
state: string;
|
||||
profile: string;
|
||||
function_id: string;
|
||||
organization_unit_id: string;
|
||||
candidate_identity_id: string;
|
||||
candidate_account_id?: string | null;
|
||||
initiator_account_id: string;
|
||||
initiator_identity_id?: string | null;
|
||||
justification: string;
|
||||
evidence: string[];
|
||||
requested_valid_from?: string | null;
|
||||
requested_valid_until?: string | null;
|
||||
required_steps: string[];
|
||||
completed_steps: string[];
|
||||
policy_decision: Record<string, unknown>;
|
||||
workflow_definition_revision?: number | null;
|
||||
workflow_definition_hash?: string | null;
|
||||
workflow_instance_id?: string | null;
|
||||
resulting_assignment_id?: string | null;
|
||||
expires_at?: string | null;
|
||||
outcome_reason?: string | null;
|
||||
resource_revision: number;
|
||||
etag: string;
|
||||
metadata: Record<string, unknown>;
|
||||
events: FunctionAssignmentChangeEvent[];
|
||||
available_actions: FunctionAssignmentChangeAction[];
|
||||
availability_reason?: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
|
||||
export type FunctionAssignmentChangeList = {
|
||||
changes: FunctionAssignmentChange[];
|
||||
total: number;
|
||||
page: number;
|
||||
page_size: number;
|
||||
pages: number;
|
||||
};
|
||||
|
||||
export type FunctionAssignmentChangePayload = {
|
||||
kind: FunctionAssignmentChangeKind;
|
||||
function_id: string;
|
||||
candidate_identity_id: string;
|
||||
candidate_account_id?: string | null;
|
||||
justification: string;
|
||||
evidence?: string[];
|
||||
requested_valid_from?: string | null;
|
||||
requested_valid_until?: string | null;
|
||||
applies_to_subunits?: boolean;
|
||||
assignment_source?: "governance" | "delegated";
|
||||
represented_assignment_id?: string | null;
|
||||
idempotency_key: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
function post<T, P extends Record<string, unknown>>(settings: ApiSettings, path: string, payload: P): Promise<T> {
|
||||
return apiFetch<T>(settings, path, { method: "POST", body: JSON.stringify(payload) });
|
||||
}
|
||||
@@ -168,3 +248,40 @@ export function patchOrganizationFunctionAssignment(
|
||||
): Promise<OrganizationFunctionAssignmentItem> {
|
||||
return patch(settings, `/api/v1/idm/organization-function-assignments/${encodeURIComponent(id)}`, payload);
|
||||
}
|
||||
|
||||
export function getFunctionAssignmentChanges(settings: ApiSettings): Promise<FunctionAssignmentChangeList> {
|
||||
return apiFetch<FunctionAssignmentChangeList>(settings, "/api/v1/idm/function-assignment-changes?page_size=200");
|
||||
}
|
||||
|
||||
export function getFunctionAssignmentChange(settings: ApiSettings, id: string): Promise<FunctionAssignmentChange> {
|
||||
return apiFetch<FunctionAssignmentChange>(settings, `/api/v1/idm/function-assignment-changes/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
export function createFunctionAssignmentChange(
|
||||
settings: ApiSettings,
|
||||
payload: FunctionAssignmentChangePayload
|
||||
): Promise<FunctionAssignmentChange> {
|
||||
return post(settings, "/api/v1/idm/function-assignment-changes", payload);
|
||||
}
|
||||
|
||||
export function actOnFunctionAssignmentChange(
|
||||
settings: ApiSettings,
|
||||
change: FunctionAssignmentChange,
|
||||
action: FunctionAssignmentChangeAction,
|
||||
comment?: string
|
||||
): Promise<FunctionAssignmentChange> {
|
||||
return apiFetch<FunctionAssignmentChange>(
|
||||
settings,
|
||||
`/api/v1/idm/function-assignment-changes/${encodeURIComponent(change.id)}/actions`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: { "If-Match": change.etag },
|
||||
body: JSON.stringify({
|
||||
action,
|
||||
base_revision: change.resource_revision,
|
||||
comment: comment?.trim() || null,
|
||||
evidence: []
|
||||
})
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user