diff --git a/src/api/client.ts b/src/api/client.ts index d10e041..cca0af6 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -20,10 +20,6 @@ import type { Message, MindSpaceAgentJob, MindSpaceQuota, - PageDataAccessPolicy, - PageDataDatasetSummary, - PageDataLogEntry, - PageDataOpsOverview, PlazaCategory, PlazaPostBrief, FeedbackContextInput, @@ -103,6 +99,20 @@ export { redactMindSpacePage, updatePublicationStatus, } from './mindspace-publications'; +export { + applyPageDataPublishPolicy, + buildPageDataExportUrl, + closePageDataDataset, + getPageDataOpsOverview, + getPageDataPolicy, + listOwnerPageDataPolicies, + listPageDataDatasets, + listPageDataLogs, + resetPageDataPassword, + restorePageDataRow, + revokePageDataTokens, + savePageDataPolicy, +} from './page-data'; const AGENT_CONNECT_TIMEOUT_MS = 60_000; const QUICK_PLAZA_TIMEOUT_MS = 120_000; @@ -607,165 +617,6 @@ export async function fetchPreviewAsset(path: string): Promise { return URL.createObjectURL(blob); } -export async function listOwnerPageDataPolicies(): Promise< - Array<{ - pageId: string; - ownerUserId: string; - accessMode: string; - datasetCount: number; - scopeHash: string; - updatedAt: number; - }> -> { - const result = await apiFetch<{ - data: { - policies: Array<{ - pageId: string; - ownerUserId: string; - accessMode: string; - datasetCount: number; - scopeHash: string; - updatedAt: number; - }>; - }; - }>('/admin/page-data/policies'); - return result.data.policies; -} - -export function buildPageDataExportUrl(dataset: string, format: 'json' | 'csv' = 'json') { - const params = new URLSearchParams({ format }); - return `/api/admin/page-data/${encodeURIComponent(dataset)}/export?${params.toString()}`; -} - -export async function listPageDataDatasets(): Promise { - const result = await apiFetch<{ data: { datasets: PageDataDatasetSummary[] } }>('/admin/page-data'); - return result.data.datasets; -} - -export async function getPageDataPolicy(pageId: string): Promise { - try { - const result = await apiFetch<{ data: { policy: PageDataAccessPolicy } }>( - `/admin/page-data/policies/${encodeURIComponent(pageId)}`, - ); - return result.data.policy; - } catch (error) { - if (error instanceof ApiError && error.status === 404) return null; - throw error; - } -} - -export async function applyPageDataPublishPolicy( - pageId: string, - input: { - datasetName: string; - capabilities?: { - read?: boolean; - insert?: boolean; - update?: boolean; - softDelete?: boolean; - }; - }, -): Promise { - const result = await apiFetch<{ data: { policy: PageDataAccessPolicy } }>( - `/admin/page-data/policies/${encodeURIComponent(pageId)}/apply-publish`, - { - method: 'POST', - body: JSON.stringify({ - datasetName: input.datasetName, - capabilities: input.capabilities ?? {}, - }), - }, - ); - return result.data.policy; -} - -export async function savePageDataPolicy( - pageId: string, - policy: Partial, -): Promise { - const result = await apiFetch<{ data: { policy: PageDataAccessPolicy } }>( - `/admin/page-data/policies/${encodeURIComponent(pageId)}`, - { - method: 'PUT', - body: JSON.stringify(policy), - }, - ); - return result.data.policy; -} - -export async function getPageDataOpsOverview(pageId: string): Promise { - const result = await apiFetch<{ data: PageDataOpsOverview }>( - `/admin/page-data/policies/${encodeURIComponent(pageId)}/ops`, - ); - return result.data; -} - -export async function listPageDataLogs( - pageId: string, - input: { limit?: number; offset?: number } = {}, -): Promise<{ pageId: string; logs: PageDataLogEntry[]; count: number }> { - const params = new URLSearchParams(); - if (input.limit != null) params.set('limit', String(input.limit)); - if (input.offset != null) params.set('offset', String(input.offset)); - const query = params.toString(); - const result = await apiFetch<{ data: { pageId: string; logs: PageDataLogEntry[]; count: number } }>( - `/admin/page-data/policies/${encodeURIComponent(pageId)}/logs${query ? `?${query}` : ''}`, - ); - return result.data; -} - -export async function revokePageDataTokens( - pageId: string, - input: { revokeAll?: boolean; token?: string }, -): Promise<{ pageId: string; revokedCount: number; revokeAll: boolean }> { - const result = await apiFetch<{ data: { pageId: string; revokedCount: number; revokeAll: boolean } }>( - `/admin/page-data/policies/${encodeURIComponent(pageId)}/tokens/revoke`, - { - method: 'POST', - body: JSON.stringify({ - revokeAll: Boolean(input.revokeAll), - token: input.token, - }), - }, - ); - return result.data; -} - -export async function resetPageDataPassword( - pageId: string, - password: string, -): Promise<{ pageId: string; passwordReset: boolean; revokedSessions: number }> { - const result = await apiFetch<{ - data: { pageId: string; passwordReset: boolean; revokedSessions: number }; - }>(`/admin/page-data/policies/${encodeURIComponent(pageId)}/password/reset`, { - method: 'POST', - body: JSON.stringify({ password }), - }); - return result.data; -} - -export async function closePageDataDataset( - pageId: string, - dataset: string, -): Promise<{ pageId: string; dataset: string; closed: boolean }> { - const result = await apiFetch<{ data: { pageId: string; dataset: string; closed: boolean } }>( - `/admin/page-data/policies/${encodeURIComponent(pageId)}/datasets/${encodeURIComponent(dataset)}/close`, - { method: 'POST' }, - ); - return result.data; -} - -export async function restorePageDataRow( - dataset: string, - rowId: number | string, -): Promise<{ restored: boolean; row: Record }> { - const result = await apiFetch<{ data: { restored: boolean; row: Record } }>( - `/admin/page-data/${encodeURIComponent(dataset)}/rows/${encodeURIComponent(String(rowId))}/restore`, - { method: 'POST' }, - ); - return result.data; -} - export async function listPlazaCategories(): Promise { const result = await apiFetch<{ data: { categories: PlazaCategory[] } }>('/plaza/v1/categories'); return result.data.categories; diff --git a/src/api/page-data.ts b/src/api/page-data.ts new file mode 100644 index 0000000..a35d334 --- /dev/null +++ b/src/api/page-data.ts @@ -0,0 +1,166 @@ +import type { + PageDataAccessPolicy, + PageDataDatasetSummary, + PageDataLogEntry, + PageDataOpsOverview, +} from '../types'; +import { ApiError, apiFetch } from './core'; + +export async function listOwnerPageDataPolicies(): Promise< + Array<{ + pageId: string; + ownerUserId: string; + accessMode: string; + datasetCount: number; + scopeHash: string; + updatedAt: number; + }> +> { + const result = await apiFetch<{ + data: { + policies: Array<{ + pageId: string; + ownerUserId: string; + accessMode: string; + datasetCount: number; + scopeHash: string; + updatedAt: number; + }>; + }; + }>('/page-data/policies'); + return result.data.policies; +} + +export async function listPageDataDatasets(): Promise { + const result = await apiFetch<{ data: { datasets: PageDataDatasetSummary[] } }>('/page-data'); + return result.data.datasets; +} + +export async function getPageDataPolicy(pageId: string): Promise { + try { + const result = await apiFetch<{ data: { policy: PageDataAccessPolicy } }>( + `/page-data/policies/${encodeURIComponent(pageId)}`, + ); + return result.data.policy; + } catch (error) { + if (error instanceof ApiError && error.status === 404) return null; + throw error; + } +} + +export async function applyPageDataPublishPolicy( + pageId: string, + input: { + datasetName: string; + capabilities?: { + read?: boolean; + insert?: boolean; + update?: boolean; + softDelete?: boolean; + }; + }, +): Promise { + const result = await apiFetch<{ data: { policy: PageDataAccessPolicy } }>( + `/page-data/policies/${encodeURIComponent(pageId)}/apply-publish`, + { + method: 'POST', + body: JSON.stringify({ + datasetName: input.datasetName, + capabilities: input.capabilities ?? {}, + }), + }, + ); + return result.data.policy; +} + +export async function savePageDataPolicy( + pageId: string, + policy: Partial, +): Promise { + const result = await apiFetch<{ data: { policy: PageDataAccessPolicy } }>( + `/page-data/policies/${encodeURIComponent(pageId)}`, + { + method: 'PUT', + body: JSON.stringify(policy), + }, + ); + return result.data.policy; +} + +export function buildPageDataExportUrl(dataset: string, format: 'json' | 'csv' = 'json') { + const params = new URLSearchParams({ format }); + return `/api/page-data/${encodeURIComponent(dataset)}/export?${params.toString()}`; +} + +export async function getPageDataOpsOverview(pageId: string): Promise { + const result = await apiFetch<{ data: PageDataOpsOverview }>( + `/page-data/policies/${encodeURIComponent(pageId)}/ops`, + ); + return result.data; +} + +export async function listPageDataLogs( + pageId: string, + input: { limit?: number; offset?: number } = {}, +): Promise<{ pageId: string; logs: PageDataLogEntry[]; count: number }> { + const params = new URLSearchParams(); + if (input.limit != null) params.set('limit', String(input.limit)); + if (input.offset != null) params.set('offset', String(input.offset)); + const query = params.toString(); + const result = await apiFetch<{ data: { pageId: string; logs: PageDataLogEntry[]; count: number } }>( + `/page-data/policies/${encodeURIComponent(pageId)}/logs${query ? `?${query}` : ''}`, + ); + return result.data; +} + +export async function revokePageDataTokens( + pageId: string, + input: { revokeAll?: boolean; token?: string }, +): Promise<{ pageId: string; revokedCount: number; revokeAll: boolean }> { + const result = await apiFetch<{ data: { pageId: string; revokedCount: number; revokeAll: boolean } }>( + `/page-data/policies/${encodeURIComponent(pageId)}/tokens/revoke`, + { + method: 'POST', + body: JSON.stringify({ + revokeAll: Boolean(input.revokeAll), + token: input.token, + }), + }, + ); + return result.data; +} + +export async function resetPageDataPassword( + pageId: string, + password: string, +): Promise<{ pageId: string; passwordReset: boolean; revokedSessions: number }> { + const result = await apiFetch<{ + data: { pageId: string; passwordReset: boolean; revokedSessions: number }; + }>(`/page-data/policies/${encodeURIComponent(pageId)}/password/reset`, { + method: 'POST', + body: JSON.stringify({ password }), + }); + return result.data; +} + +export async function closePageDataDataset( + pageId: string, + dataset: string, +): Promise<{ pageId: string; dataset: string; closed: boolean }> { + const result = await apiFetch<{ data: { pageId: string; dataset: string; closed: boolean } }>( + `/page-data/policies/${encodeURIComponent(pageId)}/datasets/${encodeURIComponent(dataset)}/close`, + { method: 'POST' }, + ); + return result.data; +} + +export async function restorePageDataRow( + dataset: string, + rowId: number | string, +): Promise<{ restored: boolean; row: Record }> { + const result = await apiFetch<{ data: { restored: boolean; row: Record } }>( + `/page-data/${encodeURIComponent(dataset)}/rows/${encodeURIComponent(String(rowId))}/restore`, + { method: 'POST' }, + ); + return result.data; +}