@absolutejs/voice 0.0.22-beta.376 → 0.0.22-beta.378
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/client/index.js +88 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +120 -0
- package/dist/productionReadiness.d.ts +17 -0
- package/dist/proofTrends.d.ts +10 -0
- package/dist/react/index.js +88 -0
- package/dist/vue/index.js +88 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1547,6 +1547,20 @@ const recoveryJobs = createVoiceSQLiteRealCallProfileRecoveryJobStore({
|
|
|
1547
1547
|
|
|
1548
1548
|
Recovery routes expose recent persisted jobs at `${path}/actions/jobs`. Stores can implement `list({ limit, actionId, status })`; the bundled memory and SQLite stores both support it.
|
|
1549
1549
|
|
|
1550
|
+
Use `buildVoiceRealCallProfileRecoveryJobHistoryCheck(...)` in production readiness to prove recovery jobs are persisted and inspectable:
|
|
1551
|
+
|
|
1552
|
+
```ts
|
|
1553
|
+
additionalChecks: async () => [
|
|
1554
|
+
await buildVoiceRealCallProfileRecoveryJobHistoryCheck(recoveryJobs)
|
|
1555
|
+
];
|
|
1556
|
+
```
|
|
1557
|
+
|
|
1558
|
+
Use `buildVoiceReadinessRecoveryActions(...)` when a UI or API needs a compact plan of actions attached to failed or warning readiness checks:
|
|
1559
|
+
|
|
1560
|
+
```ts
|
|
1561
|
+
const recoveryPlan = buildVoiceReadinessRecoveryActions(readinessReport);
|
|
1562
|
+
```
|
|
1563
|
+
|
|
1550
1564
|
Use `createVoiceProfileTraceTagger(...)` when the app already has a trace store and needs every appended trace to carry a benchmark profile label. It wraps any `VoiceTraceEventStore`, preserves the underlying store behavior, and adds `profileId`/`benchmarkProfileId` metadata and payload fields that real-call profile history can ingest later.
|
|
1551
1565
|
|
|
1552
1566
|
```ts
|
package/dist/client/index.js
CHANGED
|
@@ -4760,6 +4760,94 @@ var buildVoiceRealCallProfileReadinessCheck = (report, options = {}) => {
|
|
|
4760
4760
|
value: `${String(report.defaults.summary.actionableProfiles)}/${String(report.summary.profileCount)} actionable`
|
|
4761
4761
|
};
|
|
4762
4762
|
};
|
|
4763
|
+
var buildVoiceRealCallProfileRecoveryJobHistoryCheck = async (store, options = {}) => {
|
|
4764
|
+
const href = options.href ?? "/voice/real-call-profile-recovery";
|
|
4765
|
+
const sourceHref = options.sourceHref ?? "/api/voice/real-call-profile-history/actions/jobs";
|
|
4766
|
+
const minCompletedJobs = options.minCompletedJobs ?? 1;
|
|
4767
|
+
const label = options.label ?? "Real-call recovery job history";
|
|
4768
|
+
if (!store?.list) {
|
|
4769
|
+
return {
|
|
4770
|
+
actions: [
|
|
4771
|
+
{
|
|
4772
|
+
description: "Configure a recovery job store with list support so operators can inspect proof repair history.",
|
|
4773
|
+
href,
|
|
4774
|
+
label: "Configure recovery job history"
|
|
4775
|
+
}
|
|
4776
|
+
],
|
|
4777
|
+
detail: "No real-call profile recovery job store with list support is configured.",
|
|
4778
|
+
gateExplanation: {
|
|
4779
|
+
evidenceHref: sourceHref,
|
|
4780
|
+
observed: "missing",
|
|
4781
|
+
remediation: "Use the bundled memory or SQLite recovery job store, or implement list() on the custom store.",
|
|
4782
|
+
sourceHref,
|
|
4783
|
+
threshold: "list support",
|
|
4784
|
+
thresholdLabel: "Inspectable recovery jobs",
|
|
4785
|
+
unit: "status"
|
|
4786
|
+
},
|
|
4787
|
+
href,
|
|
4788
|
+
label,
|
|
4789
|
+
status: "fail",
|
|
4790
|
+
value: "missing"
|
|
4791
|
+
};
|
|
4792
|
+
}
|
|
4793
|
+
const jobs = await store.list({ limit: 50 });
|
|
4794
|
+
const now = Date.now();
|
|
4795
|
+
const recentJobs = options.maxAgeMs === undefined ? jobs : jobs.filter((job) => now - Date.parse(job.updatedAt) <= options.maxAgeMs);
|
|
4796
|
+
const completedJobs = recentJobs.filter((job) => job.status === "pass" || job.status === "fail");
|
|
4797
|
+
const failedJobs = recentJobs.filter((job) => job.status === "fail");
|
|
4798
|
+
const runningJobs = recentJobs.filter((job) => job.status === "queued" || job.status === "running");
|
|
4799
|
+
const issues = [];
|
|
4800
|
+
const warnings = [];
|
|
4801
|
+
if (completedJobs.length < minCompletedJobs) {
|
|
4802
|
+
issues.push(`Expected at least ${String(minCompletedJobs)} completed recovery job(s), found ${String(completedJobs.length)}.`);
|
|
4803
|
+
}
|
|
4804
|
+
if (!options.allowFailedJobs && failedJobs.length > 0) {
|
|
4805
|
+
issues.push(`${String(failedJobs.length)} recent recovery job(s) failed.`);
|
|
4806
|
+
}
|
|
4807
|
+
if (runningJobs.length > 0) {
|
|
4808
|
+
const message = `${String(runningJobs.length)} recovery job(s) are still queued or running.`;
|
|
4809
|
+
if (options.failOnRunningJobs) {
|
|
4810
|
+
issues.push(message);
|
|
4811
|
+
} else {
|
|
4812
|
+
warnings.push(message);
|
|
4813
|
+
}
|
|
4814
|
+
}
|
|
4815
|
+
const status = issues.length > 0 ? "fail" : warnings.length > 0 ? "warn" : "pass";
|
|
4816
|
+
const detail = status === "pass" ? `${String(completedJobs.length)} completed recovery job(s), ${String(failedJobs.length)} failed, ${String(runningJobs.length)} running.` : [...issues, ...warnings].join(" ");
|
|
4817
|
+
return {
|
|
4818
|
+
actions: [
|
|
4819
|
+
{
|
|
4820
|
+
description: "Open the recovery job UI and run or inspect proof repair jobs.",
|
|
4821
|
+
href,
|
|
4822
|
+
label: "Open recovery job history"
|
|
4823
|
+
},
|
|
4824
|
+
{
|
|
4825
|
+
description: "Open the recovery job history API.",
|
|
4826
|
+
href: sourceHref,
|
|
4827
|
+
label: "Open recovery jobs API"
|
|
4828
|
+
}
|
|
4829
|
+
],
|
|
4830
|
+
detail,
|
|
4831
|
+
gateExplanation: {
|
|
4832
|
+
evidenceHref: sourceHref,
|
|
4833
|
+
observed: completedJobs.length,
|
|
4834
|
+
remediation: "Run a browser or phone recovery proof job and ensure recent recovery jobs complete without failure.",
|
|
4835
|
+
sourceHref,
|
|
4836
|
+
threshold: minCompletedJobs,
|
|
4837
|
+
thresholdLabel: "Minimum completed recovery jobs",
|
|
4838
|
+
unit: "count"
|
|
4839
|
+
},
|
|
4840
|
+
href,
|
|
4841
|
+
label,
|
|
4842
|
+
proofSource: {
|
|
4843
|
+
href: sourceHref,
|
|
4844
|
+
source: "recovery-job-store",
|
|
4845
|
+
sourceLabel: "Real-call recovery jobs"
|
|
4846
|
+
},
|
|
4847
|
+
status,
|
|
4848
|
+
value: `${String(completedJobs.length)} completed / ${String(failedJobs.length)} failed / ${String(runningJobs.length)} running`
|
|
4849
|
+
};
|
|
4850
|
+
};
|
|
4763
4851
|
var resolveVoiceRealCallProfileProviderRoute = (options) => {
|
|
4764
4852
|
const defaults = readRealCallProfileDefaultsReport(options.defaults);
|
|
4765
4853
|
const profile = defaults.profiles.find((item) => item.profileId === options.profileId) ?? defaults.profiles.find((item) => item.status === "pass") ?? defaults.profiles[0];
|
package/dist/index.d.ts
CHANGED
|
@@ -30,12 +30,12 @@ export { assertVoicePlatformCoverage, buildVoicePlatformCoverageSummary, createV
|
|
|
30
30
|
export { assertVoiceCompetitiveCoverage, buildVoiceCompetitiveCoverageReport, createVoiceCompetitiveCoverageRoutes, evaluateVoiceCompetitiveCoverage, renderVoiceCompetitiveCoverageHTML, renderVoiceCompetitiveCoverageMarkdown } from './competitiveCoverage';
|
|
31
31
|
export type { VoiceCompetitiveCoverageAssertionInput, VoiceCompetitiveCoverageAssertionReport, VoiceCompetitiveCoverageIssue, VoiceCompetitiveCoverageLevel, VoiceCompetitiveCoverageReport, VoiceCompetitiveCoverageReportInput, VoiceCompetitiveCoverageRoutesOptions, VoiceCompetitiveCoverageStatus, VoiceCompetitiveCoverageSummary, VoiceCompetitiveDepthLevel, VoiceCompetitiveEvidence, VoiceCompetitiveSurface } from './competitiveCoverage';
|
|
32
32
|
export type { VoicePlatformCoverageAssertionInput, VoicePlatformCoverageAssertionReport, VoicePlatformCoverageEvidence, VoicePlatformCoverageRoutesOptions, VoicePlatformCoverageStatus, VoicePlatformCoverageSummary, VoicePlatformCoverageSummaryInput, VoicePlatformCoverageSurface } from './platformCoverage';
|
|
33
|
-
export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendProfileSummaries, buildVoiceProofTrendRecommendationReport, buildVoiceProofTrendReportFromRealCallProfiles, buildVoiceProofTrendReport, buildVoiceRealCallProfileEvidenceFromTraceEvents, buildVoiceRealCallProfileDefaults, buildVoiceRealCallProfileHistoryReport, buildVoiceRealCallProfileReadinessCheck, buildVoiceRealCallProfileRecoveryActions, createVoiceInMemoryRealCallProfileRecoveryJobStore, createVoiceSQLiteRealCallProfileRecoveryJobStore, createVoiceProofTrendRecommendationRoutes, createVoiceProofTrendRoutes, createVoiceRealCallProfileHistoryRoutes, createVoiceRealCallProfileRecoveryActionRoutes, DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, loadVoiceRealCallProfileEvidenceFromTraceStore, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile, renderVoiceProofTrendRecommendationHTML, renderVoiceProofTrendRecommendationMarkdown, renderVoiceRealCallProfileHistoryHTML, renderVoiceRealCallProfileHistoryMarkdown, resolveVoiceRealCallProfileProviderRoute } from './proofTrends';
|
|
33
|
+
export { assertVoiceProofTrendEvidence, buildEmptyVoiceProofTrendReport, buildVoiceProofTrendProfileSummaries, buildVoiceProofTrendRecommendationReport, buildVoiceProofTrendReportFromRealCallProfiles, buildVoiceProofTrendReport, buildVoiceRealCallProfileEvidenceFromTraceEvents, buildVoiceRealCallProfileDefaults, buildVoiceRealCallProfileHistoryReport, buildVoiceRealCallProfileReadinessCheck, buildVoiceRealCallProfileRecoveryJobHistoryCheck, buildVoiceRealCallProfileRecoveryActions, createVoiceInMemoryRealCallProfileRecoveryJobStore, createVoiceSQLiteRealCallProfileRecoveryJobStore, createVoiceProofTrendRecommendationRoutes, createVoiceProofTrendRoutes, createVoiceRealCallProfileHistoryRoutes, createVoiceRealCallProfileRecoveryActionRoutes, DEFAULT_VOICE_PROOF_TREND_PROFILE_DEFINITIONS, DEFAULT_VOICE_PROOF_TRENDS_MAX_AGE_MS, evaluateVoiceProofTrendEvidence, formatVoiceProofTrendAge, loadVoiceRealCallProfileEvidenceFromTraceStore, normalizeVoiceProofTrendReport, readVoiceProofTrendReportFile, renderVoiceProofTrendRecommendationHTML, renderVoiceProofTrendRecommendationMarkdown, renderVoiceRealCallProfileHistoryHTML, renderVoiceRealCallProfileHistoryMarkdown, resolveVoiceRealCallProfileProviderRoute } from './proofTrends';
|
|
34
34
|
export { applyVoiceProfileSwitchGuard, buildVoiceProfileSwitchReadinessReport, buildVoiceProfileSwitchLiveDecisionReport, createVoiceProfileSwitchLiveDecisionRoutes, createVoiceProfileSwitchPolicyProofRoutes, createVoiceProfileSwitchReadinessRoutes, recommendVoiceProfileSwitch, renderVoiceProfileSwitchLiveDecisionHTML, renderVoiceProfileSwitchPolicyProofHTML, renderVoiceProfileSwitchReadinessHTML, runVoiceProfileSwitchPolicyProof } from './profileSwitchRecommendation';
|
|
35
35
|
export type { VoiceProfileSwitchGuardAction, VoiceProfileSwitchGuardDecision, VoiceProfileSwitchGuardMode, VoiceProfileSwitchGuardOptions, VoiceProfileSwitchObservedSignals, VoiceProfileSwitchLiveDecisionEvidence, VoiceProfileSwitchLiveDecisionReport, VoiceProfileSwitchLiveDecisionReportOptions, VoiceProfileSwitchLiveDecisionRoutesOptions, VoiceProfileSwitchLiveDecisionSession, VoiceProfileSwitchPolicyProofCase, VoiceProfileSwitchPolicyProofCaseResult, VoiceProfileSwitchPolicyProofOptions, VoiceProfileSwitchPolicyProofReport, VoiceProfileSwitchPolicyProofRoutesOptions, VoiceProfileSwitchReadinessIssue, VoiceProfileSwitchReadinessOptions, VoiceProfileSwitchReadinessReport, VoiceProfileSwitchReadinessRoutesOptions, VoiceProfileSwitchReadinessStatus, VoiceProfileSwitchRecommendation, VoiceProfileSwitchRecommendationOptions } from './profileSwitchRecommendation';
|
|
36
36
|
export { buildVoiceProviderDecisionTraceReport, createVoiceProviderDecisionTraceEvent, createVoiceProviderDecisionTraceRoutes, listVoiceProviderDecisionTraces, renderVoiceProviderDecisionTraceHTML, renderVoiceProviderDecisionTraceMarkdown } from './providerDecisionTraces';
|
|
37
37
|
export type { VoiceProviderDecisionStatus, VoiceProviderDecisionSurfaceReport, VoiceProviderDecisionTrace, VoiceProviderDecisionTraceInput, VoiceProviderDecisionTraceIssue, VoiceProviderDecisionTraceReport, VoiceProviderDecisionTraceReportOptions, VoiceProviderDecisionTraceRoutesOptions } from './providerDecisionTraces';
|
|
38
|
-
export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendProfileDefinition, VoiceProofTrendProfileRecommendation, VoiceProofTrendProfileSummaryOptions, VoiceProofTrendProfileSummary, VoiceProofTrendProviderRecommendation, VoiceProofTrendProviderSummary, VoiceProofTrendRecommendation, VoiceProofTrendRecommendationOptions, VoiceProofTrendRecommendationReport, VoiceProofTrendRecommendationRoutesOptions, VoiceProofTrendRecommendationStatus, VoiceProofTrendRecommendationSurface, VoiceProofTrendRealCallProfileEvidence, VoiceProofTrendRealCallProfileReportOptions, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendRuntimeChannelSummary, VoiceProofTrendStatus, VoiceProofTrendSummary, VoiceRealCallProfileDefault, VoiceRealCallProfileDefaultsOptions, VoiceRealCallProfileDefaultsReport, VoiceRealCallProfileHistoryOptions, VoiceRealCallProfileHistoryReport, VoiceRealCallProfileHistoryRoutesOptions, VoiceRealCallProfileProviderRouteOptions, VoiceRealCallProfileReadinessCheckOptions, VoiceRealCallProfileRecoveryActionOptions, VoiceRealCallProfileRecoveryAction, VoiceRealCallProfileRecoveryActionHandler, VoiceRealCallProfileRecoveryActionHandlerInput, VoiceRealCallProfileRecoveryActionId, VoiceRealCallProfileRecoveryActionResult, VoiceRealCallProfileRecoveryActionRoutesOptions, VoiceRealCallProfileRecoveryJob, VoiceRealCallProfileRecoveryJobCreateInput, VoiceRealCallProfileRecoveryJobListOptions, VoiceRealCallProfileRecoveryJobStatus, VoiceRealCallProfileRecoveryJobStore, VoiceRealCallProfileRecoveryJobUpdate, VoiceSQLiteRealCallProfileRecoveryJobStoreOptions, VoiceRealCallProfileTraceEvidenceOptions, VoiceRealCallProfileTraceStoreEvidenceOptions } from './proofTrends';
|
|
38
|
+
export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, VoiceProofTrendCycle, VoiceProofTrendProfileDefinition, VoiceProofTrendProfileRecommendation, VoiceProofTrendProfileSummaryOptions, VoiceProofTrendProfileSummary, VoiceProofTrendProviderRecommendation, VoiceProofTrendProviderSummary, VoiceProofTrendRecommendation, VoiceProofTrendRecommendationOptions, VoiceProofTrendRecommendationReport, VoiceProofTrendRecommendationRoutesOptions, VoiceProofTrendRecommendationStatus, VoiceProofTrendRecommendationSurface, VoiceProofTrendRealCallProfileEvidence, VoiceProofTrendRealCallProfileReportOptions, VoiceProofTrendReport, VoiceProofTrendReportInput, VoiceProofTrendRoutesOptions, VoiceProofTrendRuntimeChannelSummary, VoiceProofTrendStatus, VoiceProofTrendSummary, VoiceRealCallProfileDefault, VoiceRealCallProfileDefaultsOptions, VoiceRealCallProfileDefaultsReport, VoiceRealCallProfileHistoryOptions, VoiceRealCallProfileHistoryReport, VoiceRealCallProfileHistoryRoutesOptions, VoiceRealCallProfileProviderRouteOptions, VoiceRealCallProfileReadinessCheckOptions, VoiceRealCallProfileRecoveryActionOptions, VoiceRealCallProfileRecoveryAction, VoiceRealCallProfileRecoveryActionHandler, VoiceRealCallProfileRecoveryActionHandlerInput, VoiceRealCallProfileRecoveryActionId, VoiceRealCallProfileRecoveryJobHistoryCheckOptions, VoiceRealCallProfileRecoveryActionResult, VoiceRealCallProfileRecoveryActionRoutesOptions, VoiceRealCallProfileRecoveryJob, VoiceRealCallProfileRecoveryJobCreateInput, VoiceRealCallProfileRecoveryJobListOptions, VoiceRealCallProfileRecoveryJobStatus, VoiceRealCallProfileRecoveryJobStore, VoiceRealCallProfileRecoveryJobUpdate, VoiceSQLiteRealCallProfileRecoveryJobStoreOptions, VoiceRealCallProfileTraceEvidenceOptions, VoiceRealCallProfileTraceStoreEvidenceOptions } from './proofTrends';
|
|
39
39
|
export { assertVoiceSloCalibration, buildVoiceSloCalibrationReport, buildVoiceSloReadinessThresholdReport, createVoiceSloReadinessThresholdOptions, createVoiceSloReadinessThresholdRoutes, createVoiceSloThresholdProfile, createVoiceSloCalibrationRoutes, renderVoiceSloCalibrationMarkdown, renderVoiceSloReadinessThresholdHTML, renderVoiceSloReadinessThresholdMarkdown } from './sloCalibration';
|
|
40
40
|
export type { VoiceSloCalibrationMetricKey, VoiceSloCalibrationOptions, VoiceSloCalibrationReport, VoiceSloCalibrationRoutesOptions, VoiceSloCalibrationSample, VoiceSloCalibrationStatus, VoiceSloCalibrationThreshold, VoiceSloCalibrationThresholds, VoiceSloReadinessThresholdReport, VoiceSloReadinessThresholdReportOptions, VoiceSloReadinessThresholdOptions, VoiceSloReadinessThresholdRoutesOptions, VoiceSloThresholdProfile } from './sloCalibration';
|
|
41
41
|
export { assertVoiceLiveOpsControlEvidence, assertVoiceLiveOpsEvidence, buildVoiceLiveOpsControlState, createVoiceLiveOpsController, createVoiceLiveOpsRoutes, createVoiceMemoryLiveOpsControlStore, evaluateVoiceLiveOpsControlEvidence, evaluateVoiceLiveOpsEvidence, getVoiceLiveOpsControlStatus, VOICE_LIVE_OPS_ACTIONS } from './liveOps';
|
|
@@ -72,7 +72,7 @@ export { buildVoiceProviderOrchestrationReport, createVoiceProviderOrchestration
|
|
|
72
72
|
export { assertVoiceProviderRoutingContractEvidence, assertVoiceProviderRoutingContract, evaluateVoiceProviderRoutingContractEvidence, runVoiceProviderRoutingContract } from './providerRoutingContract';
|
|
73
73
|
export { assertVoiceProviderSloEvidence, buildVoiceProviderSloReport, createVoiceProviderSloRoutes, evaluateVoiceProviderSloEvidence, renderVoiceProviderSloHTML, renderVoiceProviderSloMarkdown } from './providerSlo';
|
|
74
74
|
export { createVoicePhoneAgentProductionSmokeHTMLHandler, createVoicePhoneAgentProductionSmokeJSONHandler, createVoicePhoneAgentProductionSmokeRoutes, renderVoicePhoneAgentProductionSmokeHTML, runVoicePhoneAgentProductionSmokeContract } from './phoneAgentProductionSmoke';
|
|
75
|
-
export { assertVoiceProductionReadinessEvidence, buildVoiceProductionReadinessGate, buildVoiceProductionReadinessReport, createVoiceProductionReadinessProofRuntime, createVoiceProductionReadinessRoutes, evaluateVoiceProductionReadinessEvidence, renderVoiceProductionReadinessHTML, summarizeVoiceProductionReadinessGate } from './productionReadiness';
|
|
75
|
+
export { assertVoiceProductionReadinessEvidence, buildVoiceProductionReadinessGate, buildVoiceProductionReadinessReport, buildVoiceReadinessRecoveryActions, createVoiceProductionReadinessProofRuntime, createVoiceProductionReadinessRoutes, evaluateVoiceProductionReadinessEvidence, renderVoiceProductionReadinessHTML, summarizeVoiceProductionReadinessGate } from './productionReadiness';
|
|
76
76
|
export { acknowledgeVoiceMonitorIssue, buildVoiceMonitorRunReport, createVoiceMemoryMonitorIssueStore, createVoiceMemoryMonitorNotifierDeliveryReceiptStore, createVoiceMonitorRoutes, createVoiceMonitorRunner, createVoiceMonitorRunnerRoutes, createVoiceMonitorWebhookNotifier, deliverVoiceMonitorIssueNotifications, muteVoiceMonitorIssue, renderVoiceMonitorHTML, renderVoiceMonitorMarkdown, resolveVoiceMonitorIssue } from './voiceMonitoring';
|
|
77
77
|
export { createVoiceReadinessProfile, recommendVoiceReadinessProfile } from './readinessProfiles';
|
|
78
78
|
export { assertVoiceProviderContractMatrixEvidence, assertVoiceProviderStackEvidence, buildVoiceProviderContractMatrix, createVoiceProviderContractMatrixHTMLHandler, createVoiceProviderContractMatrixJSONHandler, createVoiceProviderContractMatrixPreset, createVoiceProviderContractMatrixRoutes, evaluateVoiceProviderContractMatrixEvidence, evaluateVoiceProviderStackEvidence, evaluateVoiceProviderStackGaps, renderVoiceProviderContractMatrixHTML, recommendVoiceProviderStack } from './providerStackRecommendations';
|
|
@@ -142,7 +142,7 @@ export type { VoicePhoneAgentCarrier, VoicePhoneAgentCarrierSummary, VoicePhoneA
|
|
|
142
142
|
export type { VoicePhoneAgentProductionSmokeIssue, VoicePhoneAgentProductionSmokeHandlerOptions, VoicePhoneAgentProductionSmokeHTMLHandlerOptions, VoicePhoneAgentProductionSmokeOptions, VoicePhoneAgentProductionSmokeReport, VoicePhoneAgentProductionSmokeRoutesOptions, VoicePhoneAgentProductionSmokeRequirement } from './phoneAgentProductionSmoke';
|
|
143
143
|
export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
|
|
144
144
|
export type { VoiceOpsStatus, VoiceOpsStatusLink, VoiceOpsStatusOptions, VoiceOpsStatusReport, VoiceOpsStatusRoutesOptions } from './opsStatus';
|
|
145
|
-
export type { VoiceProductionReadinessAction, VoiceProductionReadinessAuditOptions, VoiceProductionReadinessAuditRequirement, VoiceProductionReadinessAuditSummary, VoiceProductionReadinessAssertionInput, VoiceProductionReadinessAssertionReport, VoiceProductionReadinessCheck, VoiceProductionReadinessGateExplanation, VoiceProductionReadinessGateIssue, VoiceProductionReadinessGateOptions, VoiceProductionReadinessGateProfile, VoiceProductionReadinessGateProfileSurface, VoiceProductionReadinessGateReport, VoiceProductionReadinessOpsActionHistoryOptions, VoiceProductionReadinessOpsActionHistorySummary, VoiceProductionReadinessOperationsRecordLink, VoiceProductionReadinessOperationsRecordLinks, VoiceProductionReadinessProfileExplanation, VoiceProductionReadinessProfileSurface, VoiceProductionReadinessProofMetadata, VoiceProductionReadinessProofRuntime, VoiceProductionReadinessProofRuntimeOptions, VoiceProductionReadinessProofRuntimeSeedOptions, VoiceProductionReadinessProofSource, VoiceProductionReadinessReport, VoiceProductionReadinessRouteInput, VoiceProductionReadinessRoutesOptions, VoiceProductionReadinessTraceDeliverySummary, VoiceProductionReadinessAuditDeliveryOptions, VoiceProductionReadinessAuditDeliverySummary, VoiceProductionReadinessTraceDeliveryOptions, VoiceProductionReadinessStatus } from './productionReadiness';
|
|
145
|
+
export type { VoiceProductionReadinessAction, VoiceProductionReadinessAuditOptions, VoiceProductionReadinessAuditRequirement, VoiceProductionReadinessAuditSummary, VoiceProductionReadinessAssertionInput, VoiceProductionReadinessAssertionReport, VoiceProductionReadinessCheck, VoiceProductionReadinessGateExplanation, VoiceProductionReadinessGateIssue, VoiceProductionReadinessGateOptions, VoiceProductionReadinessGateProfile, VoiceProductionReadinessGateProfileSurface, VoiceProductionReadinessGateReport, VoiceProductionReadinessOpsActionHistoryOptions, VoiceProductionReadinessOpsActionHistorySummary, VoiceProductionReadinessOperationsRecordLink, VoiceProductionReadinessOperationsRecordLinks, VoiceProductionReadinessProfileExplanation, VoiceProductionReadinessProfileSurface, VoiceProductionReadinessProofMetadata, VoiceProductionReadinessProofRuntime, VoiceProductionReadinessProofRuntimeOptions, VoiceProductionReadinessProofRuntimeSeedOptions, VoiceProductionReadinessProofSource, VoiceProductionReadinessReport, VoiceProductionReadinessRouteInput, VoiceProductionReadinessRoutesOptions, VoiceProductionReadinessTraceDeliverySummary, VoiceReadinessRecoveryAction, VoiceReadinessRecoveryActionOptions, VoiceReadinessRecoveryActionPlan, VoiceProductionReadinessAuditDeliveryOptions, VoiceProductionReadinessAuditDeliverySummary, VoiceProductionReadinessTraceDeliveryOptions, VoiceProductionReadinessStatus } from './productionReadiness';
|
|
146
146
|
export type { VoiceMonitorDefinition, VoiceMonitorEvaluation, VoiceMonitorEvaluationInput, VoiceMonitorIssue, VoiceMonitorIssueStatus, VoiceMonitorIssueStore, VoiceMonitorNotifier, VoiceMonitorNotifierDeliveryInput, VoiceMonitorNotifierDeliveryOptions, VoiceMonitorNotifierDeliveryReceipt, VoiceMonitorNotifierDeliveryReceiptStore, VoiceMonitorNotifierDeliveryReport, VoiceMonitorNotifierDeliveryResult, VoiceMonitorRoutesOptions, VoiceMonitorRun, VoiceMonitorRunOptions, VoiceMonitorRunReport, VoiceMonitorRunner, VoiceMonitorRunnerOptions, VoiceMonitorRunnerRoutesOptions, VoiceMonitorRunnerTickResult, VoiceMonitorSeverity, VoiceMonitorStatus, VoiceMonitorWebhookNotifierOptions } from './voiceMonitoring';
|
|
147
147
|
export type { VoiceReadinessProfileName, VoiceReadinessProfileOptions, VoiceReadinessProfileRecommendation, VoiceReadinessProfileRecommendationScore, VoiceReadinessProfileRoutesOptions } from './readinessProfiles';
|
|
148
148
|
export type { VoiceProviderStackChoice, VoiceProviderStackCapabilities, VoiceProviderStackCapabilityGap, VoiceProviderStackCapabilityGapInput, VoiceProviderStackCapabilityGapReport, VoiceProviderContractCheck, VoiceProviderContractCheckStatus, VoiceProviderContractDefinition, VoiceProviderContractMatrixAssertionInput, VoiceProviderContractMatrixAssertionReport, VoiceProviderContractMatrixHandlerOptions, VoiceProviderContractMatrixHTMLHandlerOptions, VoiceProviderContractMatrixInput, VoiceProviderContractMatrixPresetOptions, VoiceProviderContractMatrixReport, VoiceProviderContractMatrixRoutesOptions, VoiceProviderContractMatrixRow, VoiceProviderStackAssertionInput, VoiceProviderStackAssertionReport, VoiceProviderStackInput, VoiceProviderStackKind, VoiceProviderStackRecommendation } from './providerStackRecommendations';
|
package/dist/index.js
CHANGED
|
@@ -16229,6 +16229,94 @@ var buildVoiceRealCallProfileReadinessCheck = (report, options = {}) => {
|
|
|
16229
16229
|
value: `${String(report.defaults.summary.actionableProfiles)}/${String(report.summary.profileCount)} actionable`
|
|
16230
16230
|
};
|
|
16231
16231
|
};
|
|
16232
|
+
var buildVoiceRealCallProfileRecoveryJobHistoryCheck = async (store, options = {}) => {
|
|
16233
|
+
const href = options.href ?? "/voice/real-call-profile-recovery";
|
|
16234
|
+
const sourceHref = options.sourceHref ?? "/api/voice/real-call-profile-history/actions/jobs";
|
|
16235
|
+
const minCompletedJobs = options.minCompletedJobs ?? 1;
|
|
16236
|
+
const label = options.label ?? "Real-call recovery job history";
|
|
16237
|
+
if (!store?.list) {
|
|
16238
|
+
return {
|
|
16239
|
+
actions: [
|
|
16240
|
+
{
|
|
16241
|
+
description: "Configure a recovery job store with list support so operators can inspect proof repair history.",
|
|
16242
|
+
href,
|
|
16243
|
+
label: "Configure recovery job history"
|
|
16244
|
+
}
|
|
16245
|
+
],
|
|
16246
|
+
detail: "No real-call profile recovery job store with list support is configured.",
|
|
16247
|
+
gateExplanation: {
|
|
16248
|
+
evidenceHref: sourceHref,
|
|
16249
|
+
observed: "missing",
|
|
16250
|
+
remediation: "Use the bundled memory or SQLite recovery job store, or implement list() on the custom store.",
|
|
16251
|
+
sourceHref,
|
|
16252
|
+
threshold: "list support",
|
|
16253
|
+
thresholdLabel: "Inspectable recovery jobs",
|
|
16254
|
+
unit: "status"
|
|
16255
|
+
},
|
|
16256
|
+
href,
|
|
16257
|
+
label,
|
|
16258
|
+
status: "fail",
|
|
16259
|
+
value: "missing"
|
|
16260
|
+
};
|
|
16261
|
+
}
|
|
16262
|
+
const jobs = await store.list({ limit: 50 });
|
|
16263
|
+
const now = Date.now();
|
|
16264
|
+
const recentJobs = options.maxAgeMs === undefined ? jobs : jobs.filter((job) => now - Date.parse(job.updatedAt) <= options.maxAgeMs);
|
|
16265
|
+
const completedJobs = recentJobs.filter((job) => job.status === "pass" || job.status === "fail");
|
|
16266
|
+
const failedJobs = recentJobs.filter((job) => job.status === "fail");
|
|
16267
|
+
const runningJobs = recentJobs.filter((job) => job.status === "queued" || job.status === "running");
|
|
16268
|
+
const issues = [];
|
|
16269
|
+
const warnings = [];
|
|
16270
|
+
if (completedJobs.length < minCompletedJobs) {
|
|
16271
|
+
issues.push(`Expected at least ${String(minCompletedJobs)} completed recovery job(s), found ${String(completedJobs.length)}.`);
|
|
16272
|
+
}
|
|
16273
|
+
if (!options.allowFailedJobs && failedJobs.length > 0) {
|
|
16274
|
+
issues.push(`${String(failedJobs.length)} recent recovery job(s) failed.`);
|
|
16275
|
+
}
|
|
16276
|
+
if (runningJobs.length > 0) {
|
|
16277
|
+
const message = `${String(runningJobs.length)} recovery job(s) are still queued or running.`;
|
|
16278
|
+
if (options.failOnRunningJobs) {
|
|
16279
|
+
issues.push(message);
|
|
16280
|
+
} else {
|
|
16281
|
+
warnings.push(message);
|
|
16282
|
+
}
|
|
16283
|
+
}
|
|
16284
|
+
const status = issues.length > 0 ? "fail" : warnings.length > 0 ? "warn" : "pass";
|
|
16285
|
+
const detail = status === "pass" ? `${String(completedJobs.length)} completed recovery job(s), ${String(failedJobs.length)} failed, ${String(runningJobs.length)} running.` : [...issues, ...warnings].join(" ");
|
|
16286
|
+
return {
|
|
16287
|
+
actions: [
|
|
16288
|
+
{
|
|
16289
|
+
description: "Open the recovery job UI and run or inspect proof repair jobs.",
|
|
16290
|
+
href,
|
|
16291
|
+
label: "Open recovery job history"
|
|
16292
|
+
},
|
|
16293
|
+
{
|
|
16294
|
+
description: "Open the recovery job history API.",
|
|
16295
|
+
href: sourceHref,
|
|
16296
|
+
label: "Open recovery jobs API"
|
|
16297
|
+
}
|
|
16298
|
+
],
|
|
16299
|
+
detail,
|
|
16300
|
+
gateExplanation: {
|
|
16301
|
+
evidenceHref: sourceHref,
|
|
16302
|
+
observed: completedJobs.length,
|
|
16303
|
+
remediation: "Run a browser or phone recovery proof job and ensure recent recovery jobs complete without failure.",
|
|
16304
|
+
sourceHref,
|
|
16305
|
+
threshold: minCompletedJobs,
|
|
16306
|
+
thresholdLabel: "Minimum completed recovery jobs",
|
|
16307
|
+
unit: "count"
|
|
16308
|
+
},
|
|
16309
|
+
href,
|
|
16310
|
+
label,
|
|
16311
|
+
proofSource: {
|
|
16312
|
+
href: sourceHref,
|
|
16313
|
+
source: "recovery-job-store",
|
|
16314
|
+
sourceLabel: "Real-call recovery jobs"
|
|
16315
|
+
},
|
|
16316
|
+
status,
|
|
16317
|
+
value: `${String(completedJobs.length)} completed / ${String(failedJobs.length)} failed / ${String(runningJobs.length)} running`
|
|
16318
|
+
};
|
|
16319
|
+
};
|
|
16232
16320
|
var resolveVoiceRealCallProfileProviderRoute = (options) => {
|
|
16233
16321
|
const defaults = readRealCallProfileDefaultsReport(options.defaults);
|
|
16234
16322
|
const profile = defaults.profiles.find((item) => item.profileId === options.profileId) ?? defaults.profiles.find((item) => item.status === "pass") ?? defaults.profiles[0];
|
|
@@ -32465,6 +32553,36 @@ var createVoiceObservabilityExportRoutes = (options = {}) => {
|
|
|
32465
32553
|
};
|
|
32466
32554
|
|
|
32467
32555
|
// src/productionReadiness.ts
|
|
32556
|
+
var buildVoiceReadinessRecoveryActions = (input, options = {}) => {
|
|
32557
|
+
const checks = "checks" in input ? input.checks : input;
|
|
32558
|
+
const includeWarnings = options.includeWarnings ?? true;
|
|
32559
|
+
const sourceChecks = checks.filter((check) => check.status === "fail" || includeWarnings && check.status === "warn");
|
|
32560
|
+
const seen = new Set;
|
|
32561
|
+
const actions = sourceChecks.flatMap((check) => (check.actions ?? []).flatMap((action) => {
|
|
32562
|
+
const method = action.method ?? "GET";
|
|
32563
|
+
const key = `${method}:${action.href}:${check.label}`;
|
|
32564
|
+
if (seen.has(key)) {
|
|
32565
|
+
return [];
|
|
32566
|
+
}
|
|
32567
|
+
seen.add(key);
|
|
32568
|
+
return [
|
|
32569
|
+
{
|
|
32570
|
+
...action,
|
|
32571
|
+
key,
|
|
32572
|
+
method,
|
|
32573
|
+
sourceCheckDetail: check.detail,
|
|
32574
|
+
sourceCheckHref: check.href,
|
|
32575
|
+
sourceCheckLabel: check.label,
|
|
32576
|
+
sourceStatus: check.status
|
|
32577
|
+
}
|
|
32578
|
+
];
|
|
32579
|
+
}));
|
|
32580
|
+
return {
|
|
32581
|
+
actions,
|
|
32582
|
+
generatedAt: (options.now ?? (() => new Date))().toISOString(),
|
|
32583
|
+
sourceChecks: sourceChecks.length
|
|
32584
|
+
};
|
|
32585
|
+
};
|
|
32468
32586
|
var escapeHtml52 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
32469
32587
|
var formatVoiceProofFreshnessDuration = (valueMs) => {
|
|
32470
32588
|
if (valueMs < 1000) {
|
|
@@ -39274,11 +39392,13 @@ export {
|
|
|
39274
39392
|
buildVoiceRealtimeProviderContractMatrix,
|
|
39275
39393
|
buildVoiceRealtimeChannelRuntimeSamplesFromTrace,
|
|
39276
39394
|
buildVoiceRealtimeChannelReport,
|
|
39395
|
+
buildVoiceRealCallProfileRecoveryJobHistoryCheck,
|
|
39277
39396
|
buildVoiceRealCallProfileRecoveryActions,
|
|
39278
39397
|
buildVoiceRealCallProfileReadinessCheck,
|
|
39279
39398
|
buildVoiceRealCallProfileHistoryReport,
|
|
39280
39399
|
buildVoiceRealCallProfileEvidenceFromTraceEvents,
|
|
39281
39400
|
buildVoiceRealCallProfileDefaults,
|
|
39401
|
+
buildVoiceReadinessRecoveryActions,
|
|
39282
39402
|
buildVoiceProviderSloReport,
|
|
39283
39403
|
buildVoiceProviderOrchestrationReport,
|
|
39284
39404
|
buildVoiceProviderDecisionTraceReport,
|
|
@@ -56,6 +56,22 @@ export type VoiceProductionReadinessCheck = {
|
|
|
56
56
|
status: VoiceProductionReadinessStatus;
|
|
57
57
|
value?: number | string;
|
|
58
58
|
};
|
|
59
|
+
export type VoiceReadinessRecoveryAction = VoiceProductionReadinessAction & {
|
|
60
|
+
key: string;
|
|
61
|
+
sourceCheckDetail?: string;
|
|
62
|
+
sourceCheckHref?: string;
|
|
63
|
+
sourceCheckLabel: string;
|
|
64
|
+
sourceStatus: Exclude<VoiceProductionReadinessStatus, 'pass'>;
|
|
65
|
+
};
|
|
66
|
+
export type VoiceReadinessRecoveryActionPlan = {
|
|
67
|
+
actions: VoiceReadinessRecoveryAction[];
|
|
68
|
+
generatedAt: string;
|
|
69
|
+
sourceChecks: number;
|
|
70
|
+
};
|
|
71
|
+
export type VoiceReadinessRecoveryActionOptions = {
|
|
72
|
+
includeWarnings?: boolean;
|
|
73
|
+
now?: () => Date;
|
|
74
|
+
};
|
|
59
75
|
export type VoiceProductionReadinessGateIssue = {
|
|
60
76
|
code: string;
|
|
61
77
|
detail?: string;
|
|
@@ -67,6 +83,7 @@ export type VoiceProductionReadinessGateIssue = {
|
|
|
67
83
|
export type VoiceProductionReadinessGateOptions = {
|
|
68
84
|
failOnWarnings?: boolean;
|
|
69
85
|
};
|
|
86
|
+
export declare const buildVoiceReadinessRecoveryActions: (input: VoiceProductionReadinessReport | readonly VoiceProductionReadinessCheck[], options?: VoiceReadinessRecoveryActionOptions) => VoiceReadinessRecoveryActionPlan;
|
|
70
87
|
export type VoiceProductionReadinessGateReport = {
|
|
71
88
|
checkedAt: number;
|
|
72
89
|
failures: VoiceProductionReadinessGateIssue[];
|
package/dist/proofTrends.d.ts
CHANGED
|
@@ -378,6 +378,15 @@ export type VoiceRealCallProfileReadinessCheckOptions = {
|
|
|
378
378
|
sourceHref?: string;
|
|
379
379
|
};
|
|
380
380
|
export type VoiceRealCallProfileRecoveryActionOptions = VoiceRealCallProfileReadinessCheckOptions;
|
|
381
|
+
export type VoiceRealCallProfileRecoveryJobHistoryCheckOptions = {
|
|
382
|
+
allowFailedJobs?: boolean;
|
|
383
|
+
failOnRunningJobs?: boolean;
|
|
384
|
+
href?: string;
|
|
385
|
+
label?: string;
|
|
386
|
+
maxAgeMs?: number;
|
|
387
|
+
minCompletedJobs?: number;
|
|
388
|
+
sourceHref?: string;
|
|
389
|
+
};
|
|
381
390
|
export type VoiceRealCallProfileRecoveryActionHandlerInput = {
|
|
382
391
|
actionId: VoiceRealCallProfileRecoveryActionId;
|
|
383
392
|
report: VoiceRealCallProfileHistoryReport;
|
|
@@ -478,6 +487,7 @@ export declare const createVoiceInMemoryRealCallProfileRecoveryJobStore: (option
|
|
|
478
487
|
}) => VoiceRealCallProfileRecoveryJobStore;
|
|
479
488
|
export declare const createVoiceSQLiteRealCallProfileRecoveryJobStore: (options?: VoiceSQLiteRealCallProfileRecoveryJobStoreOptions) => VoiceRealCallProfileRecoveryJobStore;
|
|
480
489
|
export declare const buildVoiceRealCallProfileReadinessCheck: (report: VoiceRealCallProfileHistoryReport, options?: VoiceRealCallProfileReadinessCheckOptions) => VoiceProductionReadinessCheck;
|
|
490
|
+
export declare const buildVoiceRealCallProfileRecoveryJobHistoryCheck: (store: Pick<VoiceRealCallProfileRecoveryJobStore, "list"> | undefined, options?: VoiceRealCallProfileRecoveryJobHistoryCheckOptions) => Promise<VoiceProductionReadinessCheck>;
|
|
481
491
|
export declare const resolveVoiceRealCallProfileProviderRoute: <TProvider extends string = string>(options: VoiceRealCallProfileProviderRouteOptions<TProvider>) => TProvider | undefined;
|
|
482
492
|
export declare const buildVoiceRealCallProfileHistoryReport: (options?: VoiceRealCallProfileHistoryOptions) => VoiceRealCallProfileHistoryReport;
|
|
483
493
|
export declare const evaluateVoiceProofTrendEvidence: (report: VoiceProofTrendReport, input?: VoiceProofTrendAssertionInput) => VoiceProofTrendAssertionReport;
|
package/dist/react/index.js
CHANGED
|
@@ -2347,6 +2347,94 @@ var buildVoiceRealCallProfileReadinessCheck = (report, options = {}) => {
|
|
|
2347
2347
|
value: `${String(report.defaults.summary.actionableProfiles)}/${String(report.summary.profileCount)} actionable`
|
|
2348
2348
|
};
|
|
2349
2349
|
};
|
|
2350
|
+
var buildVoiceRealCallProfileRecoveryJobHistoryCheck = async (store, options = {}) => {
|
|
2351
|
+
const href = options.href ?? "/voice/real-call-profile-recovery";
|
|
2352
|
+
const sourceHref = options.sourceHref ?? "/api/voice/real-call-profile-history/actions/jobs";
|
|
2353
|
+
const minCompletedJobs = options.minCompletedJobs ?? 1;
|
|
2354
|
+
const label = options.label ?? "Real-call recovery job history";
|
|
2355
|
+
if (!store?.list) {
|
|
2356
|
+
return {
|
|
2357
|
+
actions: [
|
|
2358
|
+
{
|
|
2359
|
+
description: "Configure a recovery job store with list support so operators can inspect proof repair history.",
|
|
2360
|
+
href,
|
|
2361
|
+
label: "Configure recovery job history"
|
|
2362
|
+
}
|
|
2363
|
+
],
|
|
2364
|
+
detail: "No real-call profile recovery job store with list support is configured.",
|
|
2365
|
+
gateExplanation: {
|
|
2366
|
+
evidenceHref: sourceHref,
|
|
2367
|
+
observed: "missing",
|
|
2368
|
+
remediation: "Use the bundled memory or SQLite recovery job store, or implement list() on the custom store.",
|
|
2369
|
+
sourceHref,
|
|
2370
|
+
threshold: "list support",
|
|
2371
|
+
thresholdLabel: "Inspectable recovery jobs",
|
|
2372
|
+
unit: "status"
|
|
2373
|
+
},
|
|
2374
|
+
href,
|
|
2375
|
+
label,
|
|
2376
|
+
status: "fail",
|
|
2377
|
+
value: "missing"
|
|
2378
|
+
};
|
|
2379
|
+
}
|
|
2380
|
+
const jobs = await store.list({ limit: 50 });
|
|
2381
|
+
const now = Date.now();
|
|
2382
|
+
const recentJobs = options.maxAgeMs === undefined ? jobs : jobs.filter((job) => now - Date.parse(job.updatedAt) <= options.maxAgeMs);
|
|
2383
|
+
const completedJobs = recentJobs.filter((job) => job.status === "pass" || job.status === "fail");
|
|
2384
|
+
const failedJobs = recentJobs.filter((job) => job.status === "fail");
|
|
2385
|
+
const runningJobs = recentJobs.filter((job) => job.status === "queued" || job.status === "running");
|
|
2386
|
+
const issues = [];
|
|
2387
|
+
const warnings = [];
|
|
2388
|
+
if (completedJobs.length < minCompletedJobs) {
|
|
2389
|
+
issues.push(`Expected at least ${String(minCompletedJobs)} completed recovery job(s), found ${String(completedJobs.length)}.`);
|
|
2390
|
+
}
|
|
2391
|
+
if (!options.allowFailedJobs && failedJobs.length > 0) {
|
|
2392
|
+
issues.push(`${String(failedJobs.length)} recent recovery job(s) failed.`);
|
|
2393
|
+
}
|
|
2394
|
+
if (runningJobs.length > 0) {
|
|
2395
|
+
const message = `${String(runningJobs.length)} recovery job(s) are still queued or running.`;
|
|
2396
|
+
if (options.failOnRunningJobs) {
|
|
2397
|
+
issues.push(message);
|
|
2398
|
+
} else {
|
|
2399
|
+
warnings.push(message);
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
const status = issues.length > 0 ? "fail" : warnings.length > 0 ? "warn" : "pass";
|
|
2403
|
+
const detail = status === "pass" ? `${String(completedJobs.length)} completed recovery job(s), ${String(failedJobs.length)} failed, ${String(runningJobs.length)} running.` : [...issues, ...warnings].join(" ");
|
|
2404
|
+
return {
|
|
2405
|
+
actions: [
|
|
2406
|
+
{
|
|
2407
|
+
description: "Open the recovery job UI and run or inspect proof repair jobs.",
|
|
2408
|
+
href,
|
|
2409
|
+
label: "Open recovery job history"
|
|
2410
|
+
},
|
|
2411
|
+
{
|
|
2412
|
+
description: "Open the recovery job history API.",
|
|
2413
|
+
href: sourceHref,
|
|
2414
|
+
label: "Open recovery jobs API"
|
|
2415
|
+
}
|
|
2416
|
+
],
|
|
2417
|
+
detail,
|
|
2418
|
+
gateExplanation: {
|
|
2419
|
+
evidenceHref: sourceHref,
|
|
2420
|
+
observed: completedJobs.length,
|
|
2421
|
+
remediation: "Run a browser or phone recovery proof job and ensure recent recovery jobs complete without failure.",
|
|
2422
|
+
sourceHref,
|
|
2423
|
+
threshold: minCompletedJobs,
|
|
2424
|
+
thresholdLabel: "Minimum completed recovery jobs",
|
|
2425
|
+
unit: "count"
|
|
2426
|
+
},
|
|
2427
|
+
href,
|
|
2428
|
+
label,
|
|
2429
|
+
proofSource: {
|
|
2430
|
+
href: sourceHref,
|
|
2431
|
+
source: "recovery-job-store",
|
|
2432
|
+
sourceLabel: "Real-call recovery jobs"
|
|
2433
|
+
},
|
|
2434
|
+
status,
|
|
2435
|
+
value: `${String(completedJobs.length)} completed / ${String(failedJobs.length)} failed / ${String(runningJobs.length)} running`
|
|
2436
|
+
};
|
|
2437
|
+
};
|
|
2350
2438
|
var resolveVoiceRealCallProfileProviderRoute = (options) => {
|
|
2351
2439
|
const defaults = readRealCallProfileDefaultsReport(options.defaults);
|
|
2352
2440
|
const profile = defaults.profiles.find((item) => item.profileId === options.profileId) ?? defaults.profiles.find((item) => item.status === "pass") ?? defaults.profiles[0];
|
package/dist/vue/index.js
CHANGED
|
@@ -2268,6 +2268,94 @@ var buildVoiceRealCallProfileReadinessCheck = (report, options = {}) => {
|
|
|
2268
2268
|
value: `${String(report.defaults.summary.actionableProfiles)}/${String(report.summary.profileCount)} actionable`
|
|
2269
2269
|
};
|
|
2270
2270
|
};
|
|
2271
|
+
var buildVoiceRealCallProfileRecoveryJobHistoryCheck = async (store, options = {}) => {
|
|
2272
|
+
const href = options.href ?? "/voice/real-call-profile-recovery";
|
|
2273
|
+
const sourceHref = options.sourceHref ?? "/api/voice/real-call-profile-history/actions/jobs";
|
|
2274
|
+
const minCompletedJobs = options.minCompletedJobs ?? 1;
|
|
2275
|
+
const label = options.label ?? "Real-call recovery job history";
|
|
2276
|
+
if (!store?.list) {
|
|
2277
|
+
return {
|
|
2278
|
+
actions: [
|
|
2279
|
+
{
|
|
2280
|
+
description: "Configure a recovery job store with list support so operators can inspect proof repair history.",
|
|
2281
|
+
href,
|
|
2282
|
+
label: "Configure recovery job history"
|
|
2283
|
+
}
|
|
2284
|
+
],
|
|
2285
|
+
detail: "No real-call profile recovery job store with list support is configured.",
|
|
2286
|
+
gateExplanation: {
|
|
2287
|
+
evidenceHref: sourceHref,
|
|
2288
|
+
observed: "missing",
|
|
2289
|
+
remediation: "Use the bundled memory or SQLite recovery job store, or implement list() on the custom store.",
|
|
2290
|
+
sourceHref,
|
|
2291
|
+
threshold: "list support",
|
|
2292
|
+
thresholdLabel: "Inspectable recovery jobs",
|
|
2293
|
+
unit: "status"
|
|
2294
|
+
},
|
|
2295
|
+
href,
|
|
2296
|
+
label,
|
|
2297
|
+
status: "fail",
|
|
2298
|
+
value: "missing"
|
|
2299
|
+
};
|
|
2300
|
+
}
|
|
2301
|
+
const jobs = await store.list({ limit: 50 });
|
|
2302
|
+
const now = Date.now();
|
|
2303
|
+
const recentJobs = options.maxAgeMs === undefined ? jobs : jobs.filter((job) => now - Date.parse(job.updatedAt) <= options.maxAgeMs);
|
|
2304
|
+
const completedJobs = recentJobs.filter((job) => job.status === "pass" || job.status === "fail");
|
|
2305
|
+
const failedJobs = recentJobs.filter((job) => job.status === "fail");
|
|
2306
|
+
const runningJobs = recentJobs.filter((job) => job.status === "queued" || job.status === "running");
|
|
2307
|
+
const issues = [];
|
|
2308
|
+
const warnings = [];
|
|
2309
|
+
if (completedJobs.length < minCompletedJobs) {
|
|
2310
|
+
issues.push(`Expected at least ${String(minCompletedJobs)} completed recovery job(s), found ${String(completedJobs.length)}.`);
|
|
2311
|
+
}
|
|
2312
|
+
if (!options.allowFailedJobs && failedJobs.length > 0) {
|
|
2313
|
+
issues.push(`${String(failedJobs.length)} recent recovery job(s) failed.`);
|
|
2314
|
+
}
|
|
2315
|
+
if (runningJobs.length > 0) {
|
|
2316
|
+
const message = `${String(runningJobs.length)} recovery job(s) are still queued or running.`;
|
|
2317
|
+
if (options.failOnRunningJobs) {
|
|
2318
|
+
issues.push(message);
|
|
2319
|
+
} else {
|
|
2320
|
+
warnings.push(message);
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
const status = issues.length > 0 ? "fail" : warnings.length > 0 ? "warn" : "pass";
|
|
2324
|
+
const detail = status === "pass" ? `${String(completedJobs.length)} completed recovery job(s), ${String(failedJobs.length)} failed, ${String(runningJobs.length)} running.` : [...issues, ...warnings].join(" ");
|
|
2325
|
+
return {
|
|
2326
|
+
actions: [
|
|
2327
|
+
{
|
|
2328
|
+
description: "Open the recovery job UI and run or inspect proof repair jobs.",
|
|
2329
|
+
href,
|
|
2330
|
+
label: "Open recovery job history"
|
|
2331
|
+
},
|
|
2332
|
+
{
|
|
2333
|
+
description: "Open the recovery job history API.",
|
|
2334
|
+
href: sourceHref,
|
|
2335
|
+
label: "Open recovery jobs API"
|
|
2336
|
+
}
|
|
2337
|
+
],
|
|
2338
|
+
detail,
|
|
2339
|
+
gateExplanation: {
|
|
2340
|
+
evidenceHref: sourceHref,
|
|
2341
|
+
observed: completedJobs.length,
|
|
2342
|
+
remediation: "Run a browser or phone recovery proof job and ensure recent recovery jobs complete without failure.",
|
|
2343
|
+
sourceHref,
|
|
2344
|
+
threshold: minCompletedJobs,
|
|
2345
|
+
thresholdLabel: "Minimum completed recovery jobs",
|
|
2346
|
+
unit: "count"
|
|
2347
|
+
},
|
|
2348
|
+
href,
|
|
2349
|
+
label,
|
|
2350
|
+
proofSource: {
|
|
2351
|
+
href: sourceHref,
|
|
2352
|
+
source: "recovery-job-store",
|
|
2353
|
+
sourceLabel: "Real-call recovery jobs"
|
|
2354
|
+
},
|
|
2355
|
+
status,
|
|
2356
|
+
value: `${String(completedJobs.length)} completed / ${String(failedJobs.length)} failed / ${String(runningJobs.length)} running`
|
|
2357
|
+
};
|
|
2358
|
+
};
|
|
2271
2359
|
var resolveVoiceRealCallProfileProviderRoute = (options) => {
|
|
2272
2360
|
const defaults = readRealCallProfileDefaultsReport(options.defaults);
|
|
2273
2361
|
const profile = defaults.profiles.find((item) => item.profileId === options.profileId) ?? defaults.profiles.find((item) => item.status === "pass") ?? defaults.profiles[0];
|