This commit is contained in:
2026-05-13 20:11:29 +02:00
parent 693a456e62
commit cfa1ff2289
36 changed files with 2035 additions and 103 deletions

View File

@@ -166,7 +166,8 @@
<div class="mb-3">
<label for="demoPipeline2ValidationProfileSelect" class="form-label">Validation profile</label>
<select id="demoPipeline2ValidationProfileSelect" class="form-select">
<option value="0.7.33_pair_trading_readiness" selected>0.7.33pair trading readiness</option>
<option value="0.7.34_non_trade_liquidity_lifecycle" selected>0.7.34non-trade liquidity/lifecycle</option>
<option value="0.7.33_pair_trading_readiness">0.7.33 — pair trading readiness</option>
<option value="0.7.32_validation_report_semantics">0.7.32 — validation report semantics</option>
<option value="0.7.31_trade_event_actionability_policy">0.7.31 — trade event actionability policy</option>
<option value="0.7.30_non_trade_event_classification">0.7.30 — non-trade event classification</option>

View File

@@ -52,6 +52,14 @@ decodedNonActionableTradeEventCount: number,
* Total decoded events with unknown classification.
*/
decodedUnknownEventCount: number,
/**
* Total persisted liquidity events.
*/
liquidityEventCount: number,
/**
* Total persisted pool lifecycle events.
*/
poolLifecycleEventCount: number,
/**
* Whether the local persisted pipeline has no blocking diagnostic issue.
*/

View File

@@ -42,6 +42,14 @@ decodedNonActionableTradeEventCount: number,
* Total decoded events with unknown classification.
*/
decodedUnknownEventCount: number,
/**
* Total persisted liquidity events.
*/
liquidityEventCount: number,
/**
* Total persisted pool lifecycle events.
*/
poolLifecycleEventCount: number,
/**
* Number of entries currently exposed by the DEX support matrix.
*/

View File

