Move 17 library crates into crates/, CLI binary into bin/fxt, consolidate 10 test crates into testing/, split config crate from deployment config files. Root directory reduced from 38+ to ~17 directories. All Cargo.toml paths and build.rs proto refs updated. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
137 lines
6.3 KiB
PL/PgSQL
137 lines
6.3 KiB
PL/PgSQL
-- Test Database Schema for Integration Testing
|
|
-- Creates tables needed for database integration tests
|
|
|
|
-- Test trades table for testing trade persistence
|
|
CREATE TABLE IF NOT EXISTS test_trades (
|
|
id SERIAL PRIMARY KEY,
|
|
trade_id VARCHAR(100) UNIQUE NOT NULL,
|
|
symbol VARCHAR(20) NOT NULL,
|
|
side VARCHAR(10) NOT NULL CHECK (side IN ('BUY', 'SELL')),
|
|
quantity DECIMAL(20,8) NOT NULL CHECK (quantity > 0),
|
|
price DECIMAL(20,8) NOT NULL CHECK (price > 0),
|
|
commission DECIMAL(20,8) DEFAULT 0,
|
|
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
execution_venue VARCHAR(50) DEFAULT 'TEST_EXCHANGE',
|
|
order_id VARCHAR(100),
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Test positions table for testing position management
|
|
CREATE TABLE IF NOT EXISTS test_positions (
|
|
id SERIAL PRIMARY KEY,
|
|
account_id VARCHAR(50) NOT NULL,
|
|
symbol VARCHAR(20) NOT NULL,
|
|
quantity DECIMAL(20,8) NOT NULL,
|
|
average_price DECIMAL(20,8) NOT NULL,
|
|
market_value DECIMAL(20,8) NOT NULL,
|
|
unrealized_pnl DECIMAL(20,8) DEFAULT 0,
|
|
realized_pnl DECIMAL(20,8) DEFAULT 0,
|
|
last_updated TIMESTAMPTZ DEFAULT NOW(),
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
UNIQUE(account_id, symbol)
|
|
);
|
|
|
|
-- Test orders table for testing order lifecycle
|
|
CREATE TABLE IF NOT EXISTS test_orders (
|
|
id SERIAL PRIMARY KEY,
|
|
order_id VARCHAR(100) UNIQUE NOT NULL,
|
|
client_order_id VARCHAR(100),
|
|
account_id VARCHAR(50) NOT NULL,
|
|
symbol VARCHAR(20) NOT NULL,
|
|
side VARCHAR(10) NOT NULL CHECK (side IN ('BUY', 'SELL')),
|
|
order_type VARCHAR(20) NOT NULL CHECK (order_type IN ('MARKET', 'LIMIT', 'STOP', 'STOP_LIMIT')),
|
|
quantity DECIMAL(20,8) NOT NULL CHECK (quantity > 0),
|
|
price DECIMAL(20,8),
|
|
stop_price DECIMAL(20,8),
|
|
filled_quantity DECIMAL(20,8) DEFAULT 0,
|
|
remaining_quantity DECIMAL(20,8),
|
|
status VARCHAR(20) NOT NULL DEFAULT 'PENDING' CHECK (status IN ('PENDING', 'ACTIVE', 'FILLED', 'CANCELLED', 'REJECTED')),
|
|
time_in_force VARCHAR(10) DEFAULT 'DAY' CHECK (time_in_force IN ('DAY', 'GTC', 'IOC', 'FOK')),
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
expires_at TIMESTAMPTZ
|
|
);
|
|
|
|
-- Test executions table for testing execution tracking
|
|
CREATE TABLE IF NOT EXISTS test_executions (
|
|
id SERIAL PRIMARY KEY,
|
|
execution_id VARCHAR(100) UNIQUE NOT NULL,
|
|
order_id VARCHAR(100) NOT NULL,
|
|
trade_id VARCHAR(100),
|
|
symbol VARCHAR(20) NOT NULL,
|
|
side VARCHAR(10) NOT NULL CHECK (side IN ('BUY', 'SELL')),
|
|
quantity DECIMAL(20,8) NOT NULL CHECK (quantity > 0),
|
|
price DECIMAL(20,8) NOT NULL CHECK (price > 0),
|
|
commission DECIMAL(20,8) DEFAULT 0,
|
|
execution_venue VARCHAR(50) DEFAULT 'TEST_EXCHANGE',
|
|
executed_at TIMESTAMPTZ DEFAULT NOW(),
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Performance-optimized indexes for testing
|
|
CREATE INDEX IF NOT EXISTS idx_test_trades_symbol_timestamp ON test_trades(symbol, timestamp DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_test_trades_trade_id_hash ON test_trades USING HASH(trade_id);
|
|
CREATE INDEX IF NOT EXISTS idx_test_trades_timestamp ON test_trades(timestamp DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_test_positions_account_symbol ON test_positions(account_id, symbol);
|
|
CREATE INDEX IF NOT EXISTS idx_test_positions_symbol ON test_positions(symbol);
|
|
CREATE INDEX IF NOT EXISTS idx_test_positions_updated ON test_positions(last_updated DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_test_orders_status ON test_orders(status) WHERE status IN ('PENDING', 'ACTIVE');
|
|
CREATE INDEX IF NOT EXISTS idx_test_orders_symbol_status ON test_orders(symbol, status);
|
|
CREATE INDEX IF NOT EXISTS idx_test_orders_account ON test_orders(account_id);
|
|
CREATE INDEX IF NOT EXISTS idx_test_orders_created ON test_orders(created_at DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_test_executions_order_id ON test_executions(order_id);
|
|
CREATE INDEX IF NOT EXISTS idx_test_executions_symbol_executed ON test_executions(symbol, executed_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_test_executions_executed_at ON test_executions(executed_at DESC);
|
|
|
|
-- Triggers for maintaining updated_at timestamps
|
|
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.updated_at = NOW();
|
|
RETURN NEW;
|
|
END;
|
|
$$ language 'plpgsql';
|
|
|
|
CREATE TRIGGER update_test_trades_updated_at BEFORE UPDATE ON test_trades
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_test_positions_updated_at BEFORE UPDATE ON test_positions
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
CREATE TRIGGER update_test_orders_updated_at BEFORE UPDATE ON test_orders
|
|
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
|
|
-- Function to calculate remaining quantity for orders
|
|
CREATE OR REPLACE FUNCTION update_order_remaining_quantity()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.remaining_quantity = NEW.quantity - NEW.filled_quantity;
|
|
RETURN NEW;
|
|
END;
|
|
$$ language 'plpgsql';
|
|
|
|
CREATE TRIGGER update_test_orders_remaining BEFORE INSERT OR UPDATE ON test_orders
|
|
FOR EACH ROW EXECUTE FUNCTION update_order_remaining_quantity();
|
|
|
|
-- Comments for documentation
|
|
COMMENT ON TABLE test_trades IS 'Test table for validating trade persistence and querying performance';
|
|
COMMENT ON TABLE test_positions IS 'Test table for validating position management and portfolio tracking';
|
|
COMMENT ON TABLE test_orders IS 'Test table for validating order lifecycle management';
|
|
COMMENT ON TABLE test_executions IS 'Test table for validating execution tracking and reporting';
|
|
|
|
COMMENT ON COLUMN test_trades.trade_id IS 'Unique identifier for the trade execution';
|
|
COMMENT ON COLUMN test_trades.symbol IS 'Trading symbol (e.g., AAPL, GOOGL)';
|
|
COMMENT ON COLUMN test_trades.side IS 'Buy or sell side of the trade';
|
|
COMMENT ON COLUMN test_trades.quantity IS 'Number of shares/units traded';
|
|
COMMENT ON COLUMN test_trades.price IS 'Execution price per share/unit';
|
|
|
|
COMMENT ON COLUMN test_positions.account_id IS 'Account identifier owning the position';
|
|
COMMENT ON COLUMN test_positions.symbol IS 'Trading symbol for the position';
|
|
COMMENT ON COLUMN test_positions.quantity IS 'Current position size (positive=long, negative=short)';
|
|
COMMENT ON COLUMN test_positions.average_price IS 'Average cost basis for the position';
|
|
COMMENT ON COLUMN test_positions.market_value IS 'Current market value of the position';
|
|
COMMENT ON COLUMN test_positions.unrealized_pnl IS 'Unrealized profit/loss on the position'; |