This commit is contained in:
2026-05-13 11:17:53 +02:00
parent 69385094ff
commit 24d21818cf
23 changed files with 736 additions and 65 deletions

View File

@@ -327,16 +327,47 @@ pub(crate) struct DemoPipeline2LocalPipelineDiagnosticSummary {
/// Total known pairs.
#[ts(type = "number")]
pub pair_count: i64,
/// Total pairs without trade.
/// Stable explanation for legacy pair gap counters.
pub pair_gap_counter_semantics: std::string::String,
/// Total pairs without any persisted trade event.
#[ts(type = "number")]
pub literal_pair_without_trade_count: i64,
/// Total pairs without any persisted candle.
#[ts(type = "number")]
pub literal_pair_without_candle_count: i64,
/// Total pairs that have at least one persisted trade event.
#[ts(type = "number")]
pub trade_materialized_pair_count: i64,
/// Total pairs that have at least one persisted candle bucket.
#[ts(type = "number")]
pub candle_materialized_pair_count: i64,
/// Total pairs with at least one successful decoded trade candidate.
#[ts(type = "number")]
pub actionable_pair_count: i64,
/// Total distinct candle timeframes currently materialized.
#[ts(type = "number")]
pub candle_bucket_timeframe_count: i64,
/// Whether candle rows are bucketed aggregates rather than one row per trade.
pub candles_are_bucketed: bool,
/// Total pairs without trade among actionable successful trade candidates.
#[ts(type = "number")]
pub blocking_pair_without_trade_count: i64,
/// Total pairs without candle among actionable successful candle candidates.
#[ts(type = "number")]
pub blocking_pair_without_candle_count: i64,
/// Total pairs without trade. Legacy alias for blocking/actionable gaps.
#[ts(type = "number")]
pub pair_without_trade_count: i64,
/// Total pairs without candle.
/// Total pairs without candle. Legacy alias for blocking/actionable gaps.
#[ts(type = "number")]
pub pair_without_candle_count: i64,
/// Diagnostics grouped by DEX.
pub dex_summaries: std::vec::Vec<DemoPipeline2LocalDexDiagnosticSummary>,
/// Diagnostics grouped by pair.
pub pair_summaries: std::vec::Vec<DemoPipeline2LocalPairDiagnosticSummary>,
/// Diagnostics grouped by pair materialization/actionability class.
pub pair_actionability_summaries:
std::vec::Vec<DemoPipeline2LocalPairActionabilityDiagnosticSummary>,
/// Diagnostics grouped by decoded event kind.
pub decoded_event_summaries: std::vec::Vec<DemoPipeline2LocalDecodedEventDiagnosticSummary>,
/// Diagnostics grouped by decoded event classification.
@@ -447,6 +478,39 @@ pub(crate) struct DemoPipeline2LocalPairDiagnosticSummary {
pub last_price_quote_per_base: std::option::Option<f64>,
}
/// Local pair actionability diagnostics summary for the UI.
#[derive(Clone, Debug, serde::Serialize, TS)]
#[ts(
export,
export_to = "../frontend/ts/bindings/DemoPipeline2LocalPairActionabilityDiagnosticSummary.ts"
)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DemoPipeline2LocalPairActionabilityDiagnosticSummary {
/// Pair actionability or materialization class.
pub pair_actionability: std::string::String,
/// Pair count.
#[ts(type = "number")]
pub pair_count: i64,
/// Decoded event count.
#[ts(type = "number")]
pub decoded_event_count: i64,
/// Decoded trade candidate count.
#[ts(type = "number")]
pub decoded_trade_candidate_count: i64,
/// Actionable trade candidate count.
#[ts(type = "number")]
pub actionable_trade_candidate_count: i64,
/// Failed trade candidate count.
#[ts(type = "number")]
pub failed_trade_candidate_count: i64,
/// Trade event count.
#[ts(type = "number")]
pub trade_event_count: i64,
/// Pair candle count.
#[ts(type = "number")]
pub pair_candle_count: i64,
}
/// Local decoded-event diagnostics summary for the UI.
#[derive(Clone, Debug, serde::Serialize, TS)]
#[ts(
@@ -971,7 +1035,7 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
let service = kb_lib::LocalPipelineValidationService::new(database.clone());
let profile_code = match request {
Some(request) => request.profile_code,
None => "0.7.31_trade_event_actionability_policy".to_string(),
None => "0.7.32_validation_report_semantics".to_string(),
};
let run_result = match profile_code.as_str() {
"0.7.27" | "0.7.27_dexes_non_regression" => {
@@ -989,6 +1053,9 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
"0.7.31" | "0.7.31_trade_event_actionability_policy" => {
service.validate_v0_7_31_current_database().await
},
"0.7.32" | "0.7.32_validation_report_semantics" => {
service.validate_v0_7_32_current_database().await
},
other => Err(kb_lib::Error::InvalidState(format!(
"unsupported local pipeline validation profile: {other}"
))),
@@ -1472,6 +1539,14 @@ fn demo_pipeline2_map_local_diagnostics_summary(
for pair_summary in summary.pair_summaries {
pair_summaries.push(demo_pipeline2_map_local_pair_diagnostic_summary(pair_summary));
}
let mut pair_actionability_summaries = std::vec::Vec::new();
for pair_actionability_summary in summary.pair_actionability_summaries {
pair_actionability_summaries.push(
demo_pipeline2_map_local_pair_actionability_diagnostic_summary(
pair_actionability_summary,
),
);
}
let mut decoded_event_summaries = std::vec::Vec::new();
for decoded_event_summary in summary.decoded_event_summaries {
decoded_event_summaries
@@ -1552,10 +1627,21 @@ fn demo_pipeline2_map_local_diagnostics_summary(
token_metadata_missing_count: summary.token_metadata_missing_count,
pool_count: summary.pool_count,
pair_count: summary.pair_count,
pair_gap_counter_semantics: summary.pair_gap_counter_semantics,
literal_pair_without_trade_count: summary.literal_pair_without_trade_count,
literal_pair_without_candle_count: summary.literal_pair_without_candle_count,
trade_materialized_pair_count: summary.trade_materialized_pair_count,
candle_materialized_pair_count: summary.candle_materialized_pair_count,
actionable_pair_count: summary.actionable_pair_count,
candle_bucket_timeframe_count: summary.candle_bucket_timeframe_count,
candles_are_bucketed: summary.candles_are_bucketed,
blocking_pair_without_trade_count: summary.blocking_pair_without_trade_count,
blocking_pair_without_candle_count: summary.blocking_pair_without_candle_count,
pair_without_trade_count: summary.pair_without_trade_count,
pair_without_candle_count: summary.pair_without_candle_count,
dex_summaries,
pair_summaries,
pair_actionability_summaries,
decoded_event_summaries,
event_classification_summaries,
missing_trade_event_reason_summaries,
@@ -1606,6 +1692,21 @@ fn demo_pipeline2_map_local_pair_diagnostic_summary(
}
}
fn demo_pipeline2_map_local_pair_actionability_diagnostic_summary(
summary: kb_lib::LocalPairActionabilityDiagnosticSummaryDto,
) -> DemoPipeline2LocalPairActionabilityDiagnosticSummary {
DemoPipeline2LocalPairActionabilityDiagnosticSummary {
pair_actionability: summary.pair_actionability,
pair_count: summary.pair_count,
decoded_event_count: summary.decoded_event_count,
decoded_trade_candidate_count: summary.decoded_trade_candidate_count,
actionable_trade_candidate_count: summary.actionable_trade_candidate_count,
failed_trade_candidate_count: summary.failed_trade_candidate_count,
trade_event_count: summary.trade_event_count,
pair_candle_count: summary.pair_candle_count,
}
}
fn demo_pipeline2_map_local_decoded_event_diagnostic_summary(
summary: kb_lib::LocalDecodedEventDiagnosticSummaryDto,
) -> DemoPipeline2LocalDecodedEventDiagnosticSummary {