import apiClient from './client'; import type { ActivationConfig, AdminUser, AlertConfig, AlertTestResult, FundamentalsCutoverConfig, PipelineReadiness, RecommendationConfig, ScheduleConfig, SentimentProviderConfig, SentimentTestResult, SystemSetting, TickerUniverse, TickerUniverseBootstrapResult, TickerUniverseSetting, } from '../lib/types'; // Users export function listUsers() { return apiClient.get('admin/users').then((r) => r.data); } export function createUser(data: { username: string; password: string; role: string; has_access: boolean; }) { return apiClient.post('admin/users', data).then((r) => r.data); } export function updateAccess(userId: number, hasAccess: boolean) { return apiClient .put<{ message: string }>(`admin/users/${userId}/access`, { has_access: hasAccess, }) .then((r) => r.data); } export function resetPassword(userId: number, password: string) { return apiClient .put<{ message: string }>(`admin/users/${userId}/password`, { new_password: password }) .then((r) => r.data); } // Settings export function listSettings() { return apiClient .get('admin/settings') .then((r) => r.data); } export function updateSetting(key: string, value: string) { return apiClient .put<{ message: string }>(`admin/settings/${key}`, { value }) .then((r) => r.data); } export function getFundamentalsCutoverSettings() { return apiClient .get('admin/settings/fundamentals-cutover') .then((r) => r.data); } export function updateFundamentalsCutoverSettings(enabled: boolean) { return apiClient .put('admin/settings/fundamentals-cutover', { enabled }) .then((r) => r.data); } export function getRecommendationSettings() { return apiClient .get('admin/settings/recommendations') .then((r) => r.data); } export function updateRecommendationSettings(payload: Partial) { return apiClient .put('admin/settings/recommendations', payload) .then((r) => r.data); } export function getActivationSettings() { return apiClient .get('admin/settings/activation') .then((r) => r.data); } export function updateActivationSettings(payload: Partial) { return apiClient .put('admin/settings/activation', payload) .then((r) => r.data); } export function getScheduleSettings() { return apiClient .get('admin/settings/schedule') .then((r) => r.data); } export function updateScheduleSettings(payload: Partial) { return apiClient .put('admin/settings/schedule', payload) .then((r) => r.data); } export interface PerformanceConfig { start_date: string; } export function getPerformanceSettings() { return apiClient .get('admin/settings/performance') .then((r) => r.data); } export function updatePerformanceSettings(payload: Partial) { return apiClient .put('admin/settings/performance', payload) .then((r) => r.data); } export interface ShadowBookConfig { enabled: boolean; capacity: number; risk_pct: number; start_equity: number; } export function getShadowBookSettings() { return apiClient .get('admin/settings/shadow-book') .then((r) => r.data); } export function updateShadowBookSettings(payload: Partial) { return apiClient .put('admin/settings/shadow-book', payload) .then((r) => r.data); } export function getSentimentSettings() { return apiClient .get('admin/settings/sentiment') .then((r) => r.data); } export function updateSentimentSettings(payload: { provider?: string; model?: string; api_key?: string; }) { return apiClient .put('admin/settings/sentiment', payload) .then((r) => r.data); } export function testSentimentSettings(ticker: string) { return apiClient .post('admin/settings/sentiment/test', { ticker }) .then((r) => r.data); } export function getAlertSettings() { return apiClient .get('admin/settings/alerts') .then((r) => r.data); } export function updateAlertSettings(payload: { enabled?: boolean; bot_token?: string; telegram_chat_id?: string; qualified_enabled?: boolean; sr_proximity_enabled?: boolean; score_drop_enabled?: boolean; digest_enabled?: boolean; regime_quadrant_enabled?: boolean; trade_closed_enabled?: boolean; }) { return apiClient .put('admin/settings/alerts', payload) .then((r) => r.data); } export function testAlertSettings() { return apiClient .post('admin/settings/alerts/test') .then((r) => r.data); } export function getTickerUniverseSetting() { return apiClient .get('admin/settings/ticker-universe') .then((r) => r.data); } export function updateTickerUniverseSetting(universe: TickerUniverse) { return apiClient .put('admin/settings/ticker-universe', { universe }) .then((r) => r.data); } export function bootstrapTickers(universe: TickerUniverse, pruneMissing: boolean) { return apiClient .post('admin/tickers/bootstrap', null, { params: { universe, prune_missing: pruneMissing, }, }) .then((r) => r.data); } export function backfillTickerNames() { return apiClient .post<{ updated: number; checked: number; unmatched: number }>('admin/tickers/backfill-names') .then((r) => r.data); } // Jobs export interface JobStatus { name: string; label: string; enabled: boolean; next_run_at: string | null; via_pipeline?: boolean; registered: boolean; running?: boolean; runtime_status?: string | null; runtime_processed?: number | null; runtime_total?: number | null; runtime_progress_pct?: number | null; runtime_current_ticker?: string | null; runtime_started_at?: string | null; runtime_finished_at?: string | null; runtime_message?: string | null; } export interface TriggerJobResponse { job: string; status: 'triggered' | 'busy' | 'blocked' | 'not_found'; message: string; target_model?: BacktestTargetModel; cadence?: BacktestCadence; } export interface ParityFieldStats { legacy_available: number; candidate_available: number; both_available: number; material_differences: number; median_absolute_delta: number | null; p95_absolute_delta: number | null; max_absolute_delta: number | null; } export interface FundamentalsParityReport { report_version: number; generated_at: string; as_of_date: string; approval_status: string; read_only: boolean; summary: { universe_count: number; legacy_fundamental_score_available: number; candidate_fundamental_score_available: number; fundamental_scores_compared: number; fundamental_score_material_changes: number; fundamental_rank_changes: number; field_stats: Record; }; source_runs: Record; } export type BacktestTargetModel = 'production_gtl' | 'structural_sr'; export type BacktestCadence = 'weekly' | 'daily'; export function listJobs() { return apiClient.get('admin/jobs').then((r) => r.data); } export function getPipelineReadiness() { return apiClient.get('admin/pipeline/readiness').then((r) => r.data); } export function toggleJob(jobName: string, enabled: boolean) { return apiClient .put<{ message: string }>(`admin/jobs/${jobName}/toggle`, { enabled }) .then((r) => r.data); } export function triggerJob( jobName: string, options?: { target_model?: BacktestTargetModel; cadence?: BacktestCadence }, ) { return apiClient .post(`admin/jobs/${jobName}/trigger`, options) .then((r) => r.data); } export function getFundamentalsParityReport() { return apiClient .get('admin/fundamentals-parity') .then((r) => r.data); } export function getFundamentalsParityCsv() { return apiClient .get<{ filename: string; content: string } | null>('admin/fundamentals-parity/csv') .then((r) => r.data); } export function getFundamentalsParityJson() { return apiClient .get<{ filename: string; content: string } | null>('admin/fundamentals-parity/json') .then((r) => r.data); } // System events (operational warnings / errors) export interface SystemEvent { id: number; severity: 'warning' | 'error' | string; source: string; code: string; message: string; symbol: string | null; created_at: string | null; acknowledged_at: string | null; } export interface SystemEventSummary { days: number; total: number; unacknowledged: number; unacknowledged_errors: number; unacknowledged_warnings: number; } export function listSystemEvents(params?: { days?: number; severity?: string; unacknowledged_only?: boolean; }) { return apiClient .get('admin/system-events', { params }) .then((r) => r.data); } export function getSystemEventSummary(days = 7) { return apiClient .get('admin/system-events/summary', { params: { days } }) .then((r) => r.data); } export function acknowledgeSystemEvents(days = 7) { return apiClient .post<{ acknowledged: number }>('admin/system-events/acknowledge', null, { params: { days }, }) .then((r) => r.data); } // Data cleanup export interface CleanupResult { ohlcv: number; sentiment: number; fundamentals: number; sr_refresh_ok: number; sr_refresh_failed: number; sr_refresh_failures: { symbol: string; error: string }[]; } export function cleanupData(olderThanDays: number) { return apiClient .post('admin/data/cleanup', { older_than_days: olderThanDays, }) .then((r) => r.data); } // Track record export function resetTrackRecord() { return apiClient .post<{ trade_setups: number }>('admin/track-record/reset') .then((r) => r.data); }