🚨 ARCHITECTURAL DISASTER: THREE Competing Type Sources Discovered

## Critical Investigation Results

**DISASTER CONFIRMED**: Agents discovered THREE type sources instead of ONE:
1. foxhunt-common-types/ (SHOULD NOT EXIST - still active!)
2. trading_engine/src/types/ (massive duplication)
3. common/src/types.rs (depends on competing crate)

## Evidence of Violations
- foxhunt-common-types still in workspace members (line 86)
- common/Cargo.toml depends on foxhunt-common-types (line 48)
- 48+ duplicate type definitions across OrderSide, OrderStatus, OrderType
- Compilation failures due to competing imports

## Immediate Action Required
- Choose ONE canonical source
- DELETE foxhunt-common-types completely
- Consolidate ALL types to single source
- Fix THREE-WAY import chaos

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2025-09-26 15:33:34 +02:00
parent f58d14ccc3
commit ea9d8f2c88
87 changed files with 2192 additions and 817 deletions

View File

@@ -35,6 +35,9 @@ anyhow = "1.0"
# Logging
tracing = "0.1"
# Internal workspace crates
common = { path = "../common" }
[dev-dependencies]
tokio-test = "0.4"
tempfile = "3.0"

View File

@@ -5,7 +5,7 @@
//! database-agnostic while providing rich type safety.
use chrono::{DateTime, Utc};
use trading_engine::types::prelude::Decimal;
use common::prelude::*;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
@@ -118,55 +118,13 @@ impl Order {
/// Trading order side
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, sqlx::Type)]
#[sqlx(type_name = "order_side", rename_all = "lowercase")]
pub enum OrderSide {
Buy,
Sell,
}
// OrderSide now imported from canonical source
use common::prelude::OrderSide;
impl std::fmt::Display for OrderSide {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
OrderSide::Buy => write!(f, "Buy"),
OrderSide::Sell => write!(f, "Sell"),
}
}
}
// OrderType now imported from canonical source via trading_engine::types::prelude::OrderType
// Note: Database integration may require additional derive traits for OrderType in the canonical definition
/// Trading order type
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, sqlx::Type)]
#[sqlx(type_name = "order_type", rename_all = "lowercase")]
pub enum OrderType {
Market,
Limit,
Stop,
StopLimit,
TrailingStop,
}
/// Order status
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, sqlx::Type)]
#[sqlx(type_name = "order_status", rename_all = "lowercase")]
pub enum OrderStatus {
Pending,
Submitted,
PartiallyFilled,
Filled,
Cancelled,
Rejected,
Expired,
}
impl OrderStatus {
/// Check if the order is in a terminal state
pub fn is_terminal(&self) -> bool {
matches!(self, OrderStatus::Filled | OrderStatus::Cancelled | OrderStatus::Rejected | OrderStatus::Expired)
}
/// Check if the order is active (can be filled)
pub fn is_active(&self) -> bool {
matches!(self, OrderStatus::Submitted | OrderStatus::PartiallyFilled)
}
}
// OrderStatus now imported from canonical source via trading_engine::types::prelude::OrderStatus
/// Represents a trading position
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]

View File

@@ -6,7 +6,7 @@
use async_trait::async_trait;
use chrono::{DateTime, Utc};
use trading_engine::types::prelude::Decimal;
use trading_engine::types::prelude::{Decimal, Volume};
use sqlx::{Pool, Postgres, Row};
use uuid::Uuid;
@@ -146,7 +146,7 @@ pub struct OrderStats {
pub filled_orders: i64,
pub cancelled_orders: i64,
pub pending_orders: i64,
pub total_volume: Decimal,
pub total_volume: Volume,
pub avg_fill_rate: Decimal,
}
@@ -627,7 +627,7 @@ impl OrderRepository for PostgresOrderRepository {
let filled_orders: i64 = row.get("filled_orders");
let cancelled_orders: i64 = row.get("cancelled_orders");
let pending_orders: i64 = row.get("pending_orders");
let total_volume: Decimal = row.get("total_volume");
let total_volume: Volume = Volume::new(row.get::<Decimal, _>("total_volume")).unwrap_or(Volume::ZERO);
let avg_fill_rate = if total_orders > 0 {
Decimal::from(filled_orders) / Decimal::from(total_orders) * Decimal::from(100)