Files
govoplan-search/webui/src/api/search.ts
T

207 lines
4.6 KiB
TypeScript

import {
apiFetch,
apiPath,
type ApiSettings
} from "@govoplan/core-webui";
export type SearchExternalReference = {
system: string;
object_type: string;
object_id: string;
maturity: string;
connector_id?: string | null;
canonical_url?: string | null;
};
export type SearchResult = {
provider_id: string;
module_id: string;
resource_type: string;
resource_id: string;
title: string;
summary?: string | null;
url: string;
score: number;
highlights: string[];
breadcrumbs: string[];
external_reference?: SearchExternalReference | null;
metadata: Record<string, unknown>;
source_revision?: string | null;
provenance: Record<string, unknown>;
};
export type SearchResponse = {
query: string;
results: SearchResult[];
diagnostics: Array<{
provider_id: string;
status: "unavailable";
message: string;
}>;
next_cursor?: string | null;
has_more: boolean;
};
export type SearchProvider = {
id: string;
module_id: string;
resource_types: string[];
order: number;
};
export type SearchResourceType = {
provider_id: string;
module_id: string;
resource_type: string;
label: string;
order: number;
};
export type SearchProviderListResponse = {
providers: SearchProvider[];
resources: SearchResourceType[];
};
export type SearchIndexState = {
provider_id: string;
module_id: string;
resource_type: string;
index_version: number;
status: string;
checkpoint_cursor?: string | null;
high_watermark?: string | null;
last_change_cursor?: string | null;
indexed_documents: number;
rejected_documents: number;
rebuild_started_at?: string | null;
rebuild_completed_at?: string | null;
last_success_at?: string | null;
last_error?: string | null;
};
export type SearchDiagnostics = {
backend: string;
trigram_available: boolean;
queue: Record<string, number>;
queue_oldest_age_seconds?: number | null;
states: SearchIndexState[];
};
export type SearchChangeDispatch = {
selected: number;
applied: number;
retrying: number;
quarantined: number;
};
export type SearchModuleReconcile = {
disabled_documents: number;
enabled_documents: number;
};
export type SearchRequest = {
query: string;
modules?: string[];
resourceTypes?: string[];
contextKind?: "global" | "module" | "resource";
contextId?: string;
limit?: number;
offset?: number;
cursor?: string;
language?: string;
};
export function search(
settings: ApiSettings,
request: SearchRequest,
signal?: AbortSignal
): Promise<SearchResponse> {
return apiFetch<SearchResponse>(
settings,
apiPath("/api/v1/search", {
q: request.query,
module: request.modules,
resource_type: request.resourceTypes,
context_kind: request.contextKind,
context_id: request.contextId,
limit: request.limit,
offset: request.offset,
cursor: request.cursor,
language: request.language
}),
{ signal }
);
}
export function listSearchProviders(
settings: ApiSettings,
signal?: AbortSignal
): Promise<SearchProviderListResponse> {
return apiFetch<SearchProviderListResponse>(
settings,
"/api/v1/search/providers",
{ signal }
);
}
export function getSearchDiagnostics(
settings: ApiSettings,
signal?: AbortSignal
): Promise<SearchDiagnostics> {
return apiFetch<SearchDiagnostics>(
settings,
"/api/v1/search/admin/diagnostics",
{ signal }
);
}
export function reconcileSearchModules(
settings: ApiSettings
): Promise<SearchModuleReconcile> {
return apiFetch<SearchModuleReconcile>(
settings,
"/api/v1/search/admin/reconcile-modules",
{ method: "POST" }
);
}
export function processSearchChanges(
settings: ApiSettings,
limit = 100
): Promise<SearchChangeDispatch> {
return apiFetch<SearchChangeDispatch>(
settings,
apiPath("/api/v1/search/admin/changes/process", { limit }),
{ method: "POST" }
);
}
export function startSearchRebuild(
settings: ApiSettings,
providerId: string,
resourceType: string
): Promise<{ state: SearchIndexState }> {
return apiFetch<{ state: SearchIndexState }>(
settings,
`/api/v1/search/admin/rebuilds/${encodeURIComponent(providerId)}/${encodeURIComponent(resourceType)}/start`,
{ method: "POST" }
);
}
export function continueSearchRebuild(
settings: ApiSettings,
providerId: string,
resourceType: string,
limit = 100
): Promise<{ state: SearchIndexState }> {
return apiFetch<{ state: SearchIndexState }>(
settings,
apiPath(
`/api/v1/search/admin/rebuilds/${encodeURIComponent(providerId)}/${encodeURIComponent(resourceType)}/continue`,
{ limit }
),
{ method: "POST" }
);
}