This commit is contained in:
2026-05-14 14:24:29 +02:00
parent edc8da02a3
commit 403f271083
12 changed files with 291 additions and 13 deletions

View File

@@ -66,4 +66,5 @@
0.7.33 - Ajout de la classification diagnostique `pairTradingReadiness` pour les paires, avec `quoteAssetClass`, `tradingRouteRequired`, résumé `pairTradingReadinessSummaries`, profil de validation `0.7.33_pair_trading_readiness` et mise à jour de la sélection UI Demo Pipeline 2 sans modifier la matérialisation trade/candle. 0.7.33 - Ajout de la classification diagnostique `pairTradingReadiness` pour les paires, avec `quoteAssetClass`, `tradingRouteRequired`, résumé `pairTradingReadinessSummaries`, profil de validation `0.7.33_pair_trading_readiness` et mise à jour de la sélection UI Demo Pipeline 2 sans modifier la matérialisation trade/candle.
0.7.34 - Ajout du profil `0.7.34_non_trade_liquidity_lifecycle`, matérialisation des tables non-trade liquidité/lifecycle, warning non bloquant pour DEX attendus absents du corpus local, première tranche DLMM : `add_liquidity`, `remove_liquidity`, `initialize_position`, `initialize_bin_array`, intégration de la matérialisation non-trade dans les backfills token/pool ciblés, et distinction `PositionOpen`/`PositionClose` dans `LiquidityEventKind`. 0.7.34 - Ajout du profil `0.7.34_non_trade_liquidity_lifecycle`, matérialisation des tables non-trade liquidité/lifecycle, warning non bloquant pour DEX attendus absents du corpus local, première tranche DLMM : `add_liquidity`, `remove_liquidity`, `initialize_position`, `initialize_bin_array`, intégration de la matérialisation non-trade dans les backfills token/pool ciblés, et distinction `PositionOpen`/`PositionClose` dans `LiquidityEventKind`.
0.7.35 - Ajout du profil `0.7.35_non_trade_fee_reward_admin`, matérialisation des événements non-trade fees/rewards/admin, raccordement aux diagnostics locaux et maintien strict de linvariant : aucun fee/reward/admin ne peut produire de trade, metric ou candle. 0.7.35 - Ajout du profil `0.7.35_non_trade_fee_reward_admin`, matérialisation des événements non-trade fees/rewards/admin, raccordement aux diagnostics locaux et maintien strict de linvariant : aucun fee/reward/admin ne peut produire de trade, metric ou candle.
0.7.36 - Consolidation de la famille Meteora : corpus mixte `meteora_damm_v1`, `meteora_damm_v2`, `meteora_dbc` et `meteora_dlmm`, correction des discriminants DAMM v2 / DBC, validation du profil `0.7.36_meteora_family_consolidation`, et reclassement explicite des swaps DAMM v2 / DBC sans payload montant/prix en `non_actionable_trade` afin déviter tout trade/candle artificiel. 0.7.36 - Consolidation de la famille Meteora : corpus mixte `meteora_damm_v1`, `meteora_damm_v2`, `meteora_dbc` et `meteora_dlmm`, correction des discriminants DAMM v2 / DBC, validation du profil `0.7.36_meteora_family_consolidation`, et reclassement explicite des swaps DAMM v2 / DBC sans payload montant/prix en `non_actionable_trade` afin déviter tout trade/candle artificiel.
0.7.37 - Première tranche metadata/catalog : ajout du profil `0.7.37_token_metadata_catalog_enrichment`, exposition des compteurs metadata dans diagnostics/validation et raccordement UI Demo Pipeline 2 sans rendre les metadata manquantes bloquantes.

View File

@@ -8,7 +8,7 @@ members = [
] ]
[workspace.package] [workspace.package]
version = "0.7.36-D" version = "0.7.37"
edition = "2024" edition = "2024"
license = "MIT" license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-bobobot" repository = "https://git.sasedev.com/Sasedev/khadhroony-bobobot"

View File

