feat(portal): harden readiness and explain workforce KPI

This commit is contained in:
igor04091968
2026-06-07 14:12:32 +03:00
parent 7df665a457
commit 07dfb95b6b
9 changed files with 2458 additions and 47 deletions
@@ -766,6 +766,67 @@
}
}
}
},
"/workforce/kpi/explain": {
"get": {
"tags": [
"workforce"
],
"summary": "Rule-based Workforce KPI explanation",
"parameters": [
{
"name": "date",
"in": "query",
"required": false,
"schema": {
"type": "string",
"format": "date"
}
},
{
"name": "department",
"in": "query",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "owner",
"in": "query",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "role",
"in": "query",
"required": false,
"schema": {
"$ref": "#/components/schemas/PortalRole"
}
}
],
"responses": {
"200": {
"description": "Explainable Workforce KPI payload",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WorkforceKpiExplain"
}
}
}
},
"400": {
"description": "Query limits rejected"
},
"403": {
"description": "Role denied"
}
}
}
}
},
"components": {
@@ -1172,6 +1233,118 @@
}
},
"additionalProperties": true
},
"WorkforceKpiExplainFactor": {
"type": "object",
"required": [
"name",
"label",
"impact",
"explanation"
],
"properties": {
"name": {
"type": "string"
},
"label": {
"type": "string"
},
"impact": {
"type": "string"
},
"explanation": {
"type": "string"
}
},
"additionalProperties": true
},
"WorkforceKpiExplain": {
"type": "object",
"required": [
"ok",
"kpi_score",
"confidence",
"coverage",
"factors",
"top_applications",
"warnings",
"recommendations"
],
"properties": {
"ok": {
"type": "boolean"
},
"role_context": {
"$ref": "#/components/schemas/RoleContext"
},
"scope": {
"type": "string"
},
"kpi_score": {
"type": "integer",
"minimum": 0,
"maximum": 100
},
"kpi_status": {
"type": "string"
},
"confidence": {
"type": "string",
"enum": [
"high",
"medium",
"low"
]
},
"coverage": {
"type": "object",
"properties": {
"agent_coverage_percent": {
"type": "integer",
"minimum": 0,
"maximum": 100
},
"data_freshness": {
"type": "string"
},
"missing_sources": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": true
},
"factors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WorkforceKpiExplainFactor"
}
},
"top_applications": {
"type": "array",
"items": {
"$ref": "#/components/schemas/JsonObject"
}
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"recommendations": {
"type": "array",
"items": {
"type": "string"
}
},
"model": {
"$ref": "#/components/schemas/JsonObject"
}
},
"additionalProperties": true
}
}
}
@@ -88,6 +88,35 @@ export interface AgentCoverageSla {
[key: string]: unknown;
}
export interface WorkforceKpiExplainFactor {
name: string;
label: string;
impact: string;
explanation: string;
[key: string]: unknown;
}
export interface WorkforceKpiExplainResponse {
ok: boolean;
role_context?: RoleContext;
scope?: "aggregate" | string;
kpi_score: number;
kpi_status?: string;
confidence: "high" | "medium" | "low" | string;
coverage: {
agent_coverage_percent: number;
data_freshness: "fresh" | "stale" | "missing" | string;
missing_sources: string[];
[key: string]: unknown;
};
factors: WorkforceKpiExplainFactor[];
top_applications: JsonObject[];
warnings: string[];
recommendations: string[];
model?: JsonObject;
[key: string]: unknown;
}
export interface BusinessRiskItem {
department?: string;
trust_score?: number;
@@ -263,4 +292,10 @@ export interface DetMirPortalApi {
getReadinessBundle(): Promise<JsonObject>;
verifyReadiness(): Promise<JsonObject>;
getWorkforcePolicyExplain(options?: { anonymize?: boolean }): Promise<JsonObject>;
getWorkforceKpiExplain(options?: {
date?: string;
department?: string;
owner?: string;
role?: PortalRole;
}): Promise<WorkforceKpiExplainResponse>;
}