77 lines
2.3 KiB
TypeScript
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;
|
|
}
|
|
}
|