unrip/src/core/schemas.mjs
philipp d6fc99dc60
All checks were successful
deploy / deploy (push) Successful in 43s
Fix live ops regressions
Proof: active BTC/EURe tradeable loop on k3s must expose funding state cleanly, preserve durable history, and avoid inheriting dummy executor state.

Assumptions: retained Kafka topics may contain legacy dummy records; those should be tolerated in history ingestion without weakening the current live command shape.

Still fake: internal inventory is still unfunded, strategy and executor remain disarmed, and no live quote response has been submitted yet.
2026-04-02 10:07:54 +02:00

123 lines
5.5 KiB
JavaScript

function requireString(value, field) {
if (typeof value !== 'string' || value.length === 0) throw new Error(`Missing ${field}`);
}
function requireObject(value, field) {
if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`Missing ${field}`);
}
function requireOneOf(value, field, values) {
if (!values.includes(value)) throw new Error(`Unexpected ${field}: ${value}`);
}
export function assertEventEnvelope(event) {
requireObject(event, 'event');
requireString(event.event_id, 'event.event_id');
requireString(event.event_type, 'event.event_type');
requireString(event.venue, 'event.venue');
if (event.source != null) requireString(event.source, 'event.source');
if (typeof event.schema_version !== 'number') throw new Error('Missing event.schema_version');
requireString(event.ingested_at, 'event.ingested_at');
requireObject(event.payload, 'event.payload');
return event;
}
export function assertNormalizedSwapDemand(event) {
assertEventEnvelope(event);
if (event.event_type !== 'swap_demand') throw new Error(`Unexpected event_type: ${event.event_type}`);
const payload = event.payload;
requireString(payload.quote_id, 'payload.quote_id');
requireString(payload.asset_in, 'payload.asset_in');
requireString(payload.asset_out, 'payload.asset_out');
requireString(payload.request_kind, 'payload.request_kind');
requireOneOf(payload.request_kind, 'payload.request_kind', ['exact_in', 'exact_out']);
if (payload.amount_in != null) requireString(payload.amount_in, 'payload.amount_in');
if (payload.amount_out != null) requireString(payload.amount_out, 'payload.amount_out');
if (payload.min_deadline_ms != null) requireString(payload.min_deadline_ms, 'payload.min_deadline_ms');
return event;
}
export function assertMarketPriceEvent(event) {
assertEventEnvelope(event);
if (event.event_type !== 'market_price') throw new Error(`Unexpected event_type: ${event.event_type}`);
const payload = event.payload;
requireString(payload.price_id, 'payload.price_id');
requireString(payload.pair, 'payload.pair');
requireString(payload.eur_per_btc, 'payload.eur_per_btc');
requireString(payload.btc_per_eure, 'payload.btc_per_eure');
requireString(payload.source_used, 'payload.source_used');
return event;
}
export function assertInventorySnapshotEvent(event) {
assertEventEnvelope(event);
if (event.event_type !== 'intent_inventory') throw new Error(`Unexpected event_type: ${event.event_type}`);
const payload = event.payload;
requireString(payload.inventory_id, 'payload.inventory_id');
requireString(payload.account_id, 'payload.account_id');
requireString(payload.reconciliation_status, 'payload.reconciliation_status');
requireObject(payload.spendable, 'payload.spendable');
return event;
}
export function assertLiquidityActionEvent(event) {
assertEventEnvelope(event);
if (event.event_type !== 'liquidity_action') throw new Error(`Unexpected event_type: ${event.event_type}`);
const payload = event.payload;
requireString(payload.liquidity_action_id, 'payload.liquidity_action_id');
requireString(payload.action_type, 'payload.action_type');
requireString(payload.status, 'payload.status');
return event;
}
export function assertTradeDecisionEvent(event) {
assertEventEnvelope(event);
if (event.event_type !== 'trade_decision') throw new Error(`Unexpected event_type: ${event.event_type}`);
const payload = event.payload;
requireString(payload.decision_id, 'payload.decision_id');
requireString(payload.quote_id, 'payload.quote_id');
requireString(payload.pair, 'payload.pair');
requireString(payload.direction, 'payload.direction');
requireString(payload.decision, 'payload.decision');
requireString(payload.decision_reason, 'payload.decision_reason');
return event;
}
export function assertExecuteTradeCommand(event) {
assertEventEnvelope(event);
if (event.event_type !== 'execute_trade') throw new Error(`Unexpected event_type: ${event.event_type}`);
const payload = event.payload;
requireString(payload.command_id, 'payload.command_id');
requireString(payload.idempotency_key, 'payload.idempotency_key');
requireString(payload.execution_key, 'payload.execution_key');
requireString(payload.quote_id, 'payload.quote_id');
requireString(payload.asset_in, 'payload.asset_in');
requireString(payload.asset_out, 'payload.asset_out');
if (payload.decision_id != null) requireString(payload.decision_id, 'payload.decision_id');
if (payload.request_kind != null) requireString(payload.request_kind, 'payload.request_kind');
if (payload.quote_output != null) requireObject(payload.quote_output, 'payload.quote_output');
if (payload.amount_in != null) requireString(payload.amount_in, 'payload.amount_in');
if (payload.amount_out != null) requireString(payload.amount_out, 'payload.amount_out');
return event;
}
export function assertTradeResult(event) {
assertEventEnvelope(event);
if (event.event_type !== 'trade_result') throw new Error(`Unexpected event_type: ${event.event_type}`);
const payload = event.payload;
requireString(payload.command_id, 'payload.command_id');
requireString(payload.idempotency_key, 'payload.idempotency_key');
requireString(payload.execution_key, 'payload.execution_key');
requireString(payload.quote_id, 'payload.quote_id');
requireString(payload.status, 'payload.status');
if (payload.decision_id != null) requireString(payload.decision_id, 'payload.decision_id');
if (payload.result_code != null) requireString(payload.result_code, 'payload.result_code');
return event;
}