diff --git a/apps/admin/src/app/ops/page.tsx b/apps/admin/src/app/ops/page.tsx index bf7aad5..fd3c08b 100644 --- a/apps/admin/src/app/ops/page.tsx +++ b/apps/admin/src/app/ops/page.tsx @@ -1,32 +1,17 @@ 'use client'; -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import { AdminShell } from '@/components/AdminShell'; -import { getPolicies, togglePolicy, replaySignal, PolicyInfo } from '@/lib/api'; +import { replaySignal } from '@/lib/api'; const VALID_SUBJECTS = ['signals.tip.served', 'signals.tip.feedback', 'signals.task.synced']; export default function OpsPage() { - const [policies, setPolicies] = useState([]); const [replaySubject, setReplaySubject] = useState(VALID_SUBJECTS[0]); const [replayPayload, setReplayPayload] = useState('{\n "userId": "",\n "tipId": ""\n}'); const [msg, setMsg] = useState(''); const [error, setError] = useState(''); - useEffect(() => { - getPolicies().then((r) => setPolicies(r.policies)).catch(() => {}); - }, []); - - const handleToggle = async (name: string, active: boolean) => { - try { - await togglePolicy(name, active); - setPolicies((prev) => prev.map((p) => p.name === name ? { ...p, active } : p)); - setMsg(`Policy "${name}" ${active ? 'enabled' : 'disabled'}.`); - } catch (e: any) { - setError(e.message); - } - }; - const handleReplay = async () => { let payload: Record; try { @@ -50,36 +35,14 @@ export default function OpsPage() {

Ops

- Live system controls — toggle shadow recommendation policies, replay past signals - for backfill or debugging, and find per-user actions (token revoke, bandit reset) - on the Users page. + Live system controls — replay past signals for backfill or debugging, and find + per-user actions (token revoke) on the{' '} + Users page.

{msg &&

{msg}

} {error &&

{error}

} - {/* Policy toggles */} -
-

Policies

- {policies.length === 0 ? ( -

No shadow policies registered. Shadow policies can be added to the recommender source.

- ) : ( -
- {policies.map((p) => ( -
- {p.name} - -
- ))} -
- )} -
- {/* Replay signal */}

Replay signal

diff --git a/apps/admin/src/lib/api.ts b/apps/admin/src/lib/api.ts index 50cd905..cf73476 100644 --- a/apps/admin/src/lib/api.ts +++ b/apps/admin/src/lib/api.ts @@ -91,10 +91,6 @@ export interface HealthStatus { services: { name: string; status: string; latencyMs: number }[]; } -export interface PolicyInfo { - name: string; - active: boolean; -} export interface SavedQuery { id: string; @@ -223,16 +219,6 @@ export function getHealth() { return apiFetch('/admin/health'); } -export function getPolicies() { - return apiFetch<{ policies: PolicyInfo[] }>('/admin/policies'); -} - -export function togglePolicy(name: string, active: boolean) { - return apiFetch<{ ok: boolean }>(`/admin/policies/${name}/toggle`, { - method: 'POST', - body: JSON.stringify({ active }), - }); -} export function replaySignal(subject: string, payload: Record) { return apiFetch<{ ok: boolean }>('/admin/replay-signal', { diff --git a/services/api/src/routes/admin.ts b/services/api/src/routes/admin.ts index 40e31d4..77ed599 100644 --- a/services/api/src/routes/admin.ts +++ b/services/api/src/routes/admin.ts @@ -18,7 +18,6 @@ import { requireAdmin } from '../middleware/admin.js'; import { nanoid } from 'nanoid'; import { bus } from '../events/bus.js'; import { config } from '../config.js'; -import { getShadowPolicies, setPolicyActive } from './recommender.js'; import { inspectProfile, rebuildProfile, summarizeProfileFreshness } from '../profile/builder.js'; import { spawn } from 'child_process'; import { existsSync, readFileSync, unlinkSync } from 'fs'; @@ -564,36 +563,6 @@ router.get('/health', async (_req: AuthenticatedRequest, res: Response) => { res.json({ ok: allOk, services, checkedAt: new Date().toISOString() }); }); -// --------------------------------------------------------------------------- -// GET /api/admin/policies -// POST /api/admin/policies/:name/toggle -// --------------------------------------------------------------------------- -router.get('/policies', async (_req: AuthenticatedRequest, res: Response) => { - res.json({ policies: getShadowPolicies() }); -}); - -router.post('/policies/:name/toggle', async (req: AuthenticatedRequest, res: Response) => { - const { name } = req.params as { name: string }; - const { active } = req.body as { active: boolean }; - const ok = setPolicyActive(name, active); - if (!ok) { - res.status(404).json({ error: 'Policy not found' }); - return; - } - - await db.insert(adminActions).values({ - id: nanoid(), - adminId: req.userId!, - action: active ? 'enable_policy' : 'disable_policy', - targetType: 'policy', - targetId: name, - detail: null, - createdAt: new Date().toISOString(), - }); - - res.json({ ok: true }); -}); - // --------------------------------------------------------------------------- // POST /api/admin/replay-signal // Re-emit a past event on the bus (for testing / backfill). diff --git a/services/api/src/routes/recommender.ts b/services/api/src/routes/recommender.ts index 5428bd0..bc2dd7f 100644 --- a/services/api/src/routes/recommender.ts +++ b/services/api/src/routes/recommender.ts @@ -41,23 +41,6 @@ function randomPolicy(candidates: TipCandidate[]): TipCandidate | null { return candidates[Math.floor(Math.random() * candidates.length)]; } -// --------------------------------------------------------------------------- -// Shadow-policy registry — kept for step-10 cleanup; no active shadows. -// --------------------------------------------------------------------------- -const shadowPolicies = new Map([ - ['egreedy-v2-shadow', { active: false }], -]); - -export function getShadowPolicies() { - return Array.from(shadowPolicies.entries()).map(([name, s]) => ({ name, ...s })); -} - -export function setPolicyActive(name: string, active: boolean): boolean { - if (!shadowPolicies.has(name)) return false; - shadowPolicies.set(name, { active }); - return true; -} - // --------------------------------------------------------------------------- // Orchestrator: fetch agent snippets + call ml/serving /recommend // ---------------------------------------------------------------------------