Release v0.1.5
This commit is contained in:
403
webui/src/api/admin.ts
Normal file
403
webui/src/api/admin.ts
Normal file
@@ -0,0 +1,403 @@
|
||||
import type { ApiSettings } from "@govoplan/core-webui";
|
||||
import { apiFetch } from "@govoplan/core-webui";
|
||||
|
||||
export type PermissionItem = {
|
||||
scope: string;
|
||||
label: string;
|
||||
description: string;
|
||||
category: string;
|
||||
level: "tenant" | "system";
|
||||
system_template_id?: string | null;
|
||||
system_required?: boolean;
|
||||
};
|
||||
|
||||
export type AdminOverview = {
|
||||
active_tenant_id: string;
|
||||
active_tenant_name: string;
|
||||
tenant_count?: number | null;
|
||||
system_account_count?: number | null;
|
||||
system_group_template_count?: number | null;
|
||||
system_role_template_count?: number | null;
|
||||
user_count: number;
|
||||
active_user_count: number;
|
||||
group_count: number;
|
||||
role_count: number;
|
||||
active_api_key_count: number;
|
||||
capabilities: string[];
|
||||
};
|
||||
|
||||
export type TenantAdminItem = {
|
||||
id: string;
|
||||
slug: string;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
default_locale: string;
|
||||
settings: Record<string, unknown>;
|
||||
allow_custom_groups?: boolean | null;
|
||||
allow_custom_roles?: boolean | null;
|
||||
allow_api_keys?: boolean | null;
|
||||
effective_governance: Record<string, boolean>;
|
||||
is_active: boolean;
|
||||
counts: Record<string, number>;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
|
||||
export type PrivacyRetentionPolicyFieldKey =
|
||||
| "store_raw_campaign_json"
|
||||
| "raw_campaign_json_retention_days"
|
||||
| "generated_eml_retention_days"
|
||||
| "stored_report_detail_retention_days"
|
||||
| "mock_mailbox_retention_days"
|
||||
| "audit_detail_retention_days"
|
||||
| "audit_detail_level";
|
||||
|
||||
export type PrivacyRetentionLimitPermissions = Record<PrivacyRetentionPolicyFieldKey, boolean>;
|
||||
export type PrivacyRetentionLimitPermissionPatch = Partial<PrivacyRetentionLimitPermissions>;
|
||||
|
||||
export type PrivacyRetentionPolicy = {
|
||||
store_raw_campaign_json: boolean;
|
||||
raw_campaign_json_retention_days?: number | null;
|
||||
generated_eml_retention_days?: number | null;
|
||||
stored_report_detail_retention_days?: number | null;
|
||||
mock_mailbox_retention_days?: number | null;
|
||||
audit_detail_retention_days?: number | null;
|
||||
audit_detail_level: "full" | "redacted" | "minimal";
|
||||
allow_lower_level_limits: PrivacyRetentionLimitPermissions;
|
||||
};
|
||||
|
||||
export type PrivacyRetentionPolicyPatch = Partial<Omit<PrivacyRetentionPolicy, "allow_lower_level_limits">> & {
|
||||
allow_lower_level_limits?: PrivacyRetentionLimitPermissionPatch;
|
||||
};
|
||||
|
||||
export type MaintenanceMode = {
|
||||
enabled: boolean;
|
||||
message?: string | null;
|
||||
};
|
||||
|
||||
export type SystemSettingsItem = {
|
||||
default_locale: string;
|
||||
allow_tenant_custom_groups: boolean;
|
||||
allow_tenant_custom_roles: boolean;
|
||||
allow_tenant_api_keys: boolean;
|
||||
privacy_retention_policy: PrivacyRetentionPolicy;
|
||||
maintenance_mode: MaintenanceMode;
|
||||
settings: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type SystemSettingsUpdatePayload = {
|
||||
default_locale: string;
|
||||
allow_tenant_custom_groups: boolean;
|
||||
allow_tenant_custom_roles: boolean;
|
||||
allow_tenant_api_keys: boolean;
|
||||
privacy_retention_policy?: PrivacyRetentionPolicy | null;
|
||||
maintenance_mode?: MaintenanceMode | null;
|
||||
};
|
||||
|
||||
export type ModuleCatalogItem = {
|
||||
id: string;
|
||||
name: string;
|
||||
version: string;
|
||||
installed: boolean;
|
||||
current_enabled: boolean;
|
||||
desired_enabled: boolean;
|
||||
protected: boolean;
|
||||
restart_required: boolean;
|
||||
dependencies: string[];
|
||||
optional_dependencies: string[];
|
||||
dependents: string[];
|
||||
permissions_count: number;
|
||||
role_templates_count: number;
|
||||
route_contributed: boolean;
|
||||
nav_count: number;
|
||||
frontend_package?: string | null;
|
||||
migration_module_id?: string | null;
|
||||
migration_script_location?: string | null;
|
||||
runtime_toggle_supported: boolean;
|
||||
install_uninstall_supported: boolean;
|
||||
};
|
||||
|
||||
export type ModuleCatalogResponse = {
|
||||
modules: ModuleCatalogItem[];
|
||||
current_enabled: string[];
|
||||
desired_enabled: string[];
|
||||
configured_enabled: string[];
|
||||
protected_modules: string[];
|
||||
restart_required: boolean;
|
||||
runtime_toggle_supported: boolean;
|
||||
install_uninstall_supported: boolean;
|
||||
install_plan_supported: boolean;
|
||||
package_mutation_supported: boolean;
|
||||
maintenance_mode: MaintenanceMode;
|
||||
notes: string[];
|
||||
};
|
||||
|
||||
export type ModuleInstallPlanItem = {
|
||||
module_id: string;
|
||||
action: "install" | "uninstall";
|
||||
python_package?: string | null;
|
||||
python_ref?: string | null;
|
||||
webui_package?: string | null;
|
||||
webui_ref?: string | null;
|
||||
destroy_data: boolean;
|
||||
status: "planned" | "applied" | "blocked";
|
||||
notes?: string | null;
|
||||
};
|
||||
|
||||
export type ModuleInstallPreflightIssue = {
|
||||
severity: "blocker" | "warning" | "info";
|
||||
code: string;
|
||||
message: string;
|
||||
module_id?: string | null;
|
||||
};
|
||||
|
||||
export type ModuleInstallChecklistItem = {
|
||||
id: string;
|
||||
label: string;
|
||||
status: "done" | "pending" | "blocked" | "warning";
|
||||
detail?: string | null;
|
||||
};
|
||||
|
||||
export type ModuleInstallPreflight = {
|
||||
allowed: boolean;
|
||||
maintenance_mode: boolean;
|
||||
frontend_rebuild_required: boolean;
|
||||
restart_required: boolean;
|
||||
commands: string[];
|
||||
rollback_commands: string[];
|
||||
issues: ModuleInstallPreflightIssue[];
|
||||
checklist: ModuleInstallChecklistItem[];
|
||||
};
|
||||
|
||||
export type ModuleInstallPlanResponse = {
|
||||
items: ModuleInstallPlanItem[];
|
||||
updated_at?: string | null;
|
||||
commands: string[];
|
||||
maintenance_mode: MaintenanceMode;
|
||||
preflight?: ModuleInstallPreflight | null;
|
||||
notes: string[];
|
||||
};
|
||||
|
||||
export type ModuleInstallerLockStatus = {
|
||||
locked: boolean;
|
||||
path: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export type ModuleInstallerDaemonStatus = {
|
||||
running: boolean;
|
||||
status: string;
|
||||
path: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export type ModuleInstallerRunSummary = {
|
||||
run_id: string;
|
||||
status: string;
|
||||
started_at?: string | null;
|
||||
finished_at?: string | null;
|
||||
rollback_status?: string | null;
|
||||
supervisor_status?: string | null;
|
||||
error?: string | null;
|
||||
record_path: string;
|
||||
commands_count: number;
|
||||
planned_modules: string[];
|
||||
};
|
||||
|
||||
export type ModuleInstallerRunListResponse = {
|
||||
runs: ModuleInstallerRunSummary[];
|
||||
lock: ModuleInstallerLockStatus;
|
||||
};
|
||||
|
||||
export type ModuleInstallerRequestOptions = {
|
||||
build_webui: boolean;
|
||||
migrate_database: boolean;
|
||||
webui_root?: string | null;
|
||||
npm_bin?: string | null;
|
||||
database_backup_command?: string | null;
|
||||
database_restore_command?: string | null;
|
||||
database_restore_check_command?: string | null;
|
||||
activate_installed_modules: boolean;
|
||||
remove_uninstalled_modules_from_desired: boolean;
|
||||
restart_commands: string[];
|
||||
health_urls: string[];
|
||||
health_timeout_seconds: number;
|
||||
health_interval_seconds: number;
|
||||
};
|
||||
|
||||
export type ModuleInstallerRequestItem = {
|
||||
request_id: string;
|
||||
status: string;
|
||||
created_at: string;
|
||||
requested_by?: string | null;
|
||||
started_at?: string | null;
|
||||
finished_at?: string | null;
|
||||
cancelled_at?: string | null;
|
||||
cancelled_by?: string | null;
|
||||
retry_of?: string | null;
|
||||
error?: string | null;
|
||||
record_path?: string | null;
|
||||
options: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type ModuleInstallerRequestListResponse = {
|
||||
requests: ModuleInstallerRequestItem[];
|
||||
daemon: ModuleInstallerDaemonStatus;
|
||||
};
|
||||
|
||||
export type ModulePackageCatalogItem = {
|
||||
module_id: string;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
version?: string | null;
|
||||
action: "install" | "uninstall";
|
||||
python_package?: string | null;
|
||||
python_ref?: string | null;
|
||||
webui_package?: string | null;
|
||||
webui_ref?: string | null;
|
||||
license_features: string[];
|
||||
license_allowed: boolean;
|
||||
license_enforced: boolean;
|
||||
license_missing_features: string[];
|
||||
license_reason?: string | null;
|
||||
notes?: string | null;
|
||||
tags: string[];
|
||||
};
|
||||
|
||||
export type ModulePackageCatalogResponse = {
|
||||
modules: ModulePackageCatalogItem[];
|
||||
configured: boolean;
|
||||
valid: boolean;
|
||||
path?: string | null;
|
||||
source?: string | null;
|
||||
source_type?: string | null;
|
||||
channel?: string | null;
|
||||
sequence?: number | null;
|
||||
generated_at?: string | null;
|
||||
expires_at?: string | null;
|
||||
signed: boolean;
|
||||
trusted: boolean;
|
||||
key_id?: string | null;
|
||||
warnings: string[];
|
||||
error?: string | null;
|
||||
};
|
||||
|
||||
export type GovernanceAssignment = {
|
||||
tenant_id: string;
|
||||
mode: "available" | "required";
|
||||
};
|
||||
|
||||
export type GovernanceTemplateItem = {
|
||||
id: string;
|
||||
kind: "group" | "role";
|
||||
slug: string;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
permissions: string[];
|
||||
effective_permission_count: number;
|
||||
is_active: boolean;
|
||||
assignments: GovernanceAssignment[];
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
|
||||
export function fetchAdminOverview(settings: ApiSettings): Promise<AdminOverview> {
|
||||
return apiFetch(settings, "/api/v1/admin/overview");
|
||||
}
|
||||
|
||||
export async function fetchPermissionCatalog(settings: ApiSettings): Promise<PermissionItem[]> {
|
||||
const response = await apiFetch<{ permissions: PermissionItem[] }>(settings, "/api/v1/admin/permissions");
|
||||
return response.permissions;
|
||||
}
|
||||
|
||||
export async function fetchTenants(settings: ApiSettings): Promise<TenantAdminItem[]> {
|
||||
const response = await apiFetch<{ tenants: TenantAdminItem[] }>(settings, "/api/v1/admin/tenants");
|
||||
return response.tenants;
|
||||
}
|
||||
|
||||
export function fetchSystemSettings(settings: ApiSettings): Promise<SystemSettingsItem> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/settings");
|
||||
}
|
||||
|
||||
export function updateSystemSettings(settings: ApiSettings, payload: SystemSettingsUpdatePayload): Promise<SystemSettingsItem> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/settings", { method: "PATCH", body: JSON.stringify(payload) });
|
||||
}
|
||||
|
||||
export function fetchModuleCatalog(settings: ApiSettings): Promise<ModuleCatalogResponse> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/modules");
|
||||
}
|
||||
|
||||
export function updateModuleState(settings: ApiSettings, enabledModules: string[]): Promise<ModuleCatalogResponse> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/modules", {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({ enabled_modules: enabledModules })
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchModuleInstallPlan(settings: ApiSettings): Promise<ModuleInstallPlanResponse> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/modules/install-plan");
|
||||
}
|
||||
|
||||
export function fetchModuleInstallerRuns(settings: ApiSettings): Promise<ModuleInstallerRunListResponse> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/modules/install-runs");
|
||||
}
|
||||
|
||||
export function fetchModuleInstallerRequests(settings: ApiSettings): Promise<ModuleInstallerRequestListResponse> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/modules/install-requests");
|
||||
}
|
||||
|
||||
export function createModuleInstallerRequest(settings: ApiSettings, options: ModuleInstallerRequestOptions): Promise<ModuleInstallerRequestItem> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/modules/install-requests", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ options })
|
||||
});
|
||||
}
|
||||
|
||||
export function cancelModuleInstallerRequest(settings: ApiSettings, requestId: string): Promise<ModuleInstallerRequestItem> {
|
||||
return apiFetch(settings, `/api/v1/admin/system/modules/install-requests/${requestId}/cancel`, { method: "POST" });
|
||||
}
|
||||
|
||||
export function retryModuleInstallerRequest(settings: ApiSettings, requestId: string): Promise<ModuleInstallerRequestItem> {
|
||||
return apiFetch(settings, `/api/v1/admin/system/modules/install-requests/${requestId}/retry`, { method: "POST" });
|
||||
}
|
||||
|
||||
export function fetchModulePackageCatalog(settings: ApiSettings): Promise<ModulePackageCatalogResponse> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/modules/package-catalog");
|
||||
}
|
||||
|
||||
export function planModuleInstallFromCatalog(settings: ApiSettings, moduleId: string): Promise<ModuleInstallPlanResponse> {
|
||||
return apiFetch(settings, `/api/v1/admin/system/modules/install-plan/catalog/${encodeURIComponent(moduleId)}`, { method: "POST" });
|
||||
}
|
||||
|
||||
export function planModuleUninstall(settings: ApiSettings, moduleId: string): Promise<ModuleInstallPlanResponse> {
|
||||
return apiFetch(settings, `/api/v1/admin/system/modules/${encodeURIComponent(moduleId)}/uninstall-plan`, { method: "POST" });
|
||||
}
|
||||
|
||||
export function updateModuleInstallPlan(settings: ApiSettings, items: ModuleInstallPlanItem[]): Promise<ModuleInstallPlanResponse> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/modules/install-plan", {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({ items })
|
||||
});
|
||||
}
|
||||
|
||||
export function clearModuleInstallPlan(settings: ApiSettings): Promise<ModuleInstallPlanResponse> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/modules/install-plan", { method: "DELETE" });
|
||||
}
|
||||
|
||||
export async function fetchGovernanceTemplates(settings: ApiSettings, kind?: "group" | "role"): Promise<GovernanceTemplateItem[]> {
|
||||
const suffix = kind ? `?kind=${encodeURIComponent(kind)}` : "";
|
||||
const response = await apiFetch<{ templates: GovernanceTemplateItem[] }>(settings, `/api/v1/admin/system/governance-templates${suffix}`);
|
||||
return response.templates;
|
||||
}
|
||||
|
||||
export function createGovernanceTemplate(settings: ApiSettings, payload: Omit<GovernanceTemplateItem, "id" | "created_at" | "updated_at" | "effective_permission_count">): Promise<GovernanceTemplateItem> {
|
||||
return apiFetch(settings, "/api/v1/admin/system/governance-templates", { method: "POST", body: JSON.stringify(payload) });
|
||||
}
|
||||
|
||||
export function updateGovernanceTemplate(settings: ApiSettings, templateId: string, payload: Omit<GovernanceTemplateItem, "id" | "kind" | "slug" | "created_at" | "updated_at" | "effective_permission_count">): Promise<GovernanceTemplateItem> {
|
||||
return apiFetch(settings, `/api/v1/admin/system/governance-templates/${templateId}`, { method: "PATCH", body: JSON.stringify(payload) });
|
||||
}
|
||||
|
||||
export function deleteGovernanceTemplate(settings: ApiSettings, templateId: string): Promise<void> {
|
||||
return apiFetch(settings, `/api/v1/admin/system/governance-templates/${templateId}`, { method: "DELETE" });
|
||||
}
|
||||
Reference in New Issue
Block a user