395 lines
11 KiB
TypeScript
395 lines
11 KiB
TypeScript
import { apiFetch, type ApiSettings } from "@govoplan/core-webui";
|
|
|
|
export type DocsModuleArchitecture = {
|
|
contract_version: string;
|
|
layer: string;
|
|
kind: string;
|
|
maturity: string;
|
|
evidence: Array<{ kind: string; reference: string; summary: string }>;
|
|
known_limits: string[];
|
|
supported_authority_modes: string[];
|
|
owned_concepts: string[];
|
|
non_owned_concepts: string[];
|
|
reference_packages: string[];
|
|
target_tested_providers: string[];
|
|
documentation: Record<string, string[]>;
|
|
};
|
|
|
|
export type DocsExternalProvider = {
|
|
id: string;
|
|
module_id: string;
|
|
label: string;
|
|
maturity: string;
|
|
operations: string[];
|
|
authority_modes: string[];
|
|
behavior?: Record<string, unknown>;
|
|
known_outage_behavior?: string | null;
|
|
runtime_state?: {
|
|
configured?: boolean;
|
|
active?: boolean;
|
|
authority_mode?: string | null;
|
|
authority_modes?: string[];
|
|
health?: string;
|
|
freshness?: string;
|
|
conflict?: string;
|
|
recovery?: string;
|
|
observed_at?: string;
|
|
} | null;
|
|
};
|
|
|
|
export type DocsModule = {
|
|
id: string;
|
|
name: string;
|
|
version: string;
|
|
dependencies: string[];
|
|
optional_dependencies: string[];
|
|
permission_count: number;
|
|
role_template_count: number;
|
|
nav_count: number;
|
|
route_count: number;
|
|
frontend_package?: string | null;
|
|
backend_route_contributed: boolean;
|
|
migration_module_id?: string | null;
|
|
capabilities: string[];
|
|
documentation_count: number;
|
|
documentation_provider_count: number;
|
|
architecture?: DocsModuleArchitecture | null;
|
|
external_provider_count: number;
|
|
external_providers: DocsExternalProvider[];
|
|
};
|
|
|
|
export type DocsRoute = {
|
|
module_id: string;
|
|
path: string;
|
|
label: string;
|
|
icon?: string | null;
|
|
section?: string | null;
|
|
source: string;
|
|
component?: string | null;
|
|
required_all: string[];
|
|
required_any: string[];
|
|
order: number;
|
|
visible: boolean;
|
|
reason: string;
|
|
};
|
|
|
|
export type DocsPermission = {
|
|
scope: string;
|
|
label: string;
|
|
description: string;
|
|
category: string;
|
|
level: "system" | "tenant";
|
|
module_id: string;
|
|
resource: string;
|
|
action: string;
|
|
deprecated: boolean;
|
|
granted: boolean;
|
|
};
|
|
|
|
export type DocsOptionalModuleEvidence = {
|
|
module_id: string;
|
|
source_module_id: string;
|
|
status: "installed" | "not_installed" | string;
|
|
reason: string;
|
|
};
|
|
|
|
export type DocsSource = {
|
|
id: string;
|
|
kind: string;
|
|
owner_module_id: string;
|
|
label: string;
|
|
state: "configured" | "disabled" | "unavailable";
|
|
state_reason?: string | null;
|
|
inspection_url: string;
|
|
provenance: {
|
|
source: string;
|
|
version?: string | null;
|
|
revision?: string | null;
|
|
published_at?: string | null;
|
|
checksum?: string | null;
|
|
};
|
|
};
|
|
|
|
export type DocsSourceDetail = DocsSource & {
|
|
visibility: {
|
|
documentation_types: string[];
|
|
required_modules: string[];
|
|
any_modules: string[];
|
|
missing_modules: string[];
|
|
required_capabilities: string[];
|
|
required_scopes: string[];
|
|
any_scopes: string[];
|
|
configuration_keys: string[];
|
|
};
|
|
inspection: Record<string, unknown>;
|
|
};
|
|
|
|
export type DocsDocumentationCondition = {
|
|
required_modules: string[];
|
|
any_modules: string[];
|
|
missing_modules: string[];
|
|
required_capabilities: string[];
|
|
required_scopes: string[];
|
|
any_scopes: string[];
|
|
configuration_keys: string[];
|
|
};
|
|
|
|
export type DocsDocumentationLink = {
|
|
label: string;
|
|
href: string;
|
|
kind: string;
|
|
};
|
|
|
|
export type DocsTopicKind = "workflow" | "reference" | "pattern" | "system" | string;
|
|
|
|
export type DocsDocumentationTopic = {
|
|
id: string;
|
|
source_module_id: string;
|
|
kind: DocsTopicKind;
|
|
anchor_id: string;
|
|
title: string;
|
|
summary: string;
|
|
body: string;
|
|
layer: "always" | "configured" | "available" | "evidence" | string;
|
|
target_layer: string;
|
|
documentation_types: Array<"admin" | "user" | string>;
|
|
active: boolean;
|
|
reason: string;
|
|
blockers: {
|
|
modules: string[];
|
|
capabilities: string[];
|
|
scopes: string[];
|
|
configuration: string[];
|
|
};
|
|
audience: string[];
|
|
order: number;
|
|
i18n_key: string;
|
|
locale: string;
|
|
translation_locale: string;
|
|
structured_translation_locale: string;
|
|
structured_translation_version?: string | null;
|
|
version: {
|
|
resolved: string;
|
|
minimum?: string | null;
|
|
maximum_exclusive?: string | null;
|
|
range: string;
|
|
fallback: "unversioned" | "matching_range" | string;
|
|
};
|
|
conditions: DocsDocumentationCondition[];
|
|
links: DocsDocumentationLink[];
|
|
related_modules: string[];
|
|
unlocks: string[];
|
|
configuration_keys: string[];
|
|
configuration_states: Array<{
|
|
key: string;
|
|
state: "enabled" | "disabled" | "inherited" | "unavailable";
|
|
source?: string | null;
|
|
reason?: string | null;
|
|
}>;
|
|
metadata: Record<string, unknown>;
|
|
};
|
|
|
|
export type DocsContext = {
|
|
versions: {
|
|
mode: "installed" | "selected";
|
|
selected_version?: string | null;
|
|
status: "installed" | "stable" | "older_supported" | "unsupported" | string;
|
|
latest_version?: string | null;
|
|
stable_version?: string | null;
|
|
supported_versions: string[];
|
|
installed_versions: Record<string, string>;
|
|
fallback_policy: string;
|
|
};
|
|
actor: {
|
|
tenant_id?: string;
|
|
user_id?: string;
|
|
scope_count?: number;
|
|
documentation_type: "admin" | "user";
|
|
locale: string;
|
|
available_documentation_types: Array<"admin" | "user">;
|
|
};
|
|
summary: {
|
|
module_count: number;
|
|
architecture_declared_module_count: number;
|
|
external_provider_count: number;
|
|
visible_route_count: number;
|
|
available_route_count: number;
|
|
permission_count: number;
|
|
granted_permission_count: number;
|
|
optional_module_count: number;
|
|
documentation_topic_count: number;
|
|
configured_documentation_topic_count: number;
|
|
workflow_topic_count: number;
|
|
reference_topic_count: number;
|
|
pattern_topic_count: number;
|
|
system_topic_count: number;
|
|
};
|
|
topic_groups: {
|
|
workflow: DocsDocumentationTopic[];
|
|
reference: DocsDocumentationTopic[];
|
|
pattern: DocsDocumentationTopic[];
|
|
system: DocsDocumentationTopic[];
|
|
[kind: string]: DocsDocumentationTopic[];
|
|
};
|
|
layers: {
|
|
always: {
|
|
documentation: DocsDocumentationTopic[];
|
|
};
|
|
configured: {
|
|
modules: DocsModule[];
|
|
routes: DocsRoute[];
|
|
permissions: DocsPermission[];
|
|
documentation: DocsDocumentationTopic[];
|
|
};
|
|
available: {
|
|
routes: DocsRoute[];
|
|
permissions: DocsPermission[];
|
|
documentation: DocsDocumentationTopic[];
|
|
};
|
|
evidence: {
|
|
optional_modules: DocsOptionalModuleEvidence[];
|
|
sources: DocsSource[];
|
|
documentation: DocsDocumentationTopic[];
|
|
};
|
|
};
|
|
};
|
|
|
|
export function fetchDocsContext(settings: ApiSettings, options: { documentationType?: "admin" | "user"; locale?: string; version?: string | null } = {}): Promise<DocsContext> {
|
|
const params = new URLSearchParams();
|
|
if (options.documentationType) params.set("type", options.documentationType);
|
|
if (options.locale) params.set("locale", options.locale);
|
|
if (options.version) params.set("version", options.version);
|
|
const query = params.toString();
|
|
return apiFetch(settings, `/api/v1/docs/context${query ? `?${query}` : ""}`);
|
|
}
|
|
|
|
export function fetchDocsSource(
|
|
settings: ApiSettings,
|
|
sourceId: string,
|
|
options: { documentationType?: "admin" | "user"; locale?: string } = {}
|
|
): Promise<DocsSourceDetail> {
|
|
const params = new URLSearchParams();
|
|
if (options.documentationType) params.set("type", options.documentationType);
|
|
if (options.locale) params.set("locale", options.locale);
|
|
const query = params.toString();
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/docs/sources/${encodeURIComponent(sourceId)}${query ? `?${query}` : ""}`
|
|
);
|
|
}
|
|
|
|
export type SemanticSubjectReference = {
|
|
module_id: string;
|
|
tenant_id: string;
|
|
subject_kind: string;
|
|
subject_id: string;
|
|
anchor?: { kind: string; id: string } | null;
|
|
observed_revision?: string | null;
|
|
observed_fingerprint?: string | null;
|
|
};
|
|
|
|
export type SemanticSubjectDescriptor = {
|
|
reference: SemanticSubjectReference;
|
|
labels: Record<string, string>;
|
|
descriptions: Record<string, string>;
|
|
route?: string | null;
|
|
route_anchor?: string | null;
|
|
};
|
|
|
|
export type SemanticContent = {
|
|
title: string;
|
|
summary: string;
|
|
body: string;
|
|
meaning: string;
|
|
intended_use: string;
|
|
non_intended_use: string;
|
|
examples: string[];
|
|
owner_account_id: string | null;
|
|
steward_account_id: string | null;
|
|
audience: string[];
|
|
classification: "internal" | "restricted";
|
|
links: Array<{ label: string; href: string }>;
|
|
};
|
|
|
|
export type SemanticEntry = {
|
|
id: string;
|
|
subject: SemanticSubjectReference;
|
|
subject_resolution: {
|
|
availability: "available" | "changed" | "superseded" | "missing" | "temporarily_unavailable";
|
|
reason_code?: string | null;
|
|
};
|
|
locale: string;
|
|
requested_locale: string;
|
|
locale_fallback: boolean;
|
|
lifecycle_state: "draft" | "published" | "superseded" | "retired";
|
|
pending_draft: boolean;
|
|
current_revision: number;
|
|
published_revision?: number | null;
|
|
content: SemanticContent;
|
|
content_redacted: boolean;
|
|
updated_at: string;
|
|
};
|
|
|
|
export async function fetchSemanticSubjects(
|
|
settings: ApiSettings,
|
|
query = ""
|
|
): Promise<SemanticSubjectDescriptor[]> {
|
|
const params = new URLSearchParams({ query });
|
|
const response = await apiFetch<{ providers: Array<{ subjects: SemanticSubjectDescriptor[] }> }>(
|
|
settings,
|
|
`/api/v1/docs/semantic/subjects?${params}`
|
|
);
|
|
return response.providers.flatMap((provider) => provider.subjects);
|
|
}
|
|
|
|
export async function fetchSemanticEntries(
|
|
settings: ApiSettings,
|
|
locale: string,
|
|
includeDrafts = true
|
|
): Promise<SemanticEntry[]> {
|
|
const params = new URLSearchParams({ locale, include_drafts: String(includeDrafts) });
|
|
const response = await apiFetch<{ items: SemanticEntry[] }>(
|
|
settings,
|
|
`/api/v1/docs/semantic/entries?${params}`
|
|
);
|
|
return response.items;
|
|
}
|
|
|
|
export function createSemanticEntry(
|
|
settings: ApiSettings,
|
|
payload: { subject: SemanticSubjectReference; locale: string; content: SemanticContent; change_reason: string }
|
|
): Promise<SemanticEntry> {
|
|
return apiFetch(settings, "/api/v1/docs/semantic/entries", {
|
|
method: "POST",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export function updateSemanticEntry(
|
|
settings: ApiSettings,
|
|
entryId: string,
|
|
payload: { expected_revision: number; content: SemanticContent; change_reason: string }
|
|
): Promise<SemanticEntry> {
|
|
return apiFetch(settings, `/api/v1/docs/semantic/entries/${encodeURIComponent(entryId)}`, {
|
|
method: "PUT",
|
|
body: JSON.stringify(payload)
|
|
});
|
|
}
|
|
|
|
export function transitionSemanticEntry(
|
|
settings: ApiSettings,
|
|
entryId: string,
|
|
transition: "publish" | "retire",
|
|
expectedRevision: number,
|
|
changeReason: string
|
|
): Promise<SemanticEntry> {
|
|
return apiFetch(
|
|
settings,
|
|
`/api/v1/docs/semantic/entries/${encodeURIComponent(entryId)}/${transition}`,
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify({ expected_revision: expectedRevision, change_reason: changeReason })
|
|
}
|
|
);
|
|
}
|