import { api } from './client'; // Mirrors internal/api/admin_recommendation_tuning.go (#1250): the // recommendation tuning lab. Field names are the server's snake_case // keys, used verbatim in PATCH bodies. export type WeightProfile = { base_weight: number; like_boost: number; recency_weight: number; skip_penalty: number; jitter_magnitude: number; context_weight: number; similarity_weight: number; taste_weight: number; }; export type TasteTuning = { half_life_days: number; engagement_hard_skip: number; engagement_neutral: number; engagement_full: number; }; export type TuningScope = 'radio' | 'daily_mix' | 'taste'; export type TuningSnapshot = { profiles: Record<'radio' | 'daily_mix', WeightProfile>; taste: TasteTuning; shipped: { profiles: Record<'radio' | 'daily_mix', WeightProfile>; taste: TasteTuning; }; }; export function getTuning(): Promise { return api.get('/api/admin/recommendation-tuning'); } export function patchTuning( scope: TuningScope, values: Record ): Promise { return api.patch(`/api/admin/recommendation-tuning/${scope}`, { values }); } export function resetTuning(scope: TuningScope): Promise { return api.post(`/api/admin/recommendation-tuning/${scope}/reset`, {}); } // Trends (#1251): weekly per-surface outcome series with knob-turn // markers. Mirrors internal/api/admin_recommendation_trends.go. export type TrendPoint = { week_start: string; plays: number; skips: number; skip_rate: number; avg_completion: number; taste_hit_rate: number; }; export type TrendSeries = { key: string; label: string; intent: string; plays: number; points: TrendPoint[]; }; export type TrendMarker = { changed_at: string; scope: string; action: string; changes: { field: string; old: number; new: number }[]; }; export type TrendsResponse = { weeks: number; series: TrendSeries[]; markers: TrendMarker[]; }; export function getTrends(weeks = 12): Promise { return api.get(`/api/admin/recommendation-trends?weeks=${weeks}`); }