🔧 Fix database crate duplicate name errors (E0252)

- Removed duplicate re-exports in database/src/lib.rs
- Types are already imported at module level, no need to re-export
- Fixes compilation error that was blocking workspace build
This commit is contained in:
jgrusewski
2025-09-29 23:15:59 +02:00
parent c2b0a51c51
commit d2d9fc3f82
10 changed files with 82 additions and 74 deletions

View File

@@ -248,9 +248,8 @@ pub struct RegimePerformanceTracker {
regime_performance: HashMap<MarketRegime, RegimePerformance>,
/// Detection accuracy tracking
detection_accuracy: VecDeque<AccuracyMeasurement>,
/// False positive tracking
}
/// False positive tracking metrics
false_positives: VecDeque<FalsePositiveRecord>, }
/// Performance metrics for a specific regime
#[derive(Debug, Clone, Serialize, Deserialize)]

View File

@@ -60,6 +60,8 @@ use crate::transaction::{DatabaseTransaction, TransactionManager, TransactionSta
use crate::query::QueryBuilder;
use config::database::DatabaseConfig;
// Re-export commonly used types - Already imported above, no need to re-export
// serde imports removed - not needed
use sqlx::postgres::PgRow;
use sqlx::FromRow;

View File

@@ -302,7 +302,7 @@ impl FeatureRepository {
let conn = self.pool.get().await?;
// Using sqlx query builder pattern
let query =
let (query, params) =
if let Some(version) = feature_set_version {
(r#"SELECT features, last_updated, expires_at
FROM ml_feature_cache
@@ -347,40 +347,37 @@ impl FeatureRepository {
WHERE feature_set_id = $1
"#.to_string();
// Using sqlx query builder pattern instead of raw parameters
// Using sqlx query builder pattern
let mut query_builder = sqlx::QueryBuilder::new(
"SELECT feature_name, feature_value, computation_timestamp FROM ml_feature_vectors WHERE feature_set_id = "
);
query_builder.push_bind(feature_set_id);
let mut param_count = 1;
// Add entity filter
if !entity_ids.is_empty() {
param_count += 1;
query.push_str(&format!(" AND entity_id = ANY(${}) ", param_count));
params.push(&entity_ids);
query_builder.push(" AND entity_id = ANY(");
query_builder.push_bind(&entity_ids);
query_builder.push(")");
}
// Add time range filter
if let Some((start, end)) = time_range {
param_count += 1;
query.push_str(&format!(" AND timestamp >= ${} ", param_count));
params.push(&start);
param_count += 1;
query.push_str(&format!(" AND timestamp <= ${} ", param_count));
params.push(&end);
query_builder.push(" AND timestamp >= ");
query_builder.push_bind(start);
query_builder.push(" AND timestamp <= ");
query_builder.push_bind(end);
}
query.push_str(" ORDER BY timestamp DESC");
query_builder.push(" ORDER BY timestamp DESC");
// Add limit
if let Some(limit_val) = limit {
param_count += 1;
query.push_str(&format!(" LIMIT ${}", param_count));
params.push(&(limit_val as i64));
}
let rows = conn.query(&query, &params).await?;
query_builder.push(" LIMIT ");
query_builder.push_bind(limit_val as i64);
}
let query = query_builder.build();
let rows = query.fetch_all(&mut *conn).await?;
let mut results = Vec::new();
for row in rows {

View File

@@ -219,40 +219,37 @@ impl PerformanceRepository {
WHERE model_id = $1
"#.to_string();
// Using sqlx query builder pattern instead of raw parameters
// Using sqlx query builder pattern
let mut query_builder = sqlx::QueryBuilder::new(
"SELECT timestamp, metric_name, metric_value, metric_metadata FROM ml_model_performance WHERE model_id = "
);
query_builder.push_bind(model_id);
let mut param_count = 1;
// Add metric name filter
if let Some(ref names) = metric_names {
param_count += 1;
query.push_str(&format!(" AND metric_name = ANY(${}) ", param_count));
params.push(names);
query_builder.push(" AND metric_name = ANY(");
query_builder.push_bind(names);
query_builder.push(")");
}
// Add time range filter
if let Some((start, end)) = time_range {
param_count += 1;
query.push_str(&format!(" AND timestamp >= ${} ", param_count));
params.push(&start);
param_count += 1;
query.push_str(&format!(" AND timestamp <= ${} ", param_count));
params.push(&end);
query_builder.push(" AND timestamp >= ");
query_builder.push_bind(start);
query_builder.push(" AND timestamp <= ");
query_builder.push_bind(end);
}
query.push_str(" ORDER BY timestamp DESC");
query_builder.push(" ORDER BY timestamp DESC");
// Add limit
if let Some(limit_val) = limit {
param_count += 1;
query.push_str(&format!(" LIMIT ${}", param_count));
params.push(&(limit_val as i64));
query_builder.push(" LIMIT ");
query_builder.push_bind(limit_val as i64);
}
let rows = conn.query(&query, &params).await?;
let query = query_builder.build();
let rows = query.fetch_all(&mut *conn).await?;
let mut metrics = Vec::new();
for row in rows {
@@ -418,22 +415,21 @@ impl PerformanceRepository {
// Using sqlx query builder pattern
let query =
if let Some(model_id) = model_id {
(r#"SELECT id, model_id, model_name, alert_type, severity, metric_name,
threshold_value, actual_value, triggered_at, message, metadata
FROM ml_performance_alerts
WHERE model_id = $1 AND status = 'active'
ORDER BY triggered_at DESC"#.to_string(),
vec![&model_id])
} else {
(r#"SELECT id, model_id, model_name, alert_type, severity, metric_name,
threshold_value, actual_value, triggered_at, message, metadata
FROM ml_performance_alerts
WHERE status = 'active'
ORDER BY triggered_at DESC"#.to_string(),
vec![])
};
let (query, params) = if let Some(model_id) = model_id {
(r#"SELECT id, model_id, model_name, alert_type, severity, metric_name,
threshold_value, actual_value, triggered_at, message, metadata
FROM ml_performance_alerts
WHERE model_id = $1 AND status = 'active'
ORDER BY triggered_at DESC"#.to_string(),
vec![&model_id])
} else {
(r#"SELECT id, model_id, model_name, alert_type, severity, metric_name,
threshold_value, actual_value, triggered_at, message, metadata
FROM ml_performance_alerts
WHERE status = 'active'
ORDER BY triggered_at DESC"#.to_string(),
vec![])
};
let rows = conn.query(&query, &params).await?;
let mut alerts = Vec::new();

View File

@@ -1043,8 +1043,7 @@ impl ComplianceValidator {
// CRITICAL: Market abuse thresholds must be configurable, not hardcoded
// Different markets have different reporting thresholds - hardcoding could cause regulatory violations
let threshold = self.config.market_abuse_threshold
.ok_or_else(|| RiskError::ConfigurationError {
parameter: "market_abuse_threshold".to_owned(),
.ok_or_else(|| RiskError::Configuration {
message: "Market abuse threshold not configured - required for regulatory compliance".to_owned(),
})?;
if order_value > threshold {
@@ -1256,7 +1255,7 @@ impl ComplianceValidator {
order: &OrderInfo,
violations: &[RiskViolation],
warnings: &[ComplianceWarning],
) -> Result<Price, ComplianceError> {
) -> Result<Price, RiskError> {
let mut risk_score = Price::ZERO;
// Base risk from order size - use safe conversion helpers
@@ -1280,7 +1279,7 @@ impl ComplianceValidator {
let order_risk = f64_to_price_safe(order_value_f64 / 100_000.0, "order risk calculation")
.map_err(|e| {
error!("CRITICAL: Failed to calculate order risk - this could hide compliance violations: {}", e);
ComplianceError::ConversionError(format!("Failed to calculate order risk: {}", e))
RiskError::Calculation { operation: "order_risk_calculation".to_string(), reason: format!("Failed to calculate order risk: {}", e) }
})?;
let current_risk_f64 = decimal_to_f64_safe(
risk_score.to_decimal().unwrap_or(Decimal::ZERO),
@@ -1309,7 +1308,7 @@ impl ComplianceValidator {
f64_to_price_safe((violations.len() * 10) as f64, "violation risk calculation")
.map_err(|e| {
error!("CRITICAL: Failed to calculate violation risk - this could hide compliance issues: {}", e);
ComplianceError::ConversionError(format!("Failed to calculate violation risk: {}", e))
RiskError::Calculation { operation: "violation_risk_calculation".to_string(), reason: format!("Failed to calculate violation risk: {}", e) }
})?;
let violation_risk_f64 = decimal_to_f64_safe(
violation_risk.to_decimal().unwrap_or(Decimal::ZERO),

View File

@@ -325,6 +325,15 @@ pub enum RiskError {
/// Market data system error occurred
#[error("Market data error: {0}")]
MarketDataError(String),
/// Required data is unavailable for calculations
#[error("Data unavailable: {resource} - {reason}")]
DataUnavailable {
/// The data resource that is unavailable
resource: String,
/// Reason why the data is unavailable
reason: String,
},
}
/// Result type for risk management operations
@@ -500,8 +509,9 @@ impl RiskError {
RiskError::BrokerConnection { .. } => "BROKER_CONNECTION_ERROR",
RiskError::Connection { .. } => "CONNECTION_ERROR",
RiskError::MarketDataError(_) => "MARKET_DATA_ERROR",
RiskError::DataUnavailable { .. } => "DATA_UNAVAILABLE",
}
}
}
}
/// Convert from tokio timeout error

View File

@@ -1404,18 +1404,18 @@ impl PositionTracker {
position.base_position.unrealized_pnl = Price::from_f64(
ToPrimitive::to_f64(&unrealized_pnl)
.ok_or_else(|| RiskError::TypeConversion {
from: "Decimal".to_string(),
to: "f64".to_string(),
value: unrealized_pnl.to_string(),
from_type: "Decimal".to_string(),
to_type: "f64".to_string(),
reason: format!("invalid Decimal value {}", unrealized_pnl),
})?
)?;
position.volatility = market_data
.volatility
.map(|v| Price::from_f64(v)
.map_err(|_| RiskError::TypeConversion {
from: "f64".to_string(),
to: "Price".to_string(),
value: v.to_string(),
from_type: "f64".to_string(),
to_type: "Price".to_string(),
reason: format!("invalid f64 value {}", v),
})
).transpose()?;
position.last_updated = Utc::now();

View File

@@ -19,6 +19,7 @@ use num::ToPrimitive;
use uuid::Uuid;
use std::marker::Send;
use std::sync::Arc;
use tracing::error;
// ELIMINATED: Prelude import removed to force explicit imports
use rust_decimal::Decimal;
use common::{Position, Symbol, Price, OrderSide, Quantity};
@@ -1701,8 +1702,7 @@ impl RiskEngine {
.min(
safe_divide(
Decimal::try_from(self.config.position_limits.global_limit)
.map_err(|_| RiskError::ConfigurationError {
parameter: "global_limit".to_owned(),
.map_err(|_| RiskError::Configuration {
message: "Invalid global limit configuration".to_owned(),
})?
.into(),

View File

@@ -11,6 +11,7 @@ use std::collections::HashMap;
// ELIMINATED: Re-exports removed to force explicit imports
use common::types::{Price, Quantity, Symbol, Volume, OrderType, OrderSide};
use crate::error::RiskError;
// Note: Side is an alias for OrderSide - using canonical OrderSide from trading_engine
// Note: Side is an alias for OrderSide in common crate - both are available
@@ -606,6 +607,10 @@ pub struct ComplianceConfig {
pub position_limits: PositionLimits,
/// Number of days to retain audit records for compliance
pub audit_retention_days: u32,
/// Market abuse detection threshold
pub market_abuse_threshold: Option<Price>,
/// Large exposure threshold for regulatory reporting
pub large_exposure_threshold: Price,
}
/// Types of compliance warnings that can be issued

View File

@@ -141,15 +141,15 @@ impl EmergencyResponseSystem {
if metrics.max_drawdown.abs().to_decimal()
.map_err(|e| RiskError::TypeConversion {
from: "Price".to_string(),
to: "Decimal".to_string(),
value: metrics.max_drawdown.to_string(),
from_type: "Price".to_string(),
to_type: "Decimal".to_string(),
reason: format!("conversion failed: {}", e),
})?
>= Decimal::try_from(0.20)
.map_err(|e| RiskError::TypeConversion {
from: "f64".to_string(),
to: "Decimal".to_string(),
value: "0.20".to_string(),
from_type: "f64".to_string(),
to_type: "Decimal".to_string(),
reason: format!("conversion failed: {}", e),
})?
{
// 20% drawdown limit