refactor(backend): extract shared trading persistence types from SupabaseService
Made-with: Cursor
This commit is contained in:
parent
774541289a
commit
b306f3264e
@ -15,6 +15,29 @@ import {
|
|||||||
type AlpacaSubTagIntent
|
type AlpacaSubTagIntent
|
||||||
} from '../utils/alpacaSubTag.js';
|
} from '../utils/alpacaSubTag.js';
|
||||||
import { SymbolMapper } from '../utils/symbolMapper.js';
|
import { SymbolMapper } from '../utils/symbolMapper.js';
|
||||||
|
import type {
|
||||||
|
FilledLifecycleOrderRow,
|
||||||
|
ReconciliationBackfillAuditInsert,
|
||||||
|
ReconciliationBackfillAuditQuery,
|
||||||
|
ReconciliationBackfillAuditRow,
|
||||||
|
ReconciliationBackfillBatchSummary,
|
||||||
|
ReconciliationBackfillOrderInsert,
|
||||||
|
ReconciliationSubTagRepairSummary,
|
||||||
|
StaleOrderScope,
|
||||||
|
VirtualOpenPosition
|
||||||
|
} from './tradingPersistenceTypes.js';
|
||||||
|
|
||||||
|
export type {
|
||||||
|
FilledLifecycleOrderRow,
|
||||||
|
ReconciliationBackfillAuditInsert,
|
||||||
|
ReconciliationBackfillAuditQuery,
|
||||||
|
ReconciliationBackfillAuditRow,
|
||||||
|
ReconciliationBackfillBatchSummary,
|
||||||
|
ReconciliationBackfillOrderInsert,
|
||||||
|
ReconciliationSubTagRepairSummary,
|
||||||
|
StaleOrderScope,
|
||||||
|
VirtualOpenPosition
|
||||||
|
} from './tradingPersistenceTypes.js';
|
||||||
|
|
||||||
export interface UserConfig {
|
export interface UserConfig {
|
||||||
user_id: string;
|
user_id: string;
|
||||||
@ -32,145 +55,6 @@ export interface UserConfig {
|
|||||||
market_poll_interval_in_seconds: number;
|
market_poll_interval_in_seconds: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VirtualOpenPosition {
|
|
||||||
profileId: string;
|
|
||||||
symbol: string;
|
|
||||||
side: 'BUY' | 'SELL';
|
|
||||||
qty: number;
|
|
||||||
entryPrice: number;
|
|
||||||
stopLoss: number;
|
|
||||||
takeProfit: number;
|
|
||||||
userId?: string;
|
|
||||||
tradeId: string;
|
|
||||||
tradeIds: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StaleOrderScope {
|
|
||||||
profileId?: string;
|
|
||||||
userId?: string;
|
|
||||||
includeOrphanUserOrders?: boolean;
|
|
||||||
profileNullOnly?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FilledLifecycleOrderRow {
|
|
||||||
id?: string;
|
|
||||||
order_id?: string | null;
|
|
||||||
user_id?: string | null;
|
|
||||||
profile_id?: string | null;
|
|
||||||
symbol?: string | null;
|
|
||||||
trade_id?: string | null;
|
|
||||||
action?: string | null;
|
|
||||||
side?: string | null;
|
|
||||||
qty?: number | string | null;
|
|
||||||
quantity?: number | string | null;
|
|
||||||
price?: number | string | null;
|
|
||||||
status?: string | null;
|
|
||||||
source?: string | null;
|
|
||||||
sub_tag?: string | null;
|
|
||||||
stop_loss?: number | string | null;
|
|
||||||
take_profit?: number | string | null;
|
|
||||||
timestamp?: number | string | null;
|
|
||||||
created_at?: string | null;
|
|
||||||
filled_at?: string | null;
|
|
||||||
type?: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReconciliationBackfillOrderInsert {
|
|
||||||
user_id: string;
|
|
||||||
profile_id: string;
|
|
||||||
order_id: string;
|
|
||||||
symbol: string;
|
|
||||||
type: string;
|
|
||||||
side: string;
|
|
||||||
qty: number;
|
|
||||||
quantity: number;
|
|
||||||
price: number;
|
|
||||||
status: string;
|
|
||||||
timestamp: number;
|
|
||||||
filled_at?: string;
|
|
||||||
trade_id: string;
|
|
||||||
action: 'EXIT';
|
|
||||||
source: 'BOT';
|
|
||||||
sub_tag?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReconciliationBackfillAuditInsert {
|
|
||||||
batch_id: string;
|
|
||||||
profile_id: string;
|
|
||||||
symbol: string;
|
|
||||||
trade_id: string;
|
|
||||||
exchange_order_id?: string | null;
|
|
||||||
exchange_client_order_id?: string | null;
|
|
||||||
backfill_order_id?: string | null;
|
|
||||||
filled_qty?: number | null;
|
|
||||||
filled_price?: number | null;
|
|
||||||
filled_at?: string | null;
|
|
||||||
dry_run: boolean;
|
|
||||||
decision: string;
|
|
||||||
reason?: string | null;
|
|
||||||
metadata?: Record<string, any> | null;
|
|
||||||
applied_at?: string | null;
|
|
||||||
reverted_at?: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReconciliationBackfillAuditQuery {
|
|
||||||
profileId?: string;
|
|
||||||
symbol?: string;
|
|
||||||
batchId?: string;
|
|
||||||
decisions?: string[];
|
|
||||||
fromIso?: string;
|
|
||||||
toIso?: string;
|
|
||||||
limit?: number;
|
|
||||||
offset?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReconciliationBackfillAuditRow {
|
|
||||||
id: number;
|
|
||||||
batch_id: string;
|
|
||||||
profile_id: string;
|
|
||||||
symbol: string;
|
|
||||||
trade_id: string;
|
|
||||||
exchange_order_id?: string | null;
|
|
||||||
exchange_client_order_id?: string | null;
|
|
||||||
backfill_order_id?: string | null;
|
|
||||||
filled_qty?: number | null;
|
|
||||||
filled_price?: number | null;
|
|
||||||
filled_at?: string | null;
|
|
||||||
dry_run: boolean;
|
|
||||||
decision: string;
|
|
||||||
reason?: string | null;
|
|
||||||
metadata?: Record<string, any> | null;
|
|
||||||
applied_at?: string | null;
|
|
||||||
reverted_at?: string | null;
|
|
||||||
created_at: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReconciliationBackfillBatchSummary {
|
|
||||||
batchId: string;
|
|
||||||
firstSeenAt: string;
|
|
||||||
lastSeenAt: string;
|
|
||||||
profileIds: string[];
|
|
||||||
symbols: string[];
|
|
||||||
totalRows: number;
|
|
||||||
byDecision: Record<string, number>;
|
|
||||||
dryRunRows: number;
|
|
||||||
appliedRows: number;
|
|
||||||
revertedRows: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReconciliationSubTagRepairSummary {
|
|
||||||
attempted: boolean;
|
|
||||||
unsupported?: boolean;
|
|
||||||
scannedRows: number;
|
|
||||||
eligibleRows: number;
|
|
||||||
updatedRows: number;
|
|
||||||
skippedNoProfile: number;
|
|
||||||
skippedNoTrade: number;
|
|
||||||
skippedTagDisabled: number;
|
|
||||||
skippedAlreadyTagged: number;
|
|
||||||
dryRun: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SupabaseService {
|
class SupabaseService {
|
||||||
private client: SupabaseClient | null = null;
|
private client: SupabaseClient | null = null;
|
||||||
private tradeHistorySupportsSource: boolean | null = null;
|
private tradeHistorySupportsSource: boolean | null = null;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { FilledLifecycleOrderRow } from './SupabaseService.js';
|
import type { FilledLifecycleOrderRow } from './tradingPersistenceTypes.js';
|
||||||
|
|
||||||
export type CanonicalLifecycleState = 'OPEN' | 'PARTIAL_EXIT' | 'CLOSED' | 'ORPHAN_EXIT';
|
export type CanonicalLifecycleState = 'OPEN' | 'PARTIAL_EXIT' | 'CLOSED' | 'ORPHAN_EXIT';
|
||||||
export type CanonicalSide = 'BUY' | 'SELL';
|
export type CanonicalSide = 'BUY' | 'SELL';
|
||||||
|
|||||||
@ -4,11 +4,11 @@ import logger from '../utils/logger.js';
|
|||||||
import { normalizeOrderAction, normalizeOrderStatus, normalizeTradeSide } from '../domain/tradingEnums.js';
|
import { normalizeOrderAction, normalizeOrderStatus, normalizeTradeSide } from '../domain/tradingEnums.js';
|
||||||
import { healthTracker } from './healthTracker.js';
|
import { healthTracker } from './healthTracker.js';
|
||||||
import { observabilityService } from './observabilityService.js';
|
import { observabilityService } from './observabilityService.js';
|
||||||
import {
|
import type {
|
||||||
FilledLifecycleOrderRow,
|
FilledLifecycleOrderRow,
|
||||||
ReconciliationBackfillAuditInsert,
|
ReconciliationBackfillAuditInsert,
|
||||||
ReconciliationBackfillOrderInsert
|
ReconciliationBackfillOrderInsert
|
||||||
} from './SupabaseService.js';
|
} from './tradingPersistenceTypes.js';
|
||||||
import * as runtimeOrderRepository from './runtimeOrderRepository.js';
|
import * as runtimeOrderRepository from './runtimeOrderRepository.js';
|
||||||
import type { TradeExecutor } from './TradeExecutor.js';
|
import type { TradeExecutor } from './TradeExecutor.js';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import { config } from '../config/index.js';
|
import { config } from '../config/index.js';
|
||||||
import logger from '../utils/logger.js';
|
import logger from '../utils/logger.js';
|
||||||
import { observabilityService } from './observabilityService.js';
|
import { observabilityService } from './observabilityService.js';
|
||||||
import {
|
import type { ReconciliationSubTagRepairSummary } from './tradingPersistenceTypes.js';
|
||||||
type ReconciliationSubTagRepairSummary
|
|
||||||
} from './SupabaseService.js';
|
|
||||||
import { repairMissingSubTagsForProfile } from './runtimeOrderRepository.js';
|
import { repairMissingSubTagsForProfile } from './runtimeOrderRepository.js';
|
||||||
|
|
||||||
export interface ReconciliationSubTagRepairContext {
|
export interface ReconciliationSubTagRepairContext {
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import type {
|
|||||||
ReconciliationSubTagRepairSummary,
|
ReconciliationSubTagRepairSummary,
|
||||||
StaleOrderScope,
|
StaleOrderScope,
|
||||||
VirtualOpenPosition
|
VirtualOpenPosition
|
||||||
} from './SupabaseService.js';
|
} from './tradingPersistenceTypes.js';
|
||||||
import {
|
import {
|
||||||
ORDER_CONTAINER,
|
ORDER_CONTAINER,
|
||||||
RECONCILIATION_AUDIT_CONTAINER,
|
RECONCILIATION_AUDIT_CONTAINER,
|
||||||
|
|||||||
143
backend/src/services/tradingPersistenceTypes.ts
Normal file
143
backend/src/services/tradingPersistenceTypes.ts
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
* Shared shapes for orders, reconciliation audit, and virtual positions.
|
||||||
|
* Used by Cosmos-first repositories and legacy SupabaseService persistence.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface VirtualOpenPosition {
|
||||||
|
profileId: string;
|
||||||
|
symbol: string;
|
||||||
|
side: 'BUY' | 'SELL';
|
||||||
|
qty: number;
|
||||||
|
entryPrice: number;
|
||||||
|
stopLoss: number;
|
||||||
|
takeProfit: number;
|
||||||
|
userId?: string;
|
||||||
|
tradeId: string;
|
||||||
|
tradeIds: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StaleOrderScope {
|
||||||
|
profileId?: string;
|
||||||
|
userId?: string;
|
||||||
|
includeOrphanUserOrders?: boolean;
|
||||||
|
profileNullOnly?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilledLifecycleOrderRow {
|
||||||
|
id?: string;
|
||||||
|
order_id?: string | null;
|
||||||
|
user_id?: string | null;
|
||||||
|
profile_id?: string | null;
|
||||||
|
symbol?: string | null;
|
||||||
|
trade_id?: string | null;
|
||||||
|
action?: string | null;
|
||||||
|
side?: string | null;
|
||||||
|
qty?: number | string | null;
|
||||||
|
quantity?: number | string | null;
|
||||||
|
price?: number | string | null;
|
||||||
|
status?: string | null;
|
||||||
|
source?: string | null;
|
||||||
|
sub_tag?: string | null;
|
||||||
|
stop_loss?: number | string | null;
|
||||||
|
take_profit?: number | string | null;
|
||||||
|
timestamp?: number | string | null;
|
||||||
|
created_at?: string | null;
|
||||||
|
filled_at?: string | null;
|
||||||
|
type?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReconciliationBackfillOrderInsert {
|
||||||
|
user_id: string;
|
||||||
|
profile_id: string;
|
||||||
|
order_id: string;
|
||||||
|
symbol: string;
|
||||||
|
type: string;
|
||||||
|
side: string;
|
||||||
|
qty: number;
|
||||||
|
quantity: number;
|
||||||
|
price: number;
|
||||||
|
status: string;
|
||||||
|
timestamp: number;
|
||||||
|
filled_at?: string;
|
||||||
|
trade_id: string;
|
||||||
|
action: 'EXIT';
|
||||||
|
source: 'BOT';
|
||||||
|
sub_tag?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReconciliationBackfillAuditInsert {
|
||||||
|
batch_id: string;
|
||||||
|
profile_id: string;
|
||||||
|
symbol: string;
|
||||||
|
trade_id: string;
|
||||||
|
exchange_order_id?: string | null;
|
||||||
|
exchange_client_order_id?: string | null;
|
||||||
|
backfill_order_id?: string | null;
|
||||||
|
filled_qty?: number | null;
|
||||||
|
filled_price?: number | null;
|
||||||
|
filled_at?: string | null;
|
||||||
|
dry_run: boolean;
|
||||||
|
decision: string;
|
||||||
|
reason?: string | null;
|
||||||
|
metadata?: Record<string, any> | null;
|
||||||
|
applied_at?: string | null;
|
||||||
|
reverted_at?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReconciliationBackfillAuditQuery {
|
||||||
|
profileId?: string;
|
||||||
|
symbol?: string;
|
||||||
|
batchId?: string;
|
||||||
|
decisions?: string[];
|
||||||
|
fromIso?: string;
|
||||||
|
toIso?: string;
|
||||||
|
limit?: number;
|
||||||
|
offset?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReconciliationBackfillAuditRow {
|
||||||
|
id: number;
|
||||||
|
batch_id: string;
|
||||||
|
profile_id: string;
|
||||||
|
symbol: string;
|
||||||
|
trade_id: string;
|
||||||
|
exchange_order_id?: string | null;
|
||||||
|
exchange_client_order_id?: string | null;
|
||||||
|
backfill_order_id?: string | null;
|
||||||
|
filled_qty?: number | null;
|
||||||
|
filled_price?: number | null;
|
||||||
|
filled_at?: string | null;
|
||||||
|
dry_run: boolean;
|
||||||
|
decision: string;
|
||||||
|
reason?: string | null;
|
||||||
|
metadata?: Record<string, any> | null;
|
||||||
|
applied_at?: string | null;
|
||||||
|
reverted_at?: string | null;
|
||||||
|
created_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReconciliationBackfillBatchSummary {
|
||||||
|
batchId: string;
|
||||||
|
firstSeenAt: string;
|
||||||
|
lastSeenAt: string;
|
||||||
|
profileIds: string[];
|
||||||
|
symbols: string[];
|
||||||
|
totalRows: number;
|
||||||
|
byDecision: Record<string, number>;
|
||||||
|
dryRunRows: number;
|
||||||
|
appliedRows: number;
|
||||||
|
revertedRows: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReconciliationSubTagRepairSummary {
|
||||||
|
attempted: boolean;
|
||||||
|
unsupported?: boolean;
|
||||||
|
scannedRows: number;
|
||||||
|
eligibleRows: number;
|
||||||
|
updatedRows: number;
|
||||||
|
skippedNoProfile: number;
|
||||||
|
skippedNoTrade: number;
|
||||||
|
skippedTagDisabled: number;
|
||||||
|
skippedAlreadyTagged: number;
|
||||||
|
dryRun: boolean;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user