@@ -4,7 +4,7 @@
`khadhroony-bobobot` est un workspace Rust destiné à la détection, au décodage, à lanalyse et, à terme, au trading semi-automatisé de tokens Solana. `khadhroony-bobobot` est un workspace Rust destiné à la détection, au décodage, à lanalyse et, à terme, au trading semi-automatisé de tokens Solana.
Le README précédent décrivait surtout létat `0.3.1`. Ce fichier reflète létat de reprise autour de `0.7.36` et ouvre le travail `0.7.37` : le socle transport HTTP/WS, la résolution transactionnelle, le modèle SQLite, plusieurs connecteurs DEX, les candles, les signaux analytiques, la validation locale et une matrice DEX commune existent déjà. Le README précédent décrivait surtout létat `0.3.1`. Ce fichier reflète létat de reprise autour de `0.7.37-A` : le socle transport HTTP/WS, la résolution transactionnelle, le modèle SQLite, plusieurs connecteurs DEX, les candles, les signaux analytiques, la validation locale et une matrice DEX commune existent déjà.
## 1. Objectif ## 1. Objectif
@@ -31,7 +31,7 @@ Le workspace contient deux crates principales.
La logique métier doit rester dans `kb_lib`. `kb_demo_app` doit rester une façade UI/Tauri et ne doit pas récupérer de logique Solana ou DEX profonde. La logique métier doit rester dans `kb_lib`. `kb_demo_app` doit rester une façade UI/Tauri et ne doit pas récupérer de logique Solana ou DEX profonde.
## 3. État actuel autour de `0.7.36` ## 3. État actuel autour de `0.7.37-A`
### 3.1. Socle stabilisé à ne pas refactorer maintenant ### 3.1. Socle stabilisé à ne pas refactorer maintenant
@@ -232,7 +232,7 @@ Les tests peuvent rester plus souples lorsque cela clarifie le test.
## 8. Priorité immédiate ## 8. Priorité immédiate
La prochaine étape est `0.7.37_token_metadata_catalog_enrichment`. La phase actuelle est `0.7.37_token_metadata_catalog_enrichment`.
Objectif : rendre le catalogue local exploitable visuellement et analytiquement sans toucher aux invariants de décodage/trade validés en `0.7.36`. Objectif : rendre le catalogue local exploitable visuellement et analytiquement sans toucher aux invariants de décodage/trade validés en `0.7.36`.

View File

@@ -915,6 +915,13 @@ Réalisé :
### 6.069. Version `0.7.37` — Token metadata et catalogue local ### 6.069. Version `0.7.37` — Token metadata et catalogue local
Objectif : rendre le catalogue local exploitable et lisible avant dajouter davantage de launch surfaces. Objectif : rendre le catalogue local exploitable et lisible avant dajouter davantage de launch surfaces.
Réalisé en `0.7.37-A` :
- ajout du profil `0.7.37_token_metadata_catalog_enrichment` ;
- exposition des compteurs metadata/catalog dans les diagnostics et le rapport de validation ;
- raccordement UI Demo Pipeline 2 au profil `0.7.37` ;
- maintien volontaire du caractère non bloquant des metadata manquantes.
À faire : À faire :
- ajouter ou consolider un registre local des mints connus et stables : `SOL`, `WSOL`, `USDC`, `USDT`, puis autres mints seulement si vérifiés ; - ajouter ou consolider un registre local des mints connus et stables : `SOL`, `WSOL`, `USDC`, `USDT`, puis autres mints seulement si vérifiés ;
@@ -1236,7 +1243,7 @@ Le projet doit maintenir au minimum :
## 12. Priorité immédiate ## 12. Priorité immédiate
La priorité immédiate est désormais `0.7.37_token_metadata_catalog_enrichment`. La priorité immédiate reste de terminer `0.7.37_token_metadata_catalog_enrichment` par le backfill metadata effectif et le rafraîchissement des symboles de paires.
Ordre de travail recommandé : Ordre de travail recommandé :

View File

@@ -166,7 +166,8 @@
<div class="mb-3"> <div class="mb-3">
<label for="demoPipeline2ValidationProfileSelect" class="form-label">Validation profile</label> <label for="demoPipeline2ValidationProfileSelect" class="form-label">Validation profile</label>
<select id="demoPipeline2ValidationProfileSelect" class="form-select"> <select id="demoPipeline2ValidationProfileSelect" class="form-select">
<option value="0.7.36_meteora_family_consolidation" selected>0.7.36Meteora family consolidation</option> <option value="0.7.37_token_metadata_catalog_enrichment" selected>0.7.37token metadata/catalog enrichment</option>
<option value="0.7.36_meteora_family_consolidation">0.7.36 — Meteora family consolidation</option>
<option value="0.7.35_non_trade_fee_reward_admin">0.7.35 — non-trade fee/reward admin</option> <option value="0.7.35_non_trade_fee_reward_admin">0.7.35 — non-trade fee/reward admin</option>
<option value="0.7.34_non_trade_liquidity_lifecycle">0.7.34 — non-trade liquidity/lifecycle</option> <option value="0.7.34_non_trade_liquidity_lifecycle">0.7.34 — non-trade liquidity/lifecycle</option>
<option value="0.7.33_pair_trading_readiness">0.7.33 — pair trading readiness</option> <option value="0.7.33_pair_trading_readiness">0.7.33 — pair trading readiness</option>