@@ -14,7 +14,6 @@ import type { DemoPipeline2BackfillPayload } from "./bindings/DemoPipeline2Backf
import type { DemoPipeline2PairCandlesRequest } from "./bindings/DemoPipeline2PairCandlesRequest.ts";
import type { DemoPipeline2PairCandlesPayload } from "./bindings/DemoPipeline2PairCandlesPayload.ts";
import type { DemoPipeline2LocalDiagnosticsPayload } from "./bindings/DemoPipeline2LocalDiagnosticsPayload.ts";
import type { DemoPipeline2LocalValidationRequest } from "./bindings/DemoPipeline2LocalValidationRequest.ts";
import type { DemoPipeline2LocalValidationPayload } from "./bindings/DemoPipeline2LocalValidationPayload.ts";
import type { DemoPipeline2ProgramInstructionDiscriminatorSummaryRequest } from "./bindings/DemoPipeline2ProgramInstructionDiscriminatorSummaryRequest.ts";
import type { DemoPipeline2ProgramInstructionDiscriminatorSummaryPayload } from "./bindings/DemoPipeline2ProgramInstructionDiscriminatorSummaryPayload.ts";
@@ -52,13 +51,18 @@ interface LocalPipelineReplayResult {
decodeErrorCount: number;
detectErrorCount: number;
tradeAggregationErrorCount: number;
nonTradeMaterializationErrorCount: number;
pairCandleErrorCount: number;
analyticSignalErrorCount: number;
decodedEventCount: number;
detectionCount: number;
tradeEventCount: number;
liquidityEventCount: number;
poolLifecycleEventCount: number;
pairCandleUpsertCount: number;
analyticSignalUpsertCount: number;
transactionClassificationCount: number;
transactionClassificationErrorCount: number;
tokenMetadataUpdatedCount: number;
pairSymbolUpdatedCount: number;
resetMarketMaterializationDeletedCount: number;
@@ -358,7 +362,6 @@ document.addEventListener("DOMContentLoaded", async () => {
const replayMetadataLimitInput = document.querySelector<HTMLInputElement>("#demoPipeline2ReplayMetadataLimitInput");
const replayLocalPipelineButton = document.querySelector<HTMLButtonElement>("#demoPipeline2ReplayLocalPipelineButton");
const diagnoseLocalPipelineButton = document.querySelector<HTMLButtonElement>("#demoPipeline2DiagnoseLocalPipelineButton");
const validationProfileSelect = document.querySelector<HTMLSelectElement>("#demoPipeline2ValidationProfileSelect");
const validateLocalPipelineButton = document.querySelector<HTMLButtonElement>("#demoPipeline2ValidateLocalPipelineButton");
const discriminatorProgramIdInput = document.querySelector<HTMLInputElement>("#demoPipeline2DiscriminatorProgramIdInput");
@@ -405,7 +408,6 @@ document.addEventListener("DOMContentLoaded", async () => {
!replayMetadataLimitInput ||
!replayLocalPipelineButton ||
!diagnoseLocalPipelineButton ||
!validationProfileSelect ||
!validateLocalPipelineButton ||
!discriminatorProgramIdInput ||
!discriminatorLimitInput ||
@@ -618,7 +620,7 @@ document.addEventListener("DOMContentLoaded", async () => {
appendLogLine(
logTextarea,
`[ui] local pipeline replay completed: ${result.replayedTransactionCount.toString()} replayed, ${result.tradeEventCount.toString()} trades, ${result.pairCandleUpsertCount.toString()} candle upserts, resetDeleted='${result.resetMarketMaterializationDeletedCount.toString()}'`,
`[ui] local pipeline replay completed: ${result.replayedTransactionCount.toString()} replayed, ${result.tradeEventCount.toString()} trades, ${result.liquidityEventCount.toString()} liquidity, ${result.poolLifecycleEventCount.toString()} lifecycle, ${result.pairCandleUpsertCount.toString()} candle upserts, resetDeleted='${result.resetMarketMaterializationDeletedCount.toString()}'`,
);
await refreshCatalog();
@@ -641,7 +643,7 @@ document.addEventListener("DOMContentLoaded", async () => {
appendLogLine(
logTextarea,
`[ui] local pipeline diagnostics completed: ${payload.summary.decodedEventCount.toString()} decoded, ${payload.summary.tradeEventCount.toString()} trades, ${payload.summary.pairCandleCount.toString()} candles, actionableMissing='${payload.summary.actionableMissingTradeEventCount.toString()}', nonActionablePairs='${payload.summary.nonActionablePairCount.toString()}', blocking='${payload.summary.blockingIssueCount.toString()}', nonTradeUseful='${payload.summary.decodedNonTradeUsefulEventCount.toString()}', nonActionableTrade='${payload.summary.decodedNonActionableTradeEventCount.toString()}', unknownEvents='${payload.summary.decodedUnknownEventCount.toString()}'`,
`[ui] local pipeline diagnostics completed: ${payload.summary.decodedEventCount.toString()} decoded, ${payload.summary.tradeEventCount.toString()} trades, ${payload.summary.pairCandleCount.toString()} candles, actionableMissing='${payload.summary.actionableMissingTradeEventCount.toString()}', nonActionablePairs='${payload.summary.nonActionablePairCount.toString()}', blocking='${payload.summary.blockingIssueCount.toString()}'`,
);
} catch (error) {
appendLogLine(logTextarea, `[ui] local pipeline diagnostics error: ${String(error)}`);
@@ -651,16 +653,11 @@ document.addEventListener("DOMContentLoaded", async () => {
});
validateLocalPipelineButton.addEventListener("click", async () => {
const request: DemoPipeline2LocalValidationRequest = {
profileCode: validationProfileSelect.value,
};
appendLogLine(logTextarea, `[ui] validating local pipeline with ${request.profileCode} profile`);
appendLogLine(logTextarea, "[ui] validating local pipeline");
try {
const payload = await invoke<DemoPipeline2LocalValidationPayload>(
"demo_pipeline2_validate_local_pipeline",
{ request },
);
localValidationTextarea.value = payload.validationJson;
@@ -668,7 +665,7 @@ document.addEventListener("DOMContentLoaded", async () => {
appendLogLine(
logTextarea,
`[ui] local pipeline validation completed: profile='${payload.run.validationProfileCode}' passed='${payload.run.validationPassed ? "yes" : "no"}' blocking='${payload.run.blockingIssueCount.toString()}' warnings='${payload.run.warningCount.toString()}' dexMatrix='${payload.run.report.dexSupportMatrixEntryCount.toString()}' nonTradeUseful='${payload.run.report.decodedNonTradeUsefulEventCount.toString()}' nonActionableTrade='${payload.run.report.decodedNonActionableTradeEventCount.toString()}' unknownEvents='${payload.run.report.decodedUnknownEventCount.toString()}'`,
`[ui] local pipeline validation completed: profile='${payload.run.validationProfileCode}' passed='${payload.run.validationPassed ? "yes" : "no"}' blocking='${payload.run.blockingIssueCount.toString()}' warnings='${payload.run.warningCount.toString()}'`,
);
} catch (error) {
appendLogLine(logTextarea, `[ui] local pipeline validation error: ${String(error)}`);

View File

@@ -1,7 +1,7 @@
{
"name": "kb-demo-app",
"private": true,
"version": "0.7.33",
"version": "0.7.34",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -161,6 +161,12 @@ pub(crate) struct DemoPipeline2LocalPipelineValidationReport {
/// Total decoded events with unknown classification.
#[ts(type = "number")]
pub decoded_unknown_event_count: i64,
/// Total persisted liquidity events.
#[ts(type = "number")]
pub liquidity_event_count: i64,
/// Total persisted pool lifecycle events.
#[ts(type = "number")]
pub pool_lifecycle_event_count: i64,
/// Number of entries currently exposed by the DEX support matrix.
#[ts(type = "number")]
pub dex_support_matrix_entry_count: i64,
@@ -271,6 +277,12 @@ pub(crate) struct DemoPipeline2LocalPipelineDiagnosticSummary {
/// Total decoded events with unknown classification.
#[ts(type = "number")]
pub decoded_unknown_event_count: i64,
/// Total persisted liquidity events.
#[ts(type = "number")]
pub liquidity_event_count: i64,
/// Total persisted pool lifecycle events.
#[ts(type = "number")]
pub pool_lifecycle_event_count: i64,
/// Whether the local persisted pipeline has no blocking diagnostic issue.
pub diagnostics_clean: bool,
/// Number of blocking diagnostic issues.
@@ -1075,7 +1087,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.33_pair_trading_readiness".to_string(),
None => "0.7.34_non_trade_liquidity_lifecycle".to_string(),
};
let run_result = match profile_code.as_str() {
"0.7.27" | "0.7.27_dexes_non_regression" => {
@@ -1099,6 +1111,9 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
"0.7.33" | "0.7.33_pair_trading_readiness" => {
service.validate_v0_7_33_current_database().await
},
"0.7.34" | "0.7.34_non_trade_liquidity_lifecycle" => {
service.validate_v0_7_34_current_database().await
},
other => Err(kb_lib::Error::InvalidState(format!(
"unsupported local pipeline validation profile: {other}"
))),
@@ -1528,6 +1543,8 @@ fn demo_pipeline2_map_local_validation_report(
decoded_non_trade_useful_event_count: report.decoded_non_trade_useful_event_count,
decoded_non_actionable_trade_event_count: report.decoded_non_actionable_trade_event_count,
decoded_unknown_event_count: report.decoded_unknown_event_count,
liquidity_event_count: report.liquidity_event_count,
pool_lifecycle_event_count: report.pool_lifecycle_event_count,
dex_support_matrix_entry_count: report.dex_support_matrix_entry_count,
dex_support_matrix,
issues,
@@ -1654,6 +1671,8 @@ fn demo_pipeline2_map_local_diagnostics_summary(
decoded_non_trade_useful_event_count: summary.decoded_non_trade_useful_event_count,
decoded_non_actionable_trade_event_count: summary.decoded_non_actionable_trade_event_count,
decoded_unknown_event_count: summary.decoded_unknown_event_count,
liquidity_event_count: summary.liquidity_event_count,
pool_lifecycle_event_count: summary.pool_lifecycle_event_count,
diagnostics_clean: summary.diagnostics_clean,
blocking_issue_count: summary.blocking_issue_count,
missing_trade_event_count: summary.missing_trade_event_count,

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "kb-demo-app",
"version": "0.7.33",
"version": "0.7.34",
"identifier": "com.sasedev.kb-demo-app",
"build": {
"beforeDevCommand": "npm run dev",