feat: add access module boundary migrations
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { ApiSettings } from "@govoplan/core-webui";
|
||||
import type { ApiSettings, DeltaDeletedItem } from "@govoplan/core-webui";
|
||||
import { apiFetch } from "@govoplan/core-webui";
|
||||
|
||||
export type PermissionItem = {
|
||||
@@ -171,17 +171,35 @@ export type SystemSettingsItem = {
|
||||
allow_tenant_custom_roles: boolean;
|
||||
allow_tenant_api_keys: boolean;
|
||||
privacy_retention_policy: PrivacyRetentionPolicy;
|
||||
available_languages?: LanguagePackage[];
|
||||
enabled_language_codes?: string[];
|
||||
settings: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type LanguagePackage = {
|
||||
code: string;
|
||||
label: string;
|
||||
native_label?: string | null;
|
||||
};
|
||||
|
||||
export type TenantSettingsItem = {
|
||||
id: string;
|
||||
slug: string;
|
||||
name: string;
|
||||
default_locale: string;
|
||||
available_languages: LanguagePackage[];
|
||||
system_enabled_language_codes: string[];
|
||||
enabled_language_codes: string[];
|
||||
settings: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type TenantSettingsDeltaSections = Partial<{
|
||||
identity: Pick<TenantSettingsItem, "id" | "slug" | "name">;
|
||||
locale: Pick<TenantSettingsItem, "default_locale">;
|
||||
languages: Pick<TenantSettingsItem, "available_languages" | "system_enabled_language_codes" | "enabled_language_codes">;
|
||||
settings: Pick<TenantSettingsItem, "settings">["settings"];
|
||||
}>;
|
||||
|
||||
export type RetentionRunResponse = {
|
||||
result: {
|
||||
dry_run: boolean;
|
||||
@@ -236,6 +254,42 @@ export type AuditAdminItem = {
|
||||
created_at: string;
|
||||
};
|
||||
|
||||
type DeltaResponseFields = {
|
||||
deleted: DeltaDeletedItem[];
|
||||
watermark?: string | null;
|
||||
has_more: boolean;
|
||||
full: boolean;
|
||||
};
|
||||
|
||||
export type UserListDeltaResponse = { users: UserAdminItem[] } & DeltaResponseFields;
|
||||
export type GroupListDeltaResponse = { groups: GroupSummary[] } & DeltaResponseFields;
|
||||
export type RoleListDeltaResponse = { roles: RoleSummary[] } & DeltaResponseFields;
|
||||
export type SystemAccountListDeltaResponse = { accounts: SystemAccountItem[]; roles: RoleSummary[] } & DeltaResponseFields;
|
||||
export type ApiKeyListDeltaResponse = { api_keys: ApiKeyAdminItem[] } & DeltaResponseFields;
|
||||
export type TenantListDeltaResponse = { tenants: TenantAdminItem[] } & DeltaResponseFields;
|
||||
export type GovernanceTemplateListDeltaResponse = { templates: GovernanceTemplateItem[] } & DeltaResponseFields;
|
||||
export type TenantSettingsDeltaResponse = {
|
||||
item?: TenantSettingsItem | null;
|
||||
sections: TenantSettingsDeltaSections;
|
||||
changed_sections: string[];
|
||||
} & DeltaResponseFields;
|
||||
export type AuditAdminDeltaResponse = {
|
||||
items: AuditAdminItem[];
|
||||
total: number;
|
||||
page: number;
|
||||
page_size: number;
|
||||
pages: number;
|
||||
cursor?: string | null;
|
||||
next_cursor?: string | null;
|
||||
} & DeltaResponseFields;
|
||||
|
||||
function deltaSuffix(options: { since?: string | null; limit?: number } = {}): string {
|
||||
const params = new URLSearchParams();
|
||||
if (options.since) params.set("since", options.since);
|
||||
if (options.limit) params.set("limit", String(options.limit));
|
||||
return params.toString() ? `?${params.toString()}` : "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function fetchAdminOverview(settings: ApiSettings): Promise<AdminOverview> {
|
||||
@@ -252,6 +306,11 @@ export async function fetchTenants(settings: ApiSettings): Promise<TenantAdminIt
|
||||
return response.tenants;
|
||||
}
|
||||
|
||||
export function fetchTenantsDelta(settings: ApiSettings, options: { since?: string | null; limit?: number } = {}): Promise<TenantListDeltaResponse> {
|
||||
const suffix = deltaSuffix(options);
|
||||
return apiFetch(settings, `/api/v1/admin/tenants/delta${suffix}`);
|
||||
}
|
||||
|
||||
export async function fetchTenantOwnerCandidates(settings: ApiSettings): Promise<TenantOwnerCandidate[]> {
|
||||
const response = await apiFetch<{ accounts: TenantOwnerCandidate[] }>(settings, "/api/v1/admin/tenants/owner-candidates");
|
||||
return response.accounts;
|
||||
@@ -289,7 +348,12 @@ export function fetchTenantSettings(settings: ApiSettings): Promise<TenantSettin
|
||||
return apiFetch(settings, "/api/v1/admin/tenant/settings");
|
||||
}
|
||||
|
||||
export function updateTenantSettings(settings: ApiSettings, payload: { default_locale: string }): Promise<TenantSettingsItem> {
|
||||
export function fetchTenantSettingsDelta(settings: ApiSettings, options: { since?: string | null; limit?: number } = {}): Promise<TenantSettingsDeltaResponse> {
|
||||
const suffix = deltaSuffix(options);
|
||||
return apiFetch(settings, `/api/v1/admin/tenant/settings/delta${suffix}`);
|
||||
}
|
||||
|
||||
export function updateTenantSettings(settings: ApiSettings, payload: { default_locale: string; enabled_language_codes?: string[] | null }): Promise<TenantSettingsItem> {
|
||||
return apiFetch(settings, "/api/v1/admin/tenant/settings", { method: "PATCH", body: JSON.stringify(payload) });
|
||||
}
|
||||
|
||||
@@ -298,6 +362,11 @@ export async function fetchUsers(settings: ApiSettings): Promise<UserAdminItem[]
|
||||
return response.users;
|
||||
}
|
||||
|
||||
export function fetchUsersDelta(settings: ApiSettings, options: { since?: string | null; limit?: number } = {}): Promise<UserListDeltaResponse> {
|
||||
const suffix = deltaSuffix(options);
|
||||
return apiFetch(settings, `/api/v1/admin/users/delta${suffix}`);
|
||||
}
|
||||
|
||||
export function createUser(settings: ApiSettings, payload: {
|
||||
email: string;
|
||||
display_name?: string | null;
|
||||
@@ -324,6 +393,11 @@ export async function fetchGroups(settings: ApiSettings): Promise<GroupSummary[]
|
||||
return response.groups;
|
||||
}
|
||||
|
||||
export function fetchGroupsDelta(settings: ApiSettings, options: { since?: string | null; limit?: number } = {}): Promise<GroupListDeltaResponse> {
|
||||
const suffix = deltaSuffix(options);
|
||||
return apiFetch(settings, `/api/v1/admin/groups/delta${suffix}`);
|
||||
}
|
||||
|
||||
export function createGroup(settings: ApiSettings, payload: {
|
||||
slug: string;
|
||||
name: string;
|
||||
@@ -350,6 +424,11 @@ export async function fetchRoles(settings: ApiSettings): Promise<RoleSummary[]>
|
||||
return response.roles;
|
||||
}
|
||||
|
||||
export function fetchRolesDelta(settings: ApiSettings, options: { since?: string | null; limit?: number } = {}): Promise<RoleListDeltaResponse> {
|
||||
const suffix = deltaSuffix(options);
|
||||
return apiFetch(settings, `/api/v1/admin/roles/delta${suffix}`);
|
||||
}
|
||||
|
||||
export function createRole(settings: ApiSettings, payload: {
|
||||
slug: string;
|
||||
name: string;
|
||||
@@ -377,6 +456,11 @@ export async function fetchSystemRoles(settings: ApiSettings): Promise<RoleSumma
|
||||
return response.roles;
|
||||
}
|
||||
|
||||
export function fetchSystemRolesDelta(settings: ApiSettings, options: { since?: string | null; limit?: number } = {}): Promise<RoleListDeltaResponse> {
|
||||
const suffix = deltaSuffix(options);
|
||||
return apiFetch(settings, `/api/v1/admin/system/roles/delta${suffix}`);
|
||||
}
|
||||
|
||||
export function createSystemRole(settings: ApiSettings, payload: {
|
||||
slug: string;
|
||||
name: string;
|
||||
@@ -403,6 +487,11 @@ export async function fetchSystemAccounts(settings: ApiSettings): Promise<{ acco
|
||||
return apiFetch(settings, "/api/v1/admin/system/accounts");
|
||||
}
|
||||
|
||||
export function fetchSystemAccountsDelta(settings: ApiSettings, options: { since?: string | null; limit?: number } = {}): Promise<SystemAccountListDeltaResponse> {
|
||||
const suffix = deltaSuffix(options);
|
||||
return apiFetch(settings, `/api/v1/admin/system/accounts/delta${suffix}`);
|
||||
}
|
||||
|
||||
export function updateSystemAccount(settings: ApiSettings, accountId: string, payload: {
|
||||
display_name?: string | null;
|
||||
is_active?: boolean;
|
||||
@@ -429,6 +518,15 @@ export async function fetchApiKeys(settings: ApiSettings, includeRevoked = false
|
||||
return response.api_keys;
|
||||
}
|
||||
|
||||
export function fetchApiKeysDelta(settings: ApiSettings, includeRevoked = false, options: { since?: string | null; limit?: number } = {}): Promise<ApiKeyListDeltaResponse> {
|
||||
const params = new URLSearchParams();
|
||||
if (includeRevoked) params.set("include_revoked", "true");
|
||||
if (options.since) params.set("since", options.since);
|
||||
if (options.limit) params.set("limit", String(options.limit));
|
||||
const suffix = params.toString() ? `?${params.toString()}` : "";
|
||||
return apiFetch(settings, `/api/v1/admin/api-keys/delta${suffix}`);
|
||||
}
|
||||
|
||||
export function createApiKey(settings: ApiSettings, payload: {
|
||||
name: string;
|
||||
user_id?: string | null;
|
||||
@@ -450,12 +548,13 @@ export type AuditQueryOptions = {
|
||||
offset?: number;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
cursor?: string | null;
|
||||
sortBy?: "time" | "actor" | "action" | "object" | "tenant";
|
||||
sortDirection?: "asc" | "desc";
|
||||
filters?: Partial<Record<"time" | "actor" | "action" | "object" | "tenant", string>>;
|
||||
};
|
||||
|
||||
export async function fetchAdminAudit(settings: ApiSettings, options: AuditQueryOptions = {}): Promise<{ items: AuditAdminItem[]; total: number; page: number; page_size: number; pages: number }> {
|
||||
export async function fetchAdminAudit(settings: ApiSettings, options: AuditQueryOptions = {}): Promise<{ items: AuditAdminItem[]; total: number; page: number; page_size: number; pages: number; cursor?: string | null; next_cursor?: string | null }> {
|
||||
const params = new URLSearchParams();
|
||||
if (options.tenantId) params.set("tenant_id", options.tenantId);
|
||||
if (options.allTenants) params.set("all_tenants", "true");
|
||||
@@ -464,6 +563,7 @@ export async function fetchAdminAudit(settings: ApiSettings, options: AuditQuery
|
||||
if (options.offset) params.set("offset", String(options.offset));
|
||||
if (options.page) params.set("page", String(options.page));
|
||||
if (options.pageSize) params.set("page_size", String(options.pageSize));
|
||||
if (options.cursor) params.set("cursor", options.cursor);
|
||||
if (options.sortBy) params.set("sort_by", options.sortBy);
|
||||
if (options.sortDirection) params.set("sort_direction", options.sortDirection);
|
||||
for (const [column, value] of Object.entries(options.filters ?? {})) {
|
||||
@@ -473,6 +573,24 @@ export async function fetchAdminAudit(settings: ApiSettings, options: AuditQuery
|
||||
return apiFetch(settings, `/api/v1/admin/audit${suffix}`);
|
||||
}
|
||||
|
||||
export async function fetchAdminAuditDelta(settings: ApiSettings, options: AuditQueryOptions & { since?: string | null } = {}): Promise<AuditAdminDeltaResponse> {
|
||||
const params = new URLSearchParams();
|
||||
if (options.tenantId) params.set("tenant_id", options.tenantId);
|
||||
if (options.allTenants) params.set("all_tenants", "true");
|
||||
if (options.scope) params.set("scope", options.scope);
|
||||
if (options.limit) params.set("limit", String(options.limit));
|
||||
if (options.pageSize) params.set("page_size", String(options.pageSize));
|
||||
if (options.cursor) params.set("cursor", options.cursor);
|
||||
if (options.sortBy) params.set("sort_by", options.sortBy);
|
||||
if (options.sortDirection) params.set("sort_direction", options.sortDirection);
|
||||
if (options.since) params.set("since", options.since);
|
||||
for (const [column, value] of Object.entries(options.filters ?? {})) {
|
||||
if (value?.trim()) params.set(`filter_${column}`, value);
|
||||
}
|
||||
const suffix = params.toString() ? `?${params.toString()}` : "";
|
||||
return apiFetch(settings, `/api/v1/admin/audit/delta${suffix}`);
|
||||
}
|
||||
|
||||
|
||||
export function createSystemAccount(settings: ApiSettings, payload: {
|
||||
email: string;
|
||||
@@ -502,6 +620,8 @@ export type SystemSettingsUpdatePayload = {
|
||||
allow_tenant_custom_roles: boolean;
|
||||
allow_tenant_api_keys: boolean;
|
||||
privacy_retention_policy?: PrivacyRetentionPolicy | null;
|
||||
available_languages?: LanguagePackage[] | null;
|
||||
enabled_language_codes?: string[] | null;
|
||||
};
|
||||
|
||||
export function updateSystemSettings(settings: ApiSettings, payload: SystemSettingsUpdatePayload): Promise<SystemSettingsItem> {
|
||||
@@ -532,6 +652,11 @@ export async function fetchGovernanceTemplates(settings: ApiSettings, kind?: "gr
|
||||
return response.templates;
|
||||
}
|
||||
|
||||
export function fetchGovernanceTemplatesDelta(settings: ApiSettings, options: { since?: string | null; limit?: number } = {}): Promise<GovernanceTemplateListDeltaResponse> {
|
||||
const suffix = deltaSuffix(options);
|
||||
return apiFetch(settings, `/api/v1/admin/system/governance-templates/delta${suffix}`);
|
||||
}
|
||||
|
||||
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) });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user