236 lines
7.3 KiB
PL/PgSQL
236 lines
7.3 KiB
PL/PgSQL
BEGIN;
|
|
|
|
ALTER TABLE app_user ADD COLUMN IF NOT EXISTS is_admin boolean NOT NULL DEFAULT false;
|
|
CREATE INDEX IF NOT EXISTS idx_app_user_is_admin ON app_user (is_admin);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_strategy_run_user_status ON strategy_run (user_id, status);
|
|
CREATE INDEX IF NOT EXISTS idx_strategy_run_user_created ON strategy_run (user_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_engine_event_user_run_ts ON engine_event (user_id, run_id, ts DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_strategy_log_user_run_ts ON strategy_log (user_id, run_id, ts DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_event_ledger_user_run_logical ON event_ledger (user_id, run_id, logical_time);
|
|
CREATE INDEX IF NOT EXISTS idx_paper_order_user_run_ts ON paper_order (user_id, run_id, "timestamp" DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_paper_trade_user_run_ts ON paper_trade (user_id, run_id, "timestamp" DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_mtm_ledger_user_run_ts ON mtm_ledger (user_id, run_id, "timestamp" DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_paper_equity_curve_user_run_ts ON paper_equity_curve (user_id, run_id, "timestamp" DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_engine_status_user_run ON engine_status (user_id, run_id);
|
|
CREATE INDEX IF NOT EXISTS idx_engine_state_paper_user_run ON engine_state_paper (user_id, run_id);
|
|
|
|
CREATE OR REPLACE VIEW admin_user_metrics AS
|
|
WITH session_stats AS (
|
|
SELECT
|
|
user_id,
|
|
MIN(created_at) AS first_session_at,
|
|
MAX(COALESCE(last_seen_at, created_at)) AS last_login_at
|
|
FROM app_session
|
|
GROUP BY user_id
|
|
),
|
|
run_stats AS (
|
|
SELECT
|
|
user_id,
|
|
COUNT(*) AS runs_count,
|
|
MAX(CASE WHEN status = 'RUNNING' THEN run_id END) AS active_run_id,
|
|
MAX(CASE WHEN status = 'RUNNING' THEN status END) AS active_run_status,
|
|
MIN(created_at) AS first_run_at
|
|
FROM strategy_run
|
|
GROUP BY user_id
|
|
),
|
|
broker_stats AS (
|
|
SELECT user_id, BOOL_OR(connected) AS broker_connected
|
|
FROM user_broker
|
|
GROUP BY user_id
|
|
)
|
|
SELECT
|
|
u.id AS user_id,
|
|
u.username,
|
|
u.is_admin,
|
|
COALESCE(session_stats.first_session_at, run_stats.first_run_at) AS created_at,
|
|
session_stats.last_login_at,
|
|
COALESCE(run_stats.runs_count, 0) AS runs_count,
|
|
run_stats.active_run_id,
|
|
run_stats.active_run_status,
|
|
COALESCE(broker_stats.broker_connected, FALSE) AS broker_connected
|
|
FROM app_user u
|
|
LEFT JOIN session_stats ON session_stats.user_id = u.id
|
|
LEFT JOIN run_stats ON run_stats.user_id = u.id
|
|
LEFT JOIN broker_stats ON broker_stats.user_id = u.id;
|
|
|
|
CREATE OR REPLACE VIEW admin_run_metrics AS
|
|
WITH order_stats AS (
|
|
SELECT user_id, run_id, COUNT(*) AS order_count, MAX("timestamp") AS last_order_time
|
|
FROM paper_order
|
|
GROUP BY user_id, run_id
|
|
),
|
|
trade_stats AS (
|
|
SELECT user_id, run_id, COUNT(*) AS trade_count, MAX("timestamp") AS last_trade_time
|
|
FROM paper_trade
|
|
GROUP BY user_id, run_id
|
|
),
|
|
event_stats AS (
|
|
SELECT
|
|
user_id,
|
|
run_id,
|
|
MAX("timestamp") AS last_event_time,
|
|
MAX(CASE WHEN event = 'SIP_EXECUTED' THEN "timestamp" END) AS last_sip_time
|
|
FROM event_ledger
|
|
GROUP BY user_id, run_id
|
|
),
|
|
equity_latest AS (
|
|
SELECT DISTINCT ON (user_id, run_id)
|
|
user_id,
|
|
run_id,
|
|
equity AS equity_latest,
|
|
pnl AS pnl_latest,
|
|
"timestamp" AS equity_ts
|
|
FROM paper_equity_curve
|
|
ORDER BY user_id, run_id, "timestamp" DESC
|
|
),
|
|
mtm_latest AS (
|
|
SELECT DISTINCT ON (user_id, run_id)
|
|
user_id,
|
|
run_id,
|
|
"timestamp" AS mtm_ts
|
|
FROM mtm_ledger
|
|
ORDER BY user_id, run_id, "timestamp" DESC
|
|
),
|
|
log_latest AS (
|
|
SELECT user_id, run_id, MAX(ts) AS last_log_time
|
|
FROM strategy_log
|
|
GROUP BY user_id, run_id
|
|
),
|
|
engine_latest AS (
|
|
SELECT user_id, run_id, MAX(ts) AS last_engine_time
|
|
FROM engine_event
|
|
GROUP BY user_id, run_id
|
|
),
|
|
activity AS (
|
|
SELECT user_id, run_id, MAX(ts) AS last_event_time
|
|
FROM (
|
|
SELECT user_id, run_id, ts FROM engine_event
|
|
UNION ALL
|
|
SELECT user_id, run_id, ts FROM strategy_log
|
|
UNION ALL
|
|
SELECT user_id, run_id, "timestamp" AS ts FROM paper_order
|
|
UNION ALL
|
|
SELECT user_id, run_id, "timestamp" AS ts FROM paper_trade
|
|
UNION ALL
|
|
SELECT user_id, run_id, "timestamp" AS ts FROM mtm_ledger
|
|
UNION ALL
|
|
SELECT user_id, run_id, "timestamp" AS ts FROM paper_equity_curve
|
|
UNION ALL
|
|
SELECT user_id, run_id, "timestamp" AS ts FROM event_ledger
|
|
) t
|
|
GROUP BY user_id, run_id
|
|
)
|
|
SELECT
|
|
sr.run_id,
|
|
sr.user_id,
|
|
sr.status,
|
|
sr.created_at,
|
|
sr.started_at,
|
|
sr.stopped_at,
|
|
sr.strategy,
|
|
sr.mode,
|
|
sr.broker,
|
|
sc.sip_amount,
|
|
sc.sip_frequency_value,
|
|
sc.sip_frequency_unit,
|
|
sc.next_run AS next_sip_time,
|
|
activity.last_event_time,
|
|
event_stats.last_sip_time,
|
|
COALESCE(order_stats.order_count, 0) AS order_count,
|
|
COALESCE(trade_stats.trade_count, 0) AS trade_count,
|
|
equity_latest.equity_latest,
|
|
equity_latest.pnl_latest
|
|
FROM strategy_run sr
|
|
LEFT JOIN strategy_config sc
|
|
ON sc.user_id = sr.user_id AND sc.run_id = sr.run_id
|
|
LEFT JOIN order_stats
|
|
ON order_stats.user_id = sr.user_id AND order_stats.run_id = sr.run_id
|
|
LEFT JOIN trade_stats
|
|
ON trade_stats.user_id = sr.user_id AND trade_stats.run_id = sr.run_id
|
|
LEFT JOIN event_stats
|
|
ON event_stats.user_id = sr.user_id AND event_stats.run_id = sr.run_id
|
|
LEFT JOIN equity_latest
|
|
ON equity_latest.user_id = sr.user_id AND equity_latest.run_id = sr.run_id
|
|
LEFT JOIN mtm_latest
|
|
ON mtm_latest.user_id = sr.user_id AND mtm_latest.run_id = sr.run_id
|
|
LEFT JOIN log_latest
|
|
ON log_latest.user_id = sr.user_id AND log_latest.run_id = sr.run_id
|
|
LEFT JOIN engine_latest
|
|
ON engine_latest.user_id = sr.user_id AND engine_latest.run_id = sr.run_id
|
|
LEFT JOIN activity
|
|
ON activity.user_id = sr.user_id AND activity.run_id = sr.run_id;
|
|
|
|
CREATE OR REPLACE VIEW admin_engine_health AS
|
|
WITH activity AS (
|
|
SELECT user_id, run_id, MAX(ts) AS last_event_time
|
|
FROM (
|
|
SELECT user_id, run_id, ts FROM engine_event
|
|
UNION ALL
|
|
SELECT user_id, run_id, ts FROM strategy_log
|
|
UNION ALL
|
|
SELECT user_id, run_id, "timestamp" AS ts FROM event_ledger
|
|
) t
|
|
GROUP BY user_id, run_id
|
|
)
|
|
SELECT
|
|
sr.run_id,
|
|
sr.user_id,
|
|
sr.status,
|
|
activity.last_event_time,
|
|
es.status AS engine_status,
|
|
es.last_updated AS engine_status_ts
|
|
FROM strategy_run sr
|
|
LEFT JOIN activity
|
|
ON activity.user_id = sr.user_id AND activity.run_id = sr.run_id
|
|
LEFT JOIN engine_status es
|
|
ON es.user_id = sr.user_id AND es.run_id = sr.run_id;
|
|
|
|
CREATE OR REPLACE VIEW admin_order_stats AS
|
|
SELECT
|
|
user_id,
|
|
run_id,
|
|
COUNT(*) AS total_orders,
|
|
COUNT(*) FILTER (WHERE "timestamp" >= now() - interval '24 hours') AS orders_last_24h,
|
|
COUNT(*) FILTER (WHERE status = 'FILLED') AS filled_orders
|
|
FROM paper_order
|
|
GROUP BY user_id, run_id;
|
|
|
|
CREATE OR REPLACE VIEW admin_ledger_stats AS
|
|
WITH mtm_latest AS (
|
|
SELECT DISTINCT ON (user_id, run_id)
|
|
user_id,
|
|
run_id,
|
|
portfolio_value,
|
|
pnl,
|
|
"timestamp" AS mtm_ts
|
|
FROM mtm_ledger
|
|
ORDER BY user_id, run_id, "timestamp" DESC
|
|
),
|
|
equity_latest AS (
|
|
SELECT DISTINCT ON (user_id, run_id)
|
|
user_id,
|
|
run_id,
|
|
equity,
|
|
pnl,
|
|
"timestamp" AS equity_ts
|
|
FROM paper_equity_curve
|
|
ORDER BY user_id, run_id, "timestamp" DESC
|
|
)
|
|
SELECT
|
|
sr.user_id,
|
|
sr.run_id,
|
|
mtm_latest.portfolio_value AS mtm_value,
|
|
mtm_latest.pnl AS mtm_pnl,
|
|
mtm_latest.mtm_ts,
|
|
equity_latest.equity AS equity_value,
|
|
equity_latest.pnl AS equity_pnl,
|
|
equity_latest.equity_ts
|
|
FROM strategy_run sr
|
|
LEFT JOIN mtm_latest
|
|
ON mtm_latest.user_id = sr.user_id AND mtm_latest.run_id = sr.run_id
|
|
LEFT JOIN equity_latest
|
|
ON equity_latest.user_id = sr.user_id AND equity_latest.run_id = sr.run_id;
|
|
|
|
COMMIT;
|