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

240 lines
5.9 KiB
TypeScript

import { apiFetch, type ApiSettings } from "@govoplan/core-webui";
export type OpsCheck = {
id: string;
label: string;
state: "ok" | "warning" | "error" | string;
detail: string;
readiness_critical?: boolean;
metrics?: Record<string, unknown>;
};
export type OpsDeploymentProfile = {
id: string;
name: string;
current: boolean;
components: string[];
fit: string;
};
export type OpsSizingAssumption = {
area: string;
baseline: string;
scale_trigger: string;
operator_note: string;
};
export type OpsGovernanceModule = {
module_id: string;
name: string;
version: string;
permission_count: number;
role_template_count: number;
capability_count: number;
policy_count: number;
documentation_count: number;
documentation_provider_count: number;
access_control_count: number;
search_provider_count: number;
migration_managed: boolean;
architecture?: {
contract_version: string;
layer: string;
kind: string;
maturity: string;
known_limits: string[];
supported_authority_modes: string[];
owned_concepts: string[];
non_owned_concepts: string[];
evidence: Array<{ kind: string; reference: string; summary: string }>;
} | null;
external_provider_count: number;
external_providers: Array<{
id: string;
label: string;
maturity: string;
authority_modes: string[];
operations: string[];
behavior: { outage?: 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;
last_success_at?: string | null;
bindings?: Array<{
binding_ref: string;
authority_mode: string;
active: boolean;
health: string;
freshness: string;
conflict: string;
recovery: string;
}>;
} | null;
}>;
};
export type OpsRuntimeNode = {
node_id: string;
incarnation: string;
role: string;
software_version: string;
composition_hash: string;
queues: string[];
state: "active" | "draining" | "stopped" | string;
started_at: string;
last_heartbeat_at: string;
drain_requested_at?: string | null;
drain_reason?: string | null;
stopped_at?: string | null;
stale: boolean;
};
export type OpsRecoveryOperation = {
id: string;
module_id: string;
operation_type: string;
resource_type?: string | null;
resource_id?: string | null;
mode: string;
status: string;
checkpoint_count: number;
evidence_head_sha256?: string | null;
failure_summary?: string | null;
updated_at: string;
};
export type OpsRuntimeCluster = {
available: boolean;
detail: string;
installation_id?: string;
state_profile: string;
expected?: { api: number; worker: number };
active?: { api: number; worker: number };
composition?: {
expected_hash?: string | null;
active_hashes: string[];
unexpected_nodes: string[];
skewed: boolean;
};
software_versions?: {
active: string[];
skewed: boolean;
};
queues?: {
expected: string[];
active: string[];
missing: string[];
worker_pools: string[];
};
nodes: OpsRuntimeNode[];
recovery: {
operations: OpsRecoveryOperation[];
requires_attention: number;
};
};
export type OpsStatus = {
summary: {
app_env: string;
active_profile: string;
module_count: number;
celery_enabled: boolean;
celery_queues: string[];
redis_url: string;
maintenance_mode: {
enabled: boolean;
message?: string | null;
};
database_url: string;
database_connection_peak?: number | null;
database_connection_available?: number | null;
file_storage_backend: string;
worker_metrics: {
workers?: number;
active_tasks?: number;
expected_queues?: string[];
active_queues?: string[];
missing_queues?: string[];
queue_depths?: Record<string, number>;
};
operational_probe_count: number;
runtime_node_count: number;
recovery_required_count: number;
};
readiness: {
ready: boolean;
profile: string;
blockers: Array<{
id: string;
label: string;
state: string;
detail: string;
}>;
};
checks: OpsCheck[];
governance: {
summary: {
module_count: number;
permission_count: number;
role_template_count: number;
capability_count: number;
policy_count: number;
documented_module_count: number;
access_control_count: number;
search_provider_count: number;
migration_module_count: number;
architecture_declared_module_count: number;
external_provider_count: number;
configured_external_provider_count: number;
provider_attention_count: number;
supported_module_count: number;
};
modules: OpsGovernanceModule[];
};
deployment_profiles: OpsDeploymentProfile[];
sizing: OpsSizingAssumption[];
runtime_cluster: OpsRuntimeCluster;
};
export function fetchOpsStatus(settings: ApiSettings): Promise<OpsStatus> {
return apiFetch(settings, "/api/v1/ops/status");
}
export function runOpsChecks(settings: ApiSettings): Promise<OpsStatus> {
return apiFetch(settings, "/api/v1/ops/checks/run", { method: "POST" });
}
export function drainRuntimeNode(
settings: ApiSettings,
nodeId: string,
reason = "operator request"
): Promise<{ node_id: string; state: string; drain_reason: string }> {
return apiFetch(
settings,
`/api/v1/ops/runtime/nodes/${encodeURIComponent(nodeId)}/drain`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ reason })
}
);
}
export function cancelRuntimeNodeDrain(
settings: ApiSettings,
nodeId: string
): Promise<{ node_id: string; state: string }> {
return apiFetch(
settings,
`/api/v1/ops/runtime/nodes/${encodeURIComponent(nodeId)}/drain`,
{ method: "DELETE" }
);
}