learning_ai_invt_trdg/backend/src/services/tradingControlRepository.ts

77 lines
2.3 KiB
TypeScript

import { getContainer } from '@bytelyst/cosmos';
import { config } from '../config/index.js';
import logger from '../utils/logger.js';
import type { TradingControlSnapshot } from './healthTracker.js';
const CONTAINER_NAME = 'trading_controls';
const GLOBAL_CONTROL_ID = 'global';
interface TradingControlDocument extends TradingControlSnapshot {
id: string;
productId: string;
scope: 'global';
updatedAt: string;
}
function isCosmosConfigured(): boolean {
return Boolean(config.COSMOS_ENDPOINT && config.COSMOS_KEY);
}
function toTradingControlSnapshot(doc: Partial<TradingControlDocument> | null | undefined): TradingControlSnapshot | null {
if (!doc?.mode || !doc.lastChangedBy || !doc.lastChangedAt) {
return null;
}
if (doc.mode !== 'RUNNING' && doc.mode !== 'PAUSED') {
return null;
}
return {
mode: doc.mode,
lastChangedBy: doc.lastChangedBy,
lastChangedAt: Number(doc.lastChangedAt),
reason: doc.reason,
};
}
export async function loadGlobalTradingControl(): Promise<TradingControlSnapshot | null> {
if (!isCosmosConfigured()) {
return null;
}
try {
const container = getContainer(CONTAINER_NAME);
const { resource } = await container.item(GLOBAL_CONTROL_ID, config.PRODUCT_ID).read<TradingControlDocument>();
return toTradingControlSnapshot(resource);
} catch (error) {
const code = (error as { code?: number })?.code;
if (code === 404) {
return null;
}
logger.warn(`[TradingControl] Cosmos read failed: ${error instanceof Error ? error.message : 'unknown error'}`);
return null;
}
}
export async function saveGlobalTradingControl(update: TradingControlSnapshot): Promise<boolean> {
if (!isCosmosConfigured()) {
return false;
}
try {
const container = getContainer(CONTAINER_NAME);
const doc: TradingControlDocument = {
id: GLOBAL_CONTROL_ID,
productId: config.PRODUCT_ID,
scope: 'global',
...update,
updatedAt: new Date().toISOString(),
};
await container.items.upsert(doc);
return true;
} catch (error) {
logger.warn(`[TradingControl] Cosmos upsert failed: ${error instanceof Error ? error.message : 'unknown error'}`);
return false;
}
}