View File

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

View File

@@ -167,6 +167,39 @@ pub(crate) struct DemoPipeline2LocalPipelineValidationReport {
/// Total persisted pool lifecycle events. /// Total persisted pool lifecycle events.
#[ts(type = "number")] #[ts(type = "number")]
pub pool_lifecycle_event_count: i64, pub pool_lifecycle_event_count: i64,
/// Total persisted fee events.
#[ts(type = "number")]
pub fee_event_count: i64,
/// Total persisted reward events.
#[ts(type = "number")]
pub reward_event_count: i64,
/// Total persisted pool administration events.
#[ts(type = "number")]
pub pool_admin_event_count: i64,
/// Total known tokens.
#[ts(type = "number")]
pub token_count: i64,
/// Total tokens missing symbol or name.
#[ts(type = "number")]
pub token_metadata_missing_count: i64,
/// Total tokens used by trade-materialized pairs that still miss symbol or name.
#[ts(type = "number")]
pub tradable_token_metadata_missing_count: i64,
/// Total quote-side tokens used by pairs that still miss symbol or name.
#[ts(type = "number")]
pub quote_token_metadata_missing_count: i64,
/// Total pairs whose display symbol is missing or still falls back to raw mints.
#[ts(type = "number")]
pub pair_symbol_fallback_count: i64,
/// Total pairs whose display symbol is present and does not include raw mints.
#[ts(type = "number")]
pub pair_symbol_resolved_count: i64,
/// Total pairs whose quote token is WSOL.
#[ts(type = "number")]
pub wsol_quote_pair_count: i64,
/// Total pairs whose quote token is a known stable quote.
#[ts(type = "number")]
pub stable_quote_pair_count: i64,
/// Number of entries currently exposed by the DEX support matrix. /// Number of entries currently exposed by the DEX support matrix.
#[ts(type = "number")] #[ts(type = "number")]
pub dex_support_matrix_entry_count: i64, pub dex_support_matrix_entry_count: i64,
@@ -283,6 +316,15 @@ pub(crate) struct DemoPipeline2LocalPipelineDiagnosticSummary {
/// Total persisted pool lifecycle events. /// Total persisted pool lifecycle events.
#[ts(type = "number")] #[ts(type = "number")]
pub pool_lifecycle_event_count: i64, pub pool_lifecycle_event_count: i64,
/// Total persisted fee events.
#[ts(type = "number")]
pub fee_event_count: i64,
/// Total persisted reward events.
#[ts(type = "number")]
pub reward_event_count: i64,
/// Total persisted pool administration events.
#[ts(type = "number")]
pub pool_admin_event_count: i64,
/// Whether the local persisted pipeline has no blocking diagnostic issue. /// Whether the local persisted pipeline has no blocking diagnostic issue.
pub diagnostics_clean: bool, pub diagnostics_clean: bool,
/// Number of blocking diagnostic issues. /// Number of blocking diagnostic issues.
@@ -333,6 +375,24 @@ pub(crate) struct DemoPipeline2LocalPipelineDiagnosticSummary {
/// Total tokens missing symbol or name. /// Total tokens missing symbol or name.
#[ts(type = "number")] #[ts(type = "number")]
pub token_metadata_missing_count: i64, pub token_metadata_missing_count: i64,
/// Total tokens used by trade-materialized pairs that still miss symbol or name.
#[ts(type = "number")]
pub tradable_token_metadata_missing_count: i64,
/// Total quote-side tokens used by pairs that still miss symbol or name.
#[ts(type = "number")]
pub quote_token_metadata_missing_count: i64,
/// Total pairs whose display symbol is missing or still falls back to raw mints.
#[ts(type = "number")]
pub pair_symbol_fallback_count: i64,
/// Total pairs whose display symbol is present and does not include raw mints.
#[ts(type = "number")]
pub pair_symbol_resolved_count: i64,
/// Total pairs whose quote token is WSOL.
#[ts(type = "number")]
pub wsol_quote_pair_count: i64,
/// Total pairs whose quote token is a known stable quote.
#[ts(type = "number")]
pub stable_quote_pair_count: i64,
/// Total known pools. /// Total known pools.
#[ts(type = "number")] #[ts(type = "number")]
pub pool_count: i64, pub pool_count: i64,
@@ -1087,7 +1147,7 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
let service = kb_lib::LocalPipelineValidationService::new(database.clone()); let service = kb_lib::LocalPipelineValidationService::new(database.clone());
let profile_code = match request { let profile_code = match request {
Some(request) => request.profile_code, Some(request) => request.profile_code,
None => "0.7.36_meteora_family_consolidation".to_string(), None => "0.7.37_token_metadata_catalog_enrichment".to_string(),
}; };
let run_result = match profile_code.as_str() { let run_result = match profile_code.as_str() {
"0.7.27" | "0.7.27_dexes_non_regression" => { "0.7.27" | "0.7.27_dexes_non_regression" => {
@@ -1120,6 +1180,9 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
"0.7.36" | "0.7.36_meteora_family_consolidation" => { "0.7.36" | "0.7.36_meteora_family_consolidation" => {
service.validate_v0_7_36_current_database().await service.validate_v0_7_36_current_database().await
}, },
"0.7.37" | "0.7.37_token_metadata_catalog_enrichment" => {
service.validate_v0_7_37_current_database().await
},
other => Err(kb_lib::Error::InvalidState(format!( other => Err(kb_lib::Error::InvalidState(format!(
"unsupported local pipeline validation profile: {other}" "unsupported local pipeline validation profile: {other}"
))), ))),
@@ -1551,6 +1614,17 @@ fn demo_pipeline2_map_local_validation_report(
decoded_unknown_event_count: report.decoded_unknown_event_count, decoded_unknown_event_count: report.decoded_unknown_event_count,
liquidity_event_count: report.liquidity_event_count, liquidity_event_count: report.liquidity_event_count,
pool_lifecycle_event_count: report.pool_lifecycle_event_count, pool_lifecycle_event_count: report.pool_lifecycle_event_count,
fee_event_count: report.fee_event_count,
reward_event_count: report.reward_event_count,
pool_admin_event_count: report.pool_admin_event_count,
token_count: report.token_count,
token_metadata_missing_count: report.token_metadata_missing_count,
tradable_token_metadata_missing_count: report.tradable_token_metadata_missing_count,
quote_token_metadata_missing_count: report.quote_token_metadata_missing_count,
pair_symbol_fallback_count: report.pair_symbol_fallback_count,
pair_symbol_resolved_count: report.pair_symbol_resolved_count,
wsol_quote_pair_count: report.wsol_quote_pair_count,
stable_quote_pair_count: report.stable_quote_pair_count,
dex_support_matrix_entry_count: report.dex_support_matrix_entry_count, dex_support_matrix_entry_count: report.dex_support_matrix_entry_count,
dex_support_matrix, dex_support_matrix,
issues, issues,
@@ -1679,6 +1753,9 @@ fn demo_pipeline2_map_local_diagnostics_summary(
decoded_unknown_event_count: summary.decoded_unknown_event_count, decoded_unknown_event_count: summary.decoded_unknown_event_count,
liquidity_event_count: summary.liquidity_event_count, liquidity_event_count: summary.liquidity_event_count,
pool_lifecycle_event_count: summary.pool_lifecycle_event_count, pool_lifecycle_event_count: summary.pool_lifecycle_event_count,
fee_event_count: summary.fee_event_count,
reward_event_count: summary.reward_event_count,
pool_admin_event_count: summary.pool_admin_event_count,
diagnostics_clean: summary.diagnostics_clean, diagnostics_clean: summary.diagnostics_clean,
blocking_issue_count: summary.blocking_issue_count, blocking_issue_count: summary.blocking_issue_count,
missing_trade_event_count: summary.missing_trade_event_count, missing_trade_event_count: summary.missing_trade_event_count,
@@ -1701,6 +1778,12 @@ fn demo_pipeline2_map_local_diagnostics_summary(
duplicate_candle_bucket_count: summary.duplicate_candle_bucket_count, duplicate_candle_bucket_count: summary.duplicate_candle_bucket_count,
token_count: summary.token_count, token_count: summary.token_count,
token_metadata_missing_count: summary.token_metadata_missing_count, token_metadata_missing_count: summary.token_metadata_missing_count,
tradable_token_metadata_missing_count: summary.tradable_token_metadata_missing_count,
quote_token_metadata_missing_count: summary.quote_token_metadata_missing_count,
pair_symbol_fallback_count: summary.pair_symbol_fallback_count,
pair_symbol_resolved_count: summary.pair_symbol_resolved_count,
wsol_quote_pair_count: summary.wsol_quote_pair_count,
stable_quote_pair_count: summary.stable_quote_pair_count,
pool_count: summary.pool_count, pool_count: summary.pool_count,
pair_count: summary.pair_count, pair_count: summary.pair_count,
pair_gap_counter_semantics: summary.pair_gap_counter_semantics, pair_gap_counter_semantics: summary.pair_gap_counter_semantics,

View File

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

View File

@@ -71,6 +71,18 @@ pub struct LocalPipelineDiagnosticSummaryDto {
pub token_count: i64, pub token_count: i64,
/// Total tokens missing symbol or name. /// Total tokens missing symbol or name.
pub token_metadata_missing_count: i64, pub token_metadata_missing_count: i64,
/// Total tokens used by trade-materialized pairs that still miss symbol or name.
pub tradable_token_metadata_missing_count: i64,
/// Total quote-side tokens used by pairs that still miss symbol or name.
pub quote_token_metadata_missing_count: i64,
/// Total pairs whose display symbol is missing or still falls back to raw mints.
pub pair_symbol_fallback_count: i64,
/// Total pairs whose display symbol is present and does not include raw mints.
pub pair_symbol_resolved_count: i64,
/// Total pairs whose quote token is WSOL.
pub wsol_quote_pair_count: i64,
/// Total pairs whose quote token is a known stable quote.
pub stable_quote_pair_count: i64,
/// Total known pools. /// Total known pools.
pub pool_count: i64, pub pool_count: i64,
/// Total known pairs. /// Total known pairs.
@@ -413,6 +425,18 @@ pub struct LocalPipelineDiagnosticCountersDto {
pub token_count: i64, pub token_count: i64,
/// Total tokens missing metadata. /// Total tokens missing metadata.
pub token_metadata_missing_count: i64, pub token_metadata_missing_count: i64,
/// Total tokens used by trade-materialized pairs that still miss metadata.
pub tradable_token_metadata_missing_count: i64,
/// Total quote-side tokens used by pairs that still miss metadata.
pub quote_token_metadata_missing_count: i64,
/// Total pairs whose display symbol is missing or falls back to raw mints.
pub pair_symbol_fallback_count: i64,
/// Total pairs whose display symbol is resolved without raw mints.
pub pair_symbol_resolved_count: i64,
/// Total pairs whose quote token is WSOL.
pub wsol_quote_pair_count: i64,
/// Total pairs whose quote token is a known stable quote.
pub stable_quote_pair_count: i64,
/// Total known pools. /// Total known pools.
pub pool_count: i64, pub pool_count: i64,
/// Total known pairs. /// Total known pairs.
@@ -473,6 +497,12 @@ pub(crate) struct LocalPipelineDiagnosticCountersRow {
pub(crate) duplicate_candle_bucket_count: i64, pub(crate) duplicate_candle_bucket_count: i64,
pub(crate) token_count: i64, pub(crate) token_count: i64,
pub(crate) token_metadata_missing_count: i64, pub(crate) token_metadata_missing_count: i64,
pub(crate) tradable_token_metadata_missing_count: i64,
pub(crate) quote_token_metadata_missing_count: i64,
pub(crate) pair_symbol_fallback_count: i64,
pub(crate) pair_symbol_resolved_count: i64,
pub(crate) wsol_quote_pair_count: i64,
pub(crate) stable_quote_pair_count: i64,
pub(crate) pool_count: i64, pub(crate) pool_count: i64,
pub(crate) pair_count: i64, pub(crate) pair_count: i64,
pub(crate) literal_pair_without_trade_count: i64, pub(crate) literal_pair_without_trade_count: i64,

View File

@@ -187,10 +187,75 @@ SELECT
SELECT COUNT(*) SELECT COUNT(*)
FROM k_sol_tokens FROM k_sol_tokens
WHERE symbol IS NULL WHERE symbol IS NULL
OR symbol = '' OR TRIM(symbol) = ''
OR name IS NULL OR name IS NULL
OR name = '' OR TRIM(name) = ''
) AS token_metadata_missing_count, ) AS token_metadata_missing_count,
(
SELECT COUNT(DISTINCT token.id)
FROM k_sol_tokens token
JOIN (
SELECT pair.base_token_id AS token_id
FROM k_sol_pairs pair
JOIN k_sol_trade_events te ON te.pair_id = pair.id
UNION
SELECT pair.quote_token_id AS token_id
FROM k_sol_pairs pair
JOIN k_sol_trade_events te ON te.pair_id = pair.id
) tradable_pair_token ON tradable_pair_token.token_id = token.id
WHERE token.symbol IS NULL
OR TRIM(token.symbol) = ''
OR token.name IS NULL
OR TRIM(token.name) = ''
) AS tradable_token_metadata_missing_count,
(
SELECT COUNT(DISTINCT quote_token.id)
FROM k_sol_pairs pair
JOIN k_sol_tokens quote_token ON quote_token.id = pair.quote_token_id
WHERE quote_token.symbol IS NULL
OR TRIM(quote_token.symbol) = ''
OR quote_token.name IS NULL
OR TRIM(quote_token.name) = ''
) AS quote_token_metadata_missing_count,
(
SELECT COUNT(*)
FROM k_sol_pairs pair
JOIN k_sol_tokens base_token ON base_token.id = pair.base_token_id
JOIN k_sol_tokens quote_token ON quote_token.id = pair.quote_token_id
WHERE pair.symbol IS NULL
OR TRIM(pair.symbol) = ''
OR pair.symbol = base_token.mint || '/' || quote_token.mint
OR instr(pair.symbol, base_token.mint) > 0
OR instr(pair.symbol, quote_token.mint) > 0
) AS pair_symbol_fallback_count,
(
SELECT COUNT(*)
FROM k_sol_pairs pair
JOIN k_sol_tokens base_token ON base_token.id = pair.base_token_id
JOIN k_sol_tokens quote_token ON quote_token.id = pair.quote_token_id
WHERE pair.symbol IS NOT NULL
AND TRIM(pair.symbol) != ''
AND pair.symbol != base_token.mint || '/' || quote_token.mint
AND instr(pair.symbol, base_token.mint) = 0
AND instr(pair.symbol, quote_token.mint) = 0
) AS pair_symbol_resolved_count,
(
SELECT COUNT(*)
FROM k_sol_pairs pair
JOIN k_sol_tokens quote_token ON quote_token.id = pair.quote_token_id
WHERE quote_token.mint = 'So11111111111111111111111111111111111111112'
) AS wsol_quote_pair_count,
(
SELECT COUNT(*)
FROM k_sol_pairs pair
JOIN k_sol_tokens quote_token ON quote_token.id = pair.quote_token_id
WHERE quote_token.mint IN (
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB',
'USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB',
'JuprjznTrTSp2UFa3ZBUFgwdAmtZCq4MQCwysN55USD'
)
) AS stable_quote_pair_count,
(SELECT COUNT(*) FROM k_sol_pools) AS pool_count, (SELECT COUNT(*) FROM k_sol_pools) AS pool_count,
(SELECT COUNT(*) FROM k_sol_pairs) AS pair_count, (SELECT COUNT(*) FROM k_sol_pairs) AS pair_count,
( (
@@ -384,6 +449,12 @@ SELECT
duplicate_candle_bucket_count: row.duplicate_candle_bucket_count, duplicate_candle_bucket_count: row.duplicate_candle_bucket_count,
token_count: row.token_count, token_count: row.token_count,
token_metadata_missing_count: row.token_metadata_missing_count, token_metadata_missing_count: row.token_metadata_missing_count,
tradable_token_metadata_missing_count: row.tradable_token_metadata_missing_count,
quote_token_metadata_missing_count: row.quote_token_metadata_missing_count,
pair_symbol_fallback_count: row.pair_symbol_fallback_count,
pair_symbol_resolved_count: row.pair_symbol_resolved_count,
wsol_quote_pair_count: row.wsol_quote_pair_count,
stable_quote_pair_count: row.stable_quote_pair_count,
pool_count: row.pool_count, pool_count: row.pool_count,
pair_count: row.pair_count, pair_count: row.pair_count,
literal_pair_without_trade_count: row.literal_pair_without_trade_count, literal_pair_without_trade_count: row.literal_pair_without_trade_count,

View File

@@ -179,6 +179,12 @@ impl LocalPipelineDiagnosticsService {
duplicate_candle_bucket_count: counters.duplicate_candle_bucket_count, duplicate_candle_bucket_count: counters.duplicate_candle_bucket_count,
token_count: counters.token_count, token_count: counters.token_count,
token_metadata_missing_count: counters.token_metadata_missing_count, token_metadata_missing_count: counters.token_metadata_missing_count,
tradable_token_metadata_missing_count: counters.tradable_token_metadata_missing_count,
quote_token_metadata_missing_count: counters.quote_token_metadata_missing_count,
pair_symbol_fallback_count: counters.pair_symbol_fallback_count,
pair_symbol_resolved_count: counters.pair_symbol_resolved_count,
wsol_quote_pair_count: counters.wsol_quote_pair_count,
stable_quote_pair_count: counters.stable_quote_pair_count,
pool_count: counters.pool_count, pool_count: counters.pool_count,
pair_count: counters.pair_count, pair_count: counters.pair_count,
pair_gap_counter_semantics: "blocking_actionable_pairs_only".to_string(), pair_gap_counter_semantics: "blocking_actionable_pairs_only".to_string(),

View File

@@ -254,6 +254,18 @@ impl LocalPipelineValidationConfig {
config.allow_unexpected_dexes = true; config.allow_unexpected_dexes = true;
return config; return config;
} }
/// Builds the `0.7.37` token metadata/catalog enrichment validation config.
///
/// This profile keeps the `0.7.36` Meteora-family checks and exposes
/// token metadata and pair-symbol diagnostics. Missing metadata remains
/// informational in this profile; refresh/materialization invariants stay
/// governed by the existing trade and candle checks.
pub fn v0_7_37_token_metadata_catalog_enrichment() -> Self {
let mut config = Self::v0_7_36_meteora_family_consolidation();
config.profile_code = "0.7.37_token_metadata_catalog_enrichment".to_string();
return config;
}
} }
/// A single local pipeline validation issue. /// A single local pipeline validation issue.
@@ -302,6 +314,22 @@ pub struct LocalPipelineValidationReportDto {
pub reward_event_count: i64, pub reward_event_count: i64,
/// Total persisted pool administration events. /// Total persisted pool administration events.
pub pool_admin_event_count: i64, pub pool_admin_event_count: i64,
/// Total known tokens.
pub token_count: i64,
/// Total tokens missing symbol or name.
pub token_metadata_missing_count: i64,
/// Total tokens used by trade-materialized pairs that still miss symbol or name.
pub tradable_token_metadata_missing_count: i64,
/// Total quote-side tokens used by pairs that still miss symbol or name.
pub quote_token_metadata_missing_count: i64,
/// Total pairs whose display symbol is missing or still falls back to raw mints.
pub pair_symbol_fallback_count: i64,
/// Total pairs whose display symbol is present and does not include raw mints.
pub pair_symbol_resolved_count: i64,
/// Total pairs whose quote token is WSOL.
pub wsol_quote_pair_count: i64,
/// Total pairs whose quote token is a known stable quote.
pub stable_quote_pair_count: i64,
/// Number of entries currently exposed by the DEX support matrix. /// Number of entries currently exposed by the DEX support matrix.
pub dex_support_matrix_entry_count: i64, pub dex_support_matrix_entry_count: i64,
/// DEX support matrix snapshot exposed with the validation report. /// DEX support matrix snapshot exposed with the validation report.
@@ -448,6 +476,15 @@ impl LocalPipelineValidationService {
let config = crate::LocalPipelineValidationConfig::v0_7_36_meteora_family_consolidation(); let config = crate::LocalPipelineValidationConfig::v0_7_36_meteora_family_consolidation();
return self.validate_current_database(&config).await; return self.validate_current_database(&config).await;
} }
/// Diagnoses the current database with the `0.7.37` metadata/catalog profile.
pub async fn validate_v0_7_37_current_database(
&self,
) -> Result<crate::LocalPipelineValidationRunDto, crate::Error> {
let config =
crate::LocalPipelineValidationConfig::v0_7_37_token_metadata_catalog_enrichment();
return self.validate_current_database(&config).await;
}
} }
/// Validates a diagnostics summary without performing database access. /// Validates a diagnostics summary without performing database access.
@@ -568,7 +605,8 @@ pub fn validate_local_pipeline_diagnostics_summary(
let missing_expected_dex_is_warning = config.profile_code let missing_expected_dex_is_warning = config.profile_code
== "0.7.34_non_trade_liquidity_lifecycle" == "0.7.34_non_trade_liquidity_lifecycle"
|| config.profile_code == "0.7.35_non_trade_fee_reward_admin" || config.profile_code == "0.7.35_non_trade_fee_reward_admin"
|| config.profile_code == "0.7.36_meteora_family_consolidation"; || config.profile_code == "0.7.36_meteora_family_consolidation"
|| config.profile_code == "0.7.37_token_metadata_catalog_enrichment";
if config.require_all_expected_dexes || missing_expected_dex_is_warning { if config.require_all_expected_dexes || missing_expected_dex_is_warning {
for expected_dex_code in &expected_dex_codes { for expected_dex_code in &expected_dex_codes {
if !observed_dex_codes.contains(expected_dex_code) { if !observed_dex_codes.contains(expected_dex_code) {
@@ -643,6 +681,14 @@ pub fn validate_local_pipeline_diagnostics_summary(
fee_event_count: summary.fee_event_count, fee_event_count: summary.fee_event_count,
reward_event_count: summary.reward_event_count, reward_event_count: summary.reward_event_count,
pool_admin_event_count: summary.pool_admin_event_count, pool_admin_event_count: summary.pool_admin_event_count,
token_count: summary.token_count,
token_metadata_missing_count: summary.token_metadata_missing_count,
tradable_token_metadata_missing_count: summary.tradable_token_metadata_missing_count,
quote_token_metadata_missing_count: summary.quote_token_metadata_missing_count,
pair_symbol_fallback_count: summary.pair_symbol_fallback_count,
pair_symbol_resolved_count: summary.pair_symbol_resolved_count,
wsol_quote_pair_count: summary.wsol_quote_pair_count,
stable_quote_pair_count: summary.stable_quote_pair_count,
dex_support_matrix_entry_count: crate::dex_support_matrix_entries().len() as i64, dex_support_matrix_entry_count: crate::dex_support_matrix_entries().len() as i64,
dex_support_matrix: crate::dex_support_matrix_entry_dtos(), dex_support_matrix: crate::dex_support_matrix_entry_dtos(),
issues, issues,
@@ -873,6 +919,12 @@ mod tests {
duplicate_candle_bucket_count: 0, duplicate_candle_bucket_count: 0,
token_count: 22, token_count: 22,
token_metadata_missing_count: 0, token_metadata_missing_count: 0,
tradable_token_metadata_missing_count: 0,
quote_token_metadata_missing_count: 0,
pair_symbol_fallback_count: 4,
pair_symbol_resolved_count: 23,
wsol_quote_pair_count: 20,
stable_quote_pair_count: 3,
pool_count: 27, pool_count: 27,
pair_count: 27, pair_count: 27,
pair_gap_counter_semantics: "blocking_actionable_pairs_only".to_string(), pair_gap_counter_semantics: "blocking_actionable_pairs_only".to_string(),
@@ -1221,6 +1273,33 @@ mod tests {
assert!(report.expected_dex_codes.contains(&"meteora_dlmm".to_string())); assert!(report.expected_dex_codes.contains(&"meteora_dlmm".to_string()));
} }
#[test]
fn validation_accepts_0_7_37_metadata_catalog_summary() {
let mut summary = make_0_7_28_summary_with_meteora();
summary.token_count = 108;
summary.token_metadata_missing_count = 102;
summary.tradable_token_metadata_missing_count = 12;
summary.quote_token_metadata_missing_count = 4;
summary.pair_symbol_fallback_count = 16;
summary.pair_symbol_resolved_count = 5;
summary.wsol_quote_pair_count = 13;
summary.stable_quote_pair_count = 2;
let config =
crate::LocalPipelineValidationConfig::v0_7_37_token_metadata_catalog_enrichment();
let report = crate::validate_local_pipeline_diagnostics_summary(&summary, &config);
assert!(report.validation_passed);
assert_eq!(report.validation_profile_code, "0.7.37_token_metadata_catalog_enrichment");
assert_eq!(report.blocking_issue_count, 0);
assert_eq!(report.token_count, 108);
assert_eq!(report.token_metadata_missing_count, 102);
assert_eq!(report.tradable_token_metadata_missing_count, 12);
assert_eq!(report.quote_token_metadata_missing_count, 4);
assert_eq!(report.pair_symbol_fallback_count, 16);
assert_eq!(report.pair_symbol_resolved_count, 5);
assert_eq!(report.wsol_quote_pair_count, 13);
assert_eq!(report.stable_quote_pair_count, 2);
}
#[test] #[test]
fn validation_rejects_0_7_33_pair_trading_readiness_mismatch() { fn validation_rejects_0_7_33_pair_trading_readiness_mismatch() {
let mut summary = make_0_7_28_summary_with_meteora(); let mut summary = make_0_7_28_summary_with_meteora();