feat: add isolated MotorSignal Operations console

This commit is contained in:
Developer 2026-09-10 08:17:06 -04:00
parent 5402412ea0
commit 55b3a5908a
18 changed files with 2355 additions and 85 deletions

View File

@ -1,26 +1,163 @@
import Link from 'next/link';
import { cookies } from 'next/headers';
import { AdminConsole } from '../../components/admin-console';
import { OperationsShell } from '../../components/ops/operations-shell';
import { OperationsErrorState } from '../../components/ops/operations-error-state';
import { normalizeHealthResponse, sanitizeAuditEvent } from '../../lib/ops-data';
import {
OperatorSession,
OperationsHealth,
SafeAuditEvent,
OperationsNavId,
} from '../../components/ops/types';
type AuditEvent = { id: string; event_type: string; actor_user_id: string | null; target_user_id: string | null; created_at: string; metadata: Record<string, unknown> | null };
interface AdminPageProps {
searchParams?: Promise<{
nav?: string;
}>;
}
function parseNavParam(nav?: string): OperationsNavId {
if (nav === 'audit' || nav === 'operators' || nav === 'session') {
return nav;
}
return 'overview';
}
export default async function AdminPage({ searchParams }: AdminPageProps) {
const resolvedParams = searchParams ? await searchParams : {};
const initialNav = parseNavParam(resolvedParams.nav);
const cookieStore = await cookies();
const isProduction = process.env.NODE_ENV === 'production';
const opsToken = isProduction
? cookieStore.get('__Host-motorsignal_ops')?.value
: cookieStore.get('__Host-motorsignal_ops')?.value ??
cookieStore.get('motorsignal_ops')?.value;
// Unauthenticated - prompt for login (Zero query parameter preview/bypass)
if (!opsToken) {
return (
<section className="min-h-screen bg-surface flex items-center justify-center p-4">
<OperationsErrorState
status={401}
message="Your Operations session has expired or is unauthenticated."
/>
</section>
);
}
async function loadAuditEvents(): Promise<{ status: number; events: AuditEvent[] }> {
const token = (await cookies()).get('motorsignal_access_token')?.value;
if (!token) return { status: 401, events: [] };
const baseUrl = process.env.MOTORSIGNAL_API_BASE_URL ?? 'https://api.motorsignal.app';
const headers = {
authorization: `Bearer ${opsToken}`,
accept: 'application/json',
};
try {
const response = await fetch(`${baseUrl}/api/v1/admin/audit-events`, { headers: { authorization: `Bearer ${token}` }, cache: 'no-store' });
if (!response.ok) return { status: response.status, events: [] };
return { status: response.status, events: await response.json() as AuditEvent[] };
// STEP 1: Verify Operations identity & role first
const meResponse = await fetch(`${baseUrl}/api/v1/ops/me`, { headers, cache: 'no-store' });
if (meResponse.status === 401) {
return (
<section className="min-h-screen bg-surface flex items-center justify-center p-4">
<OperationsErrorState
status={401}
message="Your Operations session has expired. Please sign in again."
/>
</section>
);
}
if (meResponse.status === 403) {
return (
<section className="min-h-screen bg-surface flex items-center justify-center p-4">
<OperationsErrorState
status={403}
message="You do not have sufficient authority to access Operations."
/>
</section>
);
}
if (!meResponse.ok) {
return (
<section className="min-h-screen bg-surface flex items-center justify-center p-4">
<OperationsErrorState
status={503}
message="Operations platform is temporarily unavailable."
/>
</section>
);
}
const meData = await meResponse.json();
const session: OperatorSession = {
identity: meData.identity ?? meData.email ?? 'operator',
role: meData.role === 'owner' ? 'owner' : 'operator',
status: meData.status === 'expired' || meData.status === 'revoked' ? meData.status : 'active',
createdAt: meData.created_at ?? meData.createdAt,
lastActivityAt: meData.last_activity_at ?? meData.lastActivityAt,
expiresAt: meData.expires_at ?? meData.expiresAt,
environment: process.env.NODE_ENV === 'production' ? 'production' : 'development',
};
// STEP 2: After successful verified session, fetch health, and ONLY fetch audit if role == 'owner'
const isOwner = session.role === 'owner';
const [healthResponse, auditResponse] = await Promise.all([
fetch(`${baseUrl}/api/v1/ops/health`, { headers, cache: 'no-store' }),
isOwner
? fetch(`${baseUrl}/api/v1/ops/audit-events`, { headers, cache: 'no-store' }).catch(() => null)
: Promise.resolve(null),
]);
let health: OperationsHealth;
if (healthResponse.ok) {
const healthData = await healthResponse.json();
health = normalizeHealthResponse(healthData);
} else {
health = normalizeHealthResponse({ status: 'unavailable', checked_at: new Date().toISOString() });
}
let initialAuditEvents: SafeAuditEvent[] = [];
let nextCursor: string | null = null;
let auditTotal: number | undefined = undefined;
if (auditResponse && auditResponse.ok) {
const auditData = await auditResponse.json();
const rawEvents = Array.isArray(auditData)
? auditData
: Array.isArray(auditData?.events)
? auditData.events
: Array.isArray(auditData?.items)
? auditData.items
: [];
initialAuditEvents = rawEvents
.map(sanitizeAuditEvent)
.filter((e: SafeAuditEvent | null): e is SafeAuditEvent => e !== null);
nextCursor = auditData?.next_cursor ?? auditData?.cursor ?? null;
if (typeof auditData?.total === 'number') {
auditTotal = auditData.total;
}
}
return (
<OperationsShell
initialSession={session}
initialHealth={health}
initialAudit={{
events: initialAuditEvents,
next_cursor: nextCursor,
total: auditTotal,
}}
initialNav={initialNav}
/>
);
} catch {
return { status: 503, events: [] };
return (
<section className="min-h-screen bg-surface flex items-center justify-center p-4">
<OperationsErrorState
status={503}
message="Unable to connect to the Operations platform service."
/>
</section>
);
}
}
export default async function AdminPage() {
const result = await loadAuditEvents();
if (result.status === 401) return <section className="content-page"><span className="eyebrow">Admin console</span><h1>Sign in required.</h1><p>Admin tools require an authenticated MotorSignal session.</p><Link className="button" href="/login">Sign in</Link></section>;
if (result.status === 403) return <section className="content-page"><span className="eyebrow">Admin console</span><h1>Access restricted.</h1><p>Your account does not have support or admin permissions.</p><Link className="button button-secondary" href="/account">Back to account</Link></section>;
if (result.status !== 200) return <section className="content-page"><span className="eyebrow">Admin console</span><h1>Console unavailable.</h1><p>Audit data could not be loaded. Try again when the API is available.</p></section>;
return <section className="content-page"><span className="eyebrow">Admin console</span><h1>Operations.</h1><p>Manage users, vehicles, rides, and review recent account activity.</p><AdminConsole /><h2 className="admin-audit-heading">Recent audit events</h2><div className="audit-list">{result.events.length === 0 ? <div className="panel"><p>No events recorded.</p></div> : result.events.map((event) => <article className="panel audit-row" key={event.id}><div><strong>{event.event_type}</strong><p>{event.actor_user_id ?? 'System'} {event.target_user_id ? `targeted ${event.target_user_id}` : ''}</p></div><time dateTime={event.created_at}>{new Date(event.created_at).toLocaleString()}</time></article>)}</div></section>;
}

View File

@ -1,20 +0,0 @@
import { cookies } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server';
const resources = new Set(['users', 'vehicles', 'rides']);
async function proxy(request: NextRequest, context: { params: Promise<{ path: string[] }> }) {
const { path } = await context.params;
if (!path.length || !resources.has(path[0])) return NextResponse.json({ detail: 'Unknown admin resource.' }, { status: 404 });
const token = (await cookies()).get('motorsignal_access_token')?.value;
if (!token) return NextResponse.json({ detail: 'Authentication required.' }, { status: 401 });
const baseUrl = process.env.MOTORSIGNAL_API_BASE_URL ?? 'https://api.motorsignal.app';
const body = request.method === 'GET' || request.method === 'DELETE' ? undefined : await request.text();
const response = await fetch(`${baseUrl}/api/v1/admin/${path.join('/')}${request.nextUrl.search}`, { method: request.method, headers: { authorization: `Bearer ${token}`, ...(body ? { 'content-type': 'application/json' } : {}) }, body, cache: 'no-store' });
return new NextResponse(await response.text(), { status: response.status, headers: { 'content-type': response.headers.get('content-type') ?? 'application/json' } });
}
export const GET = proxy;
export const POST = proxy;
export const PATCH = proxy;
export const DELETE = proxy;

View File

@ -0,0 +1,87 @@
import { cookies } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server';
import { sanitizeAuditEvent } from '../../../../lib/ops-data';
import { SafeAuditEvent } from '../../../../components/ops/types';
export async function GET(request: NextRequest) {
const cookieStore = await cookies();
const isProduction = process.env.NODE_ENV === 'production';
const opsToken = isProduction
? cookieStore.get('__Host-motorsignal_ops')?.value
: cookieStore.get('__Host-motorsignal_ops')?.value ??
cookieStore.get('motorsignal_ops')?.value;
if (!opsToken) {
return NextResponse.json(
{ detail: 'Authentication required.' },
{ status: 401 }
);
}
const cursor = request.nextUrl.searchParams.get('cursor');
const baseUrl = process.env.MOTORSIGNAL_API_BASE_URL ?? 'https://api.motorsignal.app';
const targetUrl = new URL(`${baseUrl}/api/v1/ops/audit-events`);
if (cursor) {
targetUrl.searchParams.set('cursor', cursor);
}
try {
const response = await fetch(targetUrl.toString(), {
method: 'GET',
headers: {
authorization: `Bearer ${opsToken}`,
accept: 'application/json',
},
cache: 'no-store',
});
if (response.status === 401) {
return NextResponse.json(
{ detail: 'Your Operations session has expired.' },
{ status: 401 }
);
}
if (response.status === 403) {
return NextResponse.json(
{ detail: 'You do not have authority to view Audit.' },
{ status: 403 }
);
}
if (!response.ok) {
return NextResponse.json(
{ detail: 'Operations is temporarily unavailable.' },
{ status: response.status >= 500 ? response.status : 503 }
);
}
const data = await response.json();
const rawEvents = Array.isArray(data)
? data
: Array.isArray(data?.events)
? data.events
: Array.isArray(data?.items)
? data.items
: [];
const safeEvents: SafeAuditEvent[] = rawEvents
.map(sanitizeAuditEvent)
.filter((e: SafeAuditEvent | null): e is SafeAuditEvent => e !== null);
const nextCursor = data?.next_cursor ?? data?.cursor ?? null;
const total = typeof data?.total === 'number' ? data.total : undefined;
return NextResponse.json(
{
events: safeEvents,
next_cursor: nextCursor,
total,
},
{ status: 200 }
);
} catch {
return NextResponse.json(
{ detail: 'Operations is temporarily unavailable.' },
{ status: 503 }
);
}
}

View File

@ -0,0 +1,61 @@
import { cookies } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server';
import { hasValidOrigin } from '../../../../../lib/request-origin';
export async function POST(request: NextRequest) {
// 1. Validate request origin
if (!hasValidOrigin(request)) {
return NextResponse.json({ detail: 'Invalid request origin.' }, { status: 403 });
}
// 2. Obtain real Operations session cookie
const cookieStore = await cookies();
const isProduction = process.env.NODE_ENV === 'production';
const opsToken = isProduction
? cookieStore.get('__Host-motorsignal_ops')?.value
: cookieStore.get('__Host-motorsignal_ops')?.value ??
cookieStore.get('motorsignal_ops')?.value;
// 3. If token present, invoke backend session revocation endpoint
if (opsToken) {
const baseUrl = process.env.MOTORSIGNAL_API_BASE_URL ?? 'https://api.motorsignal.app';
try {
await fetch(`${baseUrl}/api/v1/ops/sessions/current`, {
method: 'DELETE',
headers: {
authorization: `Bearer ${opsToken}`,
accept: 'application/json',
},
cache: 'no-store',
});
// All terminal backend states (204, 200, 401 already expired, 403, 404, 503) proceed to clear local cookie
} catch {
// Network failure / backend unavailable: proceed safely to clear local cookie without leaking internals
}
}
// 4. Clear local Operations cookies (host and non-host dev fallback)
const response = new NextResponse(null, { status: 204 });
response.cookies.set('__Host-motorsignal_ops', '', {
httpOnly: true,
secure: true,
sameSite: 'strict',
path: '/',
maxAge: 0,
expires: new Date(0),
});
response.cookies.set('motorsignal_ops', '', {
httpOnly: true,
secure: isProduction,
sameSite: 'strict',
path: '/',
maxAge: 0,
expires: new Date(0),
});
// Rider consumer session cookies are completely unreferenced and untouched
return response;
}

View File

@ -0,0 +1,56 @@
import { cookies } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server';
import { normalizeHealthResponse } from '../../../../lib/ops-data';
export async function GET(request: NextRequest) {
const cookieStore = await cookies();
const isProduction = process.env.NODE_ENV === 'production';
const opsToken = isProduction
? cookieStore.get('__Host-motorsignal_ops')?.value
: cookieStore.get('__Host-motorsignal_ops')?.value ??
cookieStore.get('motorsignal_ops')?.value;
const baseUrl = process.env.MOTORSIGNAL_API_BASE_URL ?? 'https://api.motorsignal.app';
const headers: Record<string, string> = {
accept: 'application/json',
};
if (opsToken) {
headers['authorization'] = `Bearer ${opsToken}`;
}
try {
const response = await fetch(`${baseUrl}/api/v1/ops/health`, {
method: 'GET',
headers,
cache: 'no-store',
});
if (!response.ok) {
if (response.status === 401) {
return NextResponse.json(
{ detail: 'Authentication required.' },
{ status: 401 }
);
}
if (response.status === 403) {
return NextResponse.json(
{ detail: 'Access restricted.' },
{ status: 403 }
);
}
return NextResponse.json(
normalizeHealthResponse({ status: 'unavailable', checked_at: new Date().toISOString() }),
{ status: 503 }
);
}
const data = await response.json();
return NextResponse.json(normalizeHealthResponse(data), { status: 200 });
} catch {
return NextResponse.json(
normalizeHealthResponse({ status: 'unavailable', checked_at: new Date().toISOString() }),
{ status: 503 }
);
}
}

View File

@ -0,0 +1,68 @@
import { cookies } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server';
import { OperatorSession } from '../../../../components/ops/types';
export async function GET(request: NextRequest) {
const cookieStore = await cookies();
const isProduction = process.env.NODE_ENV === 'production';
const opsToken = isProduction
? cookieStore.get('__Host-motorsignal_ops')?.value
: cookieStore.get('__Host-motorsignal_ops')?.value ??
cookieStore.get('motorsignal_ops')?.value;
if (!opsToken) {
return NextResponse.json(
{ detail: 'Authentication required.' },
{ status: 401 }
);
}
const baseUrl = process.env.MOTORSIGNAL_API_BASE_URL ?? 'https://api.motorsignal.app';
try {
const response = await fetch(`${baseUrl}/api/v1/ops/me`, {
method: 'GET',
headers: {
authorization: `Bearer ${opsToken}`,
accept: 'application/json',
},
cache: 'no-store',
});
if (response.status === 401) {
return NextResponse.json(
{ detail: 'Your Operations session has expired.' },
{ status: 401 }
);
}
if (response.status === 403) {
return NextResponse.json(
{ detail: 'Access restricted.' },
{ status: 403 }
);
}
if (!response.ok) {
return NextResponse.json(
{ detail: 'Operations is temporarily unavailable.' },
{ status: 503 }
);
}
const data = await response.json();
const session: OperatorSession = {
identity: data.identity ?? data.email ?? 'operator',
role: data.role === 'owner' ? 'owner' : 'operator',
status: data.status === 'expired' || data.status === 'revoked' ? data.status : 'active',
createdAt: data.created_at ?? data.createdAt,
lastActivityAt: data.last_activity_at ?? data.lastActivityAt,
expiresAt: data.expires_at ?? data.expiresAt,
environment: process.env.NODE_ENV === 'production' ? 'production' : 'development',
};
return NextResponse.json({ session }, { status: 200 });
} catch {
return NextResponse.json(
{ detail: 'Operations is temporarily unavailable.' },
{ status: 503 }
);
}
}

View File

@ -1,47 +0,0 @@
'use client';
import { FormEvent, useEffect, useState } from 'react';
type Resource = 'users' | 'vehicles' | 'rides';
type Item = Record<string, string | number | boolean | null>;
async function adminRequest(path: string, init?: RequestInit) {
const response = await fetch(`/api/admin/${path}`, { ...init, headers: { 'content-type': 'application/json', ...(init?.headers ?? {}) } });
const body = await response.json().catch(() => null);
if (!response.ok) throw new Error(body?.detail ?? 'Admin request failed.');
return body;
}
export function AdminConsole() {
const [resource, setResource] = useState<Resource>('users');
const [items, setItems] = useState<Item[]>([]);
const [message, setMessage] = useState('');
const [busy, setBusy] = useState(false);
async function load(selected = resource) {
setBusy(true); setMessage('');
try { const body = await adminRequest(`${selected}?page=1&page_size=50`); setItems(body.items ?? []); }
catch (error) { setItems([]); setMessage(error instanceof Error ? error.message : 'Unable to load admin data.'); }
finally { setBusy(false); }
}
useEffect(() => { void load(); }, [resource]);
async function create(event: FormEvent<HTMLFormElement>) {
event.preventDefault(); setBusy(true); setMessage('');
const form = new FormData(event.currentTarget);
const payload = Object.fromEntries(form.entries());
try { await adminRequest(resource, { method: 'POST', body: JSON.stringify(payload) }); event.currentTarget.reset(); setMessage('Created.'); await load(); }
catch (error) { setMessage(error instanceof Error ? error.message : 'Create failed.'); }
finally { setBusy(false); }
}
async function archive(id: string) {
setBusy(true); setMessage('');
try { await adminRequest(`${resource}/${id}`, { method: 'DELETE' }); setMessage(resource === 'rides' ? 'Ride archived.' : 'Deleted.'); await load(); }
catch (error) { setMessage(error instanceof Error ? error.message : 'Action failed.'); }
finally { setBusy(false); }
}
return <div className="admin-console"><div className="admin-tabs">{(['users', 'vehicles', 'rides'] as Resource[]).map((value) => <button className={resource === value ? 'admin-tab active' : 'admin-tab'} key={value} onClick={() => setResource(value)} type="button">{value}</button>)}</div><form className="admin-create-form" onSubmit={create}>{resource === 'users' && <><input name="email" required placeholder="Email" type="email" /><input name="password" required minLength={12} placeholder="Temporary password" type="password" /><select defaultValue="user" name="role"><option value="user">User</option><option value="support">Support</option><option value="admin">Admin</option></select></>}{resource === 'vehicles' && <><input name="user_id" required placeholder="Owner user ID" /><input name="nickname" required placeholder="Nickname" /><input name="make" required placeholder="Make" /><input name="model" required placeholder="Model" /><input name="year" placeholder="Year" type="number" /></>}{resource === 'rides' && <><input name="user_id" required placeholder="Rider user ID" /><input name="vehicle_id" placeholder="Vehicle ID" /><input name="started_at" required type="datetime-local" /><input name="distance_miles" placeholder="Distance miles" type="number" step="0.1" /><input name="top_speed_mph" placeholder="Top speed MPH" type="number" step="0.1" /></>}<button className="button" disabled={busy} type="submit">Create {resource.slice(0, -1)}</button></form>{message && <p className="form-message" role="status">{message}</p>}<div className="admin-table-wrap"><table className="admin-table"><thead><tr>{resource === 'users' ? <><th>Email</th><th>Role</th><th>Status</th><th /></> : resource === 'vehicles' ? <><th>Nickname</th><th>Make / model</th><th>Owner</th><th /></> : <><th>Ride</th><th>Rider</th><th>Distance</th><th>Status</th><th /></>}</tr></thead><tbody>{items.map((item) => <tr key={String(item.id)}>{resource === 'users' ? <><td>{String(item.email)}</td><td>{String(item.role)}</td><td>{item.is_active ? 'Active' : 'Inactive'}</td><td><button className="text-button" onClick={() => void archive(String(item.id))} type="button">Deactivate</button></td></> : resource === 'vehicles' ? <><td>{String(item.nickname)}</td><td>{String(item.make)} {String(item.model)}</td><td>{String(item.user_id)}</td><td><button className="text-button" onClick={() => void archive(String(item.id))} type="button">Delete</button></td></> : <><td>{String(item.id).slice(0, 8)}</td><td>{String(item.user_id)}</td><td>{item.distance_miles == null ? '-' : `${item.distance_miles} mi`}</td><td>{String(item.status)}</td><td>{item.status !== 'archived' && <button className="text-button" onClick={() => void archive(String(item.id))} type="button">Archive</button>}</td></>}</tr>)}</tbody></table>{!busy && items.length === 0 && <p className="empty-state">No {resource} found.</p>}</div></div>;
}

View File

@ -0,0 +1,254 @@
'use client';
import React from 'react';
import { SafeAuditEvent, OperationsRole } from './types';
interface OperationsAuditProps {
role: OperationsRole;
events: SafeAuditEvent[];
nextCursor?: string | null;
onNextPage?: () => Promise<void> | void;
isLoading?: boolean;
isLoadingMore?: boolean;
total?: number;
}
export function OperationsAudit({
role,
events,
nextCursor,
onNextPage,
isLoading = false,
isLoadingMore = false,
total,
}: OperationsAuditProps) {
const isOwner = role === 'owner';
// Section 7: Operator Denied Access UX
if (!isOwner) {
return (
<div className="p-8 rounded-xl bg-surface-container-low border border-outline-variant/30 text-center max-w-xl mx-auto my-12 space-y-4">
<div className="w-12 h-12 rounded-full bg-surface-container-high border border-outline-variant/40 flex items-center justify-center text-outline mx-auto">
<span className="material-symbols-outlined text-[24px]">lock</span>
</div>
<div>
<span className="text-[10px] font-mono uppercase tracking-widest text-outline">
ACCESS RESTRICTED
</span>
<h2 className="text-lg font-bold text-on-surface mt-1">
Owner Authority Required
</h2>
<p className="text-xs text-on-surface-variant mt-2 leading-relaxed">
You do not have authority to view Audit. Audit log inspection is restricted to verified Operations Owners.
</p>
</div>
<div className="pt-3 border-t border-outline-variant/20 flex items-center justify-center gap-2 text-xs text-outline font-mono">
<span>Current Role:</span>
<span className="px-2 py-0.5 rounded bg-surface-container-highest text-on-surface font-semibold uppercase">
{role}
</span>
</div>
</div>
);
}
return (
<div className="space-y-6">
{/* Header Row */}
<div className="flex flex-col sm:flex-row sm:items-end justify-between gap-4 pb-4 border-b border-outline-variant/30">
<div>
<span className="text-[11px] font-mono uppercase tracking-widest text-primary-fixed-dim">
GOVERNANCE &amp; COMPLIANCE
</span>
<h1 className="font-headline-xl text-2xl sm:text-3xl font-bold text-on-surface tracking-tight mt-1">
Audit Activity
</h1>
<p className="text-xs text-on-surface-variant mt-1">
Immutable operational and security activity log across platform boundaries.
</p>
</div>
{total !== undefined && (
<div className="text-right shrink-0">
<span className="text-[10px] uppercase font-mono text-outline block">
Recorded Events
</span>
<span className="text-xs font-mono font-bold text-on-surface">
{total.toLocaleString()}
</span>
</div>
)}
</div>
{/* Audit Activity Table Container */}
<div className="rounded-xl bg-surface-container-low border border-outline-variant/30 overflow-hidden shadow-sm">
<div className="overflow-x-auto">
<table
className="w-full text-left border-collapse min-w-[720px]"
aria-label="Operations Audit Events"
>
<thead>
<tr className="border-b border-outline-variant/30 bg-surface-container-lowest/60 text-[11px] font-mono uppercase tracking-wider text-outline">
<th scope="col" className="py-3 px-4">
TIME
</th>
<th scope="col" className="py-3 px-4">
ACTION
</th>
<th scope="col" className="py-3 px-4">
RESULT
</th>
<th scope="col" className="py-3 px-4">
ACTOR
</th>
<th scope="col" className="py-3 px-4">
TARGET
</th>
<th scope="col" className="py-3 px-4">
CASE
</th>
</tr>
</thead>
<tbody className="divide-y divide-outline-variant/20 text-xs">
{isLoading ? (
// Skeleton loading state
Array.from({ length: 5 }).map((_, index) => (
<tr key={`skeleton-${index}`} className="animate-pulse">
<td className="py-3.5 px-4">
<div className="h-3 w-28 bg-surface-container-high rounded"></div>
</td>
<td className="py-3.5 px-4">
<div className="h-4 w-32 bg-surface-container-high rounded"></div>
</td>
<td className="py-3.5 px-4">
<div className="h-4 w-16 bg-surface-container-high rounded"></div>
</td>
<td className="py-3.5 px-4">
<div className="h-3 w-36 bg-surface-container-high rounded"></div>
</td>
<td className="py-3.5 px-4">
<div className="h-3 w-20 bg-surface-container-high rounded"></div>
</td>
<td className="py-3.5 px-4">
<div className="h-3 w-16 bg-surface-container-high rounded"></div>
</td>
</tr>
))
) : events.length === 0 ? (
<tr>
<td
colSpan={6}
className="py-12 px-4 text-center text-on-surface-variant"
>
<span className="material-symbols-outlined text-[32px] text-outline block mb-2">
inbox
</span>
<p className="text-xs font-medium">No audit events recorded.</p>
</td>
</tr>
) : (
events.map((event, index) => {
const formattedTime = new Date(event.timestamp).toLocaleString('en-US', {
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
const isSuccess =
event.result.toLowerCase() === 'success' ||
event.result.toLowerCase() === 'recorded';
const isFailure =
event.result.toLowerCase() === 'failure' ||
event.result.toLowerCase() === 'denied';
return (
<tr
key={`event-${index}`}
className="hover:bg-surface-container-high/40 transition-colors"
>
{/* TIME */}
<td className="py-3 px-4 font-mono text-[11px] text-on-surface-variant whitespace-nowrap">
<time dateTime={event.timestamp}>{formattedTime}</time>
</td>
{/* ACTION */}
<td className="py-3 px-4 font-medium text-on-surface whitespace-nowrap">
<div className="flex flex-col">
<span className="font-mono text-xs">{event.action}</span>
{event.reason_code && (
<span className="text-[10px] text-outline font-mono">
reason: {event.reason_code}
</span>
)}
</div>
</td>
{/* RESULT */}
<td className="py-3 px-4 whitespace-nowrap">
<span
className={`inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-mono uppercase font-bold tracking-wider border ${
isSuccess
? 'bg-emerald-950/60 text-emerald-400 border-emerald-800/60'
: isFailure
? 'bg-rose-950/60 text-rose-400 border-rose-800/60'
: 'bg-surface-container-highest text-on-surface-variant border-outline-variant/30'
}`}
>
{event.result}
</span>
</td>
{/* ACTOR (Current Operations Identity) */}
<td className="py-3 px-4">
<div className="flex flex-col">
<span className="font-semibold text-on-surface truncate max-w-[200px]" title={event.actor_identity}>
{event.actor_identity}
</span>
{event.actor_role && (
<span className="text-[10px] text-outline font-mono uppercase">
Role: {event.actor_role}
</span>
)}
</div>
</td>
{/* TARGET */}
<td className="py-3 px-4 font-mono text-[11px] text-on-surface-variant">
{event.target_resource || '--'}
</td>
{/* CASE */}
<td className="py-3 px-4 font-mono text-[11px] text-on-surface-variant">
{event.case_reference || '--'}
</td>
</tr>
);
})
)}
</tbody>
</table>
</div>
{/* Server Cursor Bounded Pagination */}
{nextCursor && (
<div className="p-3 border-t border-outline-variant/30 bg-surface-container-lowest/40 flex items-center justify-between">
<span className="text-[11px] text-outline font-mono">
Displaying bounded result set
</span>
<button
type="button"
onClick={() => void onNextPage?.()}
disabled={isLoadingMore}
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-surface-container-high hover:bg-surface-bright text-on-surface border border-outline-variant/40 text-xs font-semibold transition-colors focus-visible:ring-2 focus-visible:ring-primary-container focus-visible:outline-none disabled:opacity-50"
>
<span>{isLoadingMore ? 'Loading...' : 'Next Page'}</span>
<span className="material-symbols-outlined text-[14px]">arrow_forward</span>
</button>
</div>
)}
</div>
</div>
);
}

View File

@ -0,0 +1,97 @@
'use client';
import React from 'react';
import Link from 'next/link';
interface OperationsErrorStateProps {
status: 401 | 403 | 404 | 503 | 'disabled' | 'network' | number;
message?: string;
onRetry?: () => void;
}
export function OperationsErrorState({
status,
message,
onRetry,
}: OperationsErrorStateProps) {
let title = 'Operations Error';
let description = message ?? 'An unexpected error occurred in the Operations console.';
let icon = 'error';
let showSignIn = false;
let showRetry = true;
if (status === 401) {
title = 'Authentication Required';
description = message ?? 'Your Operations session has expired or is unauthenticated.';
icon = 'lock';
showSignIn = true;
showRetry = false;
} else if (status === 403) {
title = 'Access Restricted';
description = message ?? 'You do not have sufficient authority to access Operations.';
icon = 'gavel';
showSignIn = false;
showRetry = false;
} else if (status === 404) {
title = 'Resource Not Found';
description = message ?? 'The requested Operations resource does not exist.';
icon = 'search_off';
} else if (status === 503 || status === 'network') {
title = 'Operations Temporarily Unavailable';
description = message ?? 'Unable to communicate with the Operations API. Try again in a few moments.';
icon = 'cloud_off';
} else if (status === 'disabled') {
title = 'Operations Disabled';
description = message ?? 'The Operations platform is currently disabled by system policy.';
icon = 'block';
showRetry = false;
}
return (
<div className="p-8 rounded-xl bg-surface-container-low border border-outline-variant/30 text-center max-w-lg mx-auto my-12 space-y-4 shadow-sm">
<div className="w-12 h-12 rounded-full bg-surface-container-high border border-outline-variant/40 flex items-center justify-center text-outline mx-auto">
<span className="material-symbols-outlined text-[24px]">{icon}</span>
</div>
<div className="space-y-1">
<span className="text-[10px] font-mono uppercase tracking-widest text-outline">
STATUS {typeof status === 'number' ? status : status.toUpperCase()}
</span>
<h2 className="text-lg font-bold text-on-surface">{title}</h2>
<p className="text-xs text-on-surface-variant leading-relaxed">
{description}
</p>
</div>
<div className="pt-4 border-t border-outline-variant/20 flex items-center justify-center gap-3">
{showSignIn && (
<Link
href="/login"
className="inline-flex items-center gap-1.5 px-4 py-2 rounded-lg bg-primary-container text-on-primary-container text-xs font-bold shadow-sm hover:brightness-105 transition-all focus-visible:ring-2 focus-visible:ring-primary-container focus-visible:outline-none"
>
<span className="material-symbols-outlined text-[16px]">login</span>
<span>Sign In</span>
</Link>
)}
{showRetry && onRetry && (
<button
type="button"
onClick={onRetry}
className="inline-flex items-center gap-1.5 px-4 py-2 rounded-lg bg-surface-container-high hover:bg-surface-bright text-on-surface border border-outline-variant/30 text-xs font-semibold transition-all focus-visible:ring-2 focus-visible:ring-primary-container focus-visible:outline-none"
>
<span className="material-symbols-outlined text-[16px]">refresh</span>
<span>Retry</span>
</button>
)}
<Link
href="/"
className="inline-flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-medium text-on-surface-variant hover:text-on-surface transition-colors"
>
Return Home
</Link>
</div>
</div>
);
}

View File

@ -0,0 +1,50 @@
'use client';
import React from 'react';
export function OperationsOperators() {
return (
<div className="space-y-6">
{/* Header Row */}
<div className="pb-4 border-b border-outline-variant/30">
<span className="text-[11px] font-mono uppercase tracking-widest text-primary-fixed-dim">
ACCESS CONTROL
</span>
<h1 className="font-headline-xl text-2xl sm:text-3xl font-bold text-on-surface tracking-tight mt-1">
OPERATORS
</h1>
<p className="text-xs text-on-surface-variant mt-1">
Directory and role assignments for platform administrative operators.
</p>
</div>
{/* Clean Placeholder Panel */}
<div className="p-8 rounded-xl bg-surface-container-low border border-outline-variant/30 max-w-2xl mx-auto my-8 text-center space-y-4 shadow-sm">
<div className="w-12 h-12 rounded-full bg-surface-container-high border border-outline-variant/40 flex items-center justify-center text-outline mx-auto">
<span className="material-symbols-outlined text-[24px]">manage_accounts</span>
</div>
<div className="space-y-2">
<h2 className="text-base font-bold text-on-surface uppercase tracking-wide">
OPERATORS
</h2>
<p className="text-xs text-on-surface-variant max-w-md mx-auto leading-relaxed">
Operator management is not enabled in this Operations foundation.
</p>
</div>
<div className="pt-4 border-t border-outline-variant/20 text-[11px] text-outline text-left space-y-2 bg-surface-container-lowest/50 p-4 rounded-lg">
<div className="flex items-center gap-1.5 font-mono text-on-surface font-semibold uppercase text-[10px]">
<span className="material-symbols-outlined text-[14px] text-primary-fixed-dim">
info
</span>
<span>Security Governance Policy</span>
</div>
<p className="leading-normal">
Operator accounts, role promotions, and revocations are managed strictly through versioned PostgreSQL infrastructure migrations on the <code className="text-primary-fixed-dim font-mono">ops.operators</code> table.
</p>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,203 @@
'use client';
import React from 'react';
import { OperationsHealth, ComponentHealthStatus, HealthComponentKey } from './types';
import { HEALTH_COMPONENT_METADATA } from '../../lib/ops-data';
interface OperationsOverviewProps {
health: OperationsHealth;
onRefresh: () => Promise<void> | void;
isRefreshing: boolean;
}
export function OperationsOverview({
health,
onRefresh,
isRefreshing,
}: OperationsOverviewProps) {
const componentKeys: HealthComponentKey[] = [
'operations_api',
'operations_database',
'session_validation',
'audit_persistence',
];
function getStatusBadge(status: ComponentHealthStatus) {
switch (status) {
case 'available':
return {
label: 'AVAILABLE',
icon: 'check_circle',
classes: 'bg-emerald-950/60 text-emerald-400 border-emerald-800/60',
};
case 'degraded':
return {
label: 'DEGRADED',
icon: 'warning',
classes: 'bg-amber-950/60 text-amber-400 border-amber-800/60',
};
case 'unavailable':
return {
label: 'UNAVAILABLE',
icon: 'cancel',
classes: 'bg-rose-950/60 text-rose-400 border-rose-800/60',
};
case 'unknown':
default:
return {
label: 'UNKNOWN',
icon: 'help',
classes: 'bg-surface-container-highest text-on-surface-variant border-outline-variant/40',
};
}
}
const formattedCheckedAt = health.checked_at
? new Date(health.checked_at).toLocaleString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZoneName: 'short',
})
: '--';
return (
<div className="space-y-6">
{/* Header Row: Title & Manual Refresh */}
<div className="flex flex-col sm:flex-row sm:items-end justify-between gap-4 pb-4 border-b border-outline-variant/30">
<div>
<span className="text-[11px] font-mono uppercase tracking-widest text-primary-fixed-dim">
SYSTEM HEALTH
</span>
<h1 className="font-headline-xl text-2xl sm:text-3xl font-bold text-on-surface tracking-tight mt-1">
Operations Overview
</h1>
<p className="text-xs text-on-surface-variant mt-1">
Real-time health telemetry across core Operations subsystems.
</p>
</div>
<div className="flex items-center gap-3 shrink-0">
<div className="text-right">
<span className="block text-[10px] uppercase font-mono text-outline">
Last checked
</span>
<time
dateTime={health.checked_at}
className="text-xs font-mono text-on-surface font-medium"
>
{formattedCheckedAt}
</time>
</div>
<button
type="button"
onClick={() => void onRefresh()}
disabled={isRefreshing}
aria-label="Refresh Operations health status"
className="inline-flex items-center gap-1.5 px-3.5 py-2 rounded-lg bg-surface-container-high hover:bg-surface-bright text-primary-container border border-primary-container/40 text-xs font-semibold shadow-sm transition-all focus-visible:ring-2 focus-visible:ring-primary-container focus-visible:outline-none disabled:opacity-50 disabled:cursor-not-allowed"
>
<span
className={`material-symbols-outlined text-[16px] ${
isRefreshing ? 'animate-spin' : ''
}`}
>
refresh
</span>
<span>{isRefreshing ? 'Checking...' : 'Refresh'}</span>
</button>
</div>
</div>
{/* 4 Health Status Cards */}
<div
className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4"
aria-label="Subsystem Health Telemetry"
>
{componentKeys.map((key) => {
const meta = HEALTH_COMPONENT_METADATA[key];
const comp = health.components?.[key];
const status = comp?.status ?? 'unknown';
const badge = getStatusBadge(status);
return (
<article
key={key}
className="p-4 rounded-xl bg-surface-container-low border border-outline-variant/30 flex flex-col justify-between gap-3 relative overflow-hidden group hover:border-outline-variant/60 transition-colors"
>
<div className="space-y-1">
<span className="text-[10px] font-mono uppercase tracking-wider text-outline">
Subsystem
</span>
<h2 className="text-sm font-bold text-on-surface tracking-tight">
{meta.name}
</h2>
<p className="text-[11px] text-on-surface-variant leading-relaxed">
{comp?.description || meta.description}
</p>
</div>
<div className="pt-2 border-t border-outline-variant/20 flex items-center justify-between">
<span className="text-[10px] text-outline font-mono uppercase">
Status
</span>
<div
className={`inline-flex items-center gap-1 px-2 py-0.5 rounded text-[10px] font-mono font-bold tracking-wider border uppercase ${badge.classes}`}
role="status"
aria-live="polite"
>
<span className="material-symbols-outlined text-[12px]">
{badge.icon}
</span>
<span>{badge.label}</span>
</div>
</div>
</article>
);
})}
</div>
{/* Operational Policy & Architecture Boundary */}
<div className="p-5 rounded-xl bg-surface-container-lowest border border-outline-variant/30 space-y-3">
<div className="flex items-center gap-2">
<span className="material-symbols-outlined text-primary-container text-[18px]">
verified_user
</span>
<h3 className="text-xs font-bold text-on-surface uppercase tracking-wider">
Operational Architecture &amp; Data Boundary
</h3>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 text-xs text-on-surface-variant pt-2 border-t border-outline-variant/20">
<div>
<span className="block font-semibold text-on-surface mb-0.5">
Authority Source
</span>
<p className="leading-normal">
PostgreSQL <code className="text-primary-fixed-dim">ops.operators</code> schema. Consumer roles and Firebase custom claims strictly bypassed.
</p>
</div>
<div>
<span className="block font-semibold text-on-surface mb-0.5">
Privacy Isolation
</span>
<p className="leading-normal">
Zero cross-rider data access. Personal rides, GPS points, vehicles, and billing accounts are structurally inaccessible.
</p>
</div>
<div>
<span className="block font-semibold text-on-surface mb-0.5">
Session Integrity
</span>
<p className="leading-normal">
Governed by host-prefixed <code className="text-primary-fixed-dim">__Host-motorsignal_ops</code> cookies with strict same-origin isolation.
</p>
</div>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,161 @@
'use client';
import React from 'react';
import { OperatorSession } from './types';
interface OperationsSessionProps {
session: OperatorSession;
onSignOut: () => void;
signingOut?: boolean;
}
export function OperationsSessionView({
session,
onSignOut,
signingOut = false,
}: OperationsSessionProps) {
function formatDate(isoString?: string) {
if (!isoString) return '--';
return new Date(isoString).toLocaleString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZoneName: 'short',
});
}
const isOwner = session.role === 'owner';
return (
<div className="space-y-6 max-w-3xl">
{/* Header Row */}
<div className="pb-4 border-b border-outline-variant/30">
<span className="text-[11px] font-mono uppercase tracking-widest text-primary-fixed-dim">
SESSION CREDENTIALS
</span>
<h1 className="font-headline-xl text-2xl sm:text-3xl font-bold text-on-surface tracking-tight mt-1">
My Session
</h1>
<p className="text-xs text-on-surface-variant mt-1">
Cryptographic authority and active authentication status for this browser session.
</p>
</div>
{/* Session Details Card */}
<div className="p-6 rounded-xl bg-surface-container-low border border-outline-variant/30 space-y-6 shadow-sm">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{/* Verified Identity */}
<div className="p-3.5 rounded-lg bg-surface-container-lowest border border-outline-variant/20 space-y-1">
<span className="text-[10px] font-mono uppercase tracking-wider text-outline">
Verified Identity
</span>
<div className="text-sm font-semibold text-on-surface break-all">
{session.identity}
</div>
<span className="text-[10px] text-on-surface-variant font-mono">
ops.operators identity
</span>
</div>
{/* Operations Role */}
<div className="p-3.5 rounded-lg bg-surface-container-lowest border border-outline-variant/20 space-y-1">
<span className="text-[10px] font-mono uppercase tracking-wider text-outline">
Operations Role
</span>
<div>
<span
className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-mono font-bold uppercase tracking-wider ${
isOwner
? 'bg-primary-container/15 text-primary-container border border-primary-container/40'
: 'bg-surface-container-high text-on-surface font-semibold border border-outline-variant/40'
}`}
>
{session.role}
</span>
</div>
<span className="text-[10px] text-on-surface-variant font-mono">
{isOwner ? 'Full platform authority' : 'Standard operator telemetry read'}
</span>
</div>
{/* Session Status */}
<div className="p-3.5 rounded-lg bg-surface-container-lowest border border-outline-variant/20 space-y-1">
<span className="text-[10px] font-mono uppercase tracking-wider text-outline">
Session Status
</span>
<div className="flex items-center gap-1.5 text-xs font-mono font-semibold text-secondary-fixed">
<span className="h-2 w-2 rounded-full bg-secondary-fixed"></span>
<span className="uppercase">{session.status}</span>
</div>
<span className="text-[10px] text-on-surface-variant font-mono">
Validated on-demand
</span>
</div>
{/* Environment */}
<div className="p-3.5 rounded-lg bg-surface-container-lowest border border-outline-variant/20 space-y-1">
<span className="text-[10px] font-mono uppercase tracking-wider text-outline">
Runtime Environment
</span>
<div className="text-xs font-mono font-semibold text-on-surface uppercase">
{session.environment ?? 'production'}
</div>
<span className="text-[10px] text-on-surface-variant font-mono">
Target API host boundary
</span>
</div>
{/* Created Timestamp */}
<div className="p-3.5 rounded-lg bg-surface-container-lowest border border-outline-variant/20 space-y-1">
<span className="text-[10px] font-mono uppercase tracking-wider text-outline">
Session Created
</span>
<div className="text-xs font-mono text-on-surface">
{formatDate(session.createdAt)}
</div>
</div>
{/* Last Activity */}
<div className="p-3.5 rounded-lg bg-surface-container-lowest border border-outline-variant/20 space-y-1">
<span className="text-[10px] font-mono uppercase tracking-wider text-outline">
Last Activity
</span>
<div className="text-xs font-mono text-on-surface">
{formatDate(session.lastActivityAt)}
</div>
</div>
{/* Absolute Expiry */}
<div className="p-3.5 rounded-lg bg-surface-container-lowest border border-outline-variant/20 space-y-1 sm:col-span-2">
<span className="text-[10px] font-mono uppercase tracking-wider text-outline">
Absolute Expiry
</span>
<div className="text-xs font-mono text-on-surface">
{formatDate(session.expiresAt)}
</div>
</div>
</div>
{/* Action Row */}
<div className="pt-4 border-t border-outline-variant/20 flex items-center justify-between">
<span className="text-[11px] text-outline font-mono">
Cookie: __Host-motorsignal_ops (HttpOnly, Secure, SameSite=Strict)
</span>
<button
type="button"
onClick={onSignOut}
disabled={signingOut}
className="inline-flex items-center gap-1.5 px-4 py-2 rounded-lg bg-surface-container-high hover:bg-surface-bright text-error border border-error/30 text-xs font-bold transition-all focus-visible:ring-2 focus-visible:ring-error focus-visible:outline-none disabled:opacity-50"
>
<span className="material-symbols-outlined text-[16px]">logout</span>
<span>{signingOut ? 'Signing out...' : 'Sign Out'}</span>
</button>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,191 @@
'use client';
import React, { useState } from 'react';
import {
OperationsNavId,
OperatorSession,
OperationsHealth,
SafeAuditEvent,
} from './types';
import { OperationsTopBar } from './operations-top-bar';
import { OperationsSidebar } from './operations-sidebar';
import { OperationsOverview } from './operations-overview';
import { OperationsAudit } from './operations-audit';
import { OperationsOperators } from './operations-operators';
import { OperationsSessionView } from './operations-session';
interface OperationsShellProps {
initialSession: OperatorSession;
initialHealth: OperationsHealth;
initialAudit?: {
events: SafeAuditEvent[];
next_cursor?: string | null;
total?: number;
};
initialNav?: OperationsNavId;
}
export function OperationsShell({
initialSession,
initialHealth,
initialAudit,
initialNav = 'overview',
}: OperationsShellProps) {
const [session, setSession] = useState<OperatorSession>(initialSession);
const [activeNav, setActiveNav] = useState<OperationsNavId>(initialNav);
const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
// Health state
const [health, setHealth] = useState<OperationsHealth>(initialHealth);
const [isRefreshingHealth, setIsRefreshingHealth] = useState(false);
// Audit state
const [auditEvents, setAuditEvents] = useState<SafeAuditEvent[]>(
initialAudit?.events ?? []
);
const [nextCursor, setNextCursor] = useState<string | null>(
initialAudit?.next_cursor ?? null
);
const [auditTotal, setAuditTotal] = useState<number | undefined>(
initialAudit?.total
);
const [isLoadingAudit, setIsLoadingAudit] = useState(false);
const [isLoadingMoreAudit, setIsLoadingMoreAudit] = useState(false);
// Sign out state
const [signingOut, setSigningOut] = useState(false);
// Manual Health Refresh (Zero automatic polling)
async function handleRefreshHealth() {
if (isRefreshingHealth) return;
setIsRefreshingHealth(true);
try {
const response = await fetch('/api/ops/health', {
method: 'GET',
headers: { accept: 'application/json' },
cache: 'no-store',
});
if (response.ok) {
const data = (await response.json()) as OperationsHealth;
setHealth(data);
} else {
setHealth((prev: OperationsHealth) => ({
...prev,
status: 'unavailable',
checked_at: new Date().toISOString(),
}));
}
} catch {
setHealth((prev: OperationsHealth) => ({
...prev,
status: 'unavailable',
checked_at: new Date().toISOString(),
}));
} finally {
setIsRefreshingHealth(false);
}
}
// Next Page of Audit Events (Owner only, server cursor)
async function handleLoadNextAuditPage() {
if (!nextCursor || isLoadingMoreAudit) return;
setIsLoadingMoreAudit(true);
try {
const response = await fetch(
`/api/ops/audit-events?cursor=${encodeURIComponent(nextCursor)}`,
{
method: 'GET',
headers: { accept: 'application/json' },
cache: 'no-store',
}
);
if (response.ok) {
const data = await response.json();
setAuditEvents((prev) => [...prev, ...(data.events ?? [])]);
setNextCursor(data.next_cursor ?? null);
if (typeof data.total === 'number') {
setAuditTotal(data.total);
}
}
} catch {
// Retain current events on failure
} finally {
setIsLoadingMoreAudit(false);
}
}
// Sign Out Handler
async function handleSignOut() {
if (signingOut) return;
setSigningOut(true);
try {
await fetch('/api/ops/auth/logout', {
method: 'POST',
headers: {
origin: window.location.origin,
},
});
} catch {
// Continue client cleanup regardless of network error
} finally {
window.location.href = '/login';
}
}
return (
<div className="min-h-screen bg-surface font-body text-sm text-on-surface antialiased selection:bg-primary-container selection:text-on-primary-container">
{/* Sidebar (Desktop persistent + Mobile off-canvas drawer) */}
<OperationsSidebar
activeNav={activeNav}
onSelectNav={(nav) => setActiveNav(nav)}
isOpenOnMobile={mobileSidebarOpen}
onCloseMobile={() => setMobileSidebarOpen(false)}
role={session.role}
/>
{/* Main Workspace Area */}
<div className="lg:pl-64 flex flex-col min-h-screen">
{/* Top App Bar */}
<OperationsTopBar
session={session}
onSignOut={handleSignOut}
onToggleMobileSidebar={() => setMobileSidebarOpen(!mobileSidebarOpen)}
signingOut={signingOut}
/>
{/* Content Body Container */}
<main className="relative pt-20 px-4 sm:px-6 py-6 w-full max-w-[1440px] mx-auto flex-1">
{activeNav === 'overview' && (
<OperationsOverview
health={health}
onRefresh={handleRefreshHealth}
isRefreshing={isRefreshingHealth}
/>
)}
{activeNav === 'audit' && (
<OperationsAudit
role={session.role}
events={auditEvents}
nextCursor={nextCursor}
onNextPage={handleLoadNextAuditPage}
isLoading={isLoadingAudit}
isLoadingMore={isLoadingMoreAudit}
total={auditTotal}
/>
)}
{activeNav === 'operators' && <OperationsOperators />}
{activeNav === 'session' && (
<OperationsSessionView
session={session}
onSignOut={handleSignOut}
signingOut={signingOut}
/>
)}
</main>
</div>
</div>
);
}

View File

@ -0,0 +1,163 @@
'use client';
import React from 'react';
import { OperationsNavId, OperationsRole } from './types';
interface OperationsSidebarProps {
activeNav: OperationsNavId;
onSelectNav: (nav: OperationsNavId) => void;
isOpenOnMobile: boolean;
onCloseMobile: () => void;
role: OperationsRole;
}
export function OperationsSidebar({
activeNav,
onSelectNav,
isOpenOnMobile,
onCloseMobile,
role,
}: OperationsSidebarProps) {
const isOwner = role === 'owner';
const navItems: Array<{
id: OperationsNavId;
label: string;
icon: string;
badge?: string;
badgeType?: 'primary' | 'neutral' | 'disabled';
}> = [
{
id: 'overview',
label: 'Overview',
icon: 'dashboard',
},
{
id: 'audit',
label: 'Audit',
icon: 'verified_user',
badge: isOwner ? 'OWNER' : 'RESTRICTED',
badgeType: isOwner ? 'primary' : 'neutral',
},
{
id: 'operators',
label: 'Operators',
icon: 'group',
badge: 'DISABLED',
badgeType: 'disabled',
},
{
id: 'session',
label: 'My Session',
icon: 'badge',
},
];
const sidebarContent = (
<div className="flex flex-col h-full bg-surface-container-lowest border-r border-outline-variant/30 text-on-surface">
{/* Brand Masthead */}
<div className="h-16 px-6 flex items-center gap-3 border-b border-outline-variant/30 shrink-0">
<div className="w-8 h-8 rounded-lg bg-surface-container-high border border-primary-container/40 flex items-center justify-center text-primary-container shadow-[0_0_12px_rgba(0,242,254,0.2)]">
<span className="material-symbols-outlined text-[18px]">terminal</span>
</div>
<div className="flex flex-col">
<span className="font-headline-sm text-sm font-bold tracking-tight text-on-surface uppercase">
Operations
</span>
<span className="text-[10px] font-mono text-primary-fixed-dim uppercase tracking-wider">
Platform Console
</span>
</div>
</div>
{/* Navigation Links */}
<nav className="flex-1 px-3 py-4 space-y-1 overflow-y-auto" aria-label="Operations Navigation">
{navItems.map((item) => {
const isActive = activeNav === item.id;
return (
<button
key={item.id}
type="button"
onClick={() => {
onSelectNav(item.id);
onCloseMobile();
}}
aria-current={isActive ? 'page' : undefined}
className={`w-full flex items-center justify-between px-3 py-2.5 rounded-lg text-xs font-medium transition-all group focus-visible:ring-2 focus-visible:ring-primary-container focus-visible:outline-none ${
isActive
? 'bg-surface-container-high text-primary-container font-semibold border-l-2 border-primary-container'
: 'text-on-surface-variant hover:text-on-surface hover:bg-surface-container-low'
}`}
>
<div className="flex items-center gap-2.5">
<span
className={`material-symbols-outlined text-[18px] transition-colors ${
isActive
? 'text-primary-container'
: 'text-outline group-hover:text-on-surface'
}`}
>
{item.icon}
</span>
<span>{item.label}</span>
</div>
{item.badge && (
<span
className={`px-1.5 py-0.5 rounded text-[9px] font-mono uppercase tracking-wider ${
item.badgeType === 'primary'
? 'bg-primary-container/15 text-primary-container border border-primary-container/30'
: item.badgeType === 'disabled'
? 'bg-surface-container-highest/60 text-outline border border-outline-variant/20'
: 'bg-surface-container text-on-surface-variant border border-outline-variant/30'
}`}
>
{item.badge}
</span>
)}
</button>
);
})}
</nav>
{/* Footer Authority Boundary Notice */}
<div className="p-4 border-t border-outline-variant/20 bg-surface-container-lowest/50 text-[10px] text-outline space-y-1">
<div className="flex items-center gap-1 font-mono uppercase text-on-surface-variant">
<span className="material-symbols-outlined text-[12px] text-primary-fixed-dim">
shield_lock
</span>
<span>Isolated Session</span>
</div>
<p className="leading-tight">
Authority strictly bounded to <code className="text-on-surface font-mono">ops.operators</code>.
</p>
</div>
</div>
);
return (
<>
{/* Desktop Persistent Sidebar */}
<aside className="hidden lg:block fixed top-0 bottom-0 left-0 w-64 z-40">
{sidebarContent}
</aside>
{/* Mobile Backdrop & Drawer */}
{isOpenOnMobile && (
<div className="lg:hidden fixed inset-0 z-50 flex">
{/* Backdrop */}
<div
className="fixed inset-0 bg-black/60 backdrop-blur-sm transition-opacity"
onClick={onCloseMobile}
aria-hidden="true"
/>
{/* Drawer Panel */}
<div className="relative w-64 max-w-[80vw] h-full shadow-2xl z-10 animate-in slide-in-from-left duration-200">
{sidebarContent}
</div>
</div>
)}
</>
);
}

View File

@ -0,0 +1,96 @@
'use client';
import React from 'react';
import { OperatorSession } from './types';
interface OperationsTopBarProps {
session: OperatorSession;
onSignOut: () => void;
onToggleMobileSidebar: () => void;
signingOut?: boolean;
}
export function OperationsTopBar({
session,
onSignOut,
onToggleMobileSidebar,
signingOut = false,
}: OperationsTopBarProps) {
const isOwner = session.role === 'owner';
const environment = (session.environment ?? 'production').toUpperCase();
return (
<header className="fixed top-0 right-0 left-0 lg:left-64 z-30 h-16 bg-surface-container-lowest/90 backdrop-blur-md border-b border-outline-variant/30 flex items-center justify-between px-4 sm:px-6">
{/* Left: Mobile Drawer Button + Operations Branding Title */}
<div className="flex items-center gap-3 min-w-0">
<button
type="button"
onClick={onToggleMobileSidebar}
aria-label="Toggle navigation menu"
className="lg:hidden p-2 rounded-lg bg-surface-container-low hover:bg-surface-container-high text-on-surface border border-outline-variant/30 focus-visible:ring-2 focus-visible:ring-primary-container focus-visible:outline-none"
>
<span className="material-symbols-outlined text-[20px]">menu</span>
</button>
<div className="flex items-center gap-2 min-w-0">
<div className="flex items-center gap-1.5 shrink-0">
<span className="font-headline-sm text-sm sm:text-base font-bold text-on-surface tracking-wider uppercase">
MotorSignal
</span>
<span className="px-1.5 py-0.5 rounded text-[10px] font-bold tracking-widest uppercase bg-surface-container-high text-primary-container border border-primary-container/30">
OPS
</span>
</div>
<span className="hidden sm:inline-flex items-center px-2 py-0.5 rounded text-[10px] font-mono uppercase bg-surface-container-low text-on-surface-variant border border-outline-variant/30">
ENV: {environment}
</span>
</div>
</div>
{/* Right: Operator Identity + Role Pill + Status + Sign Out */}
<div className="flex items-center gap-2 sm:gap-3 shrink-0">
{/* Safe Identity */}
<div className="hidden md:flex flex-col items-end text-right">
<span className="text-xs font-semibold text-on-surface tracking-tight truncate max-w-[200px]">
{session.identity}
</span>
<span className="text-[10px] text-on-surface-variant font-mono">
Current Operations Identity
</span>
</div>
{/* Role Pill */}
<span
className={`px-2 py-0.5 rounded text-[11px] font-bold uppercase tracking-wider ${
isOwner
? 'bg-primary-container/15 text-primary-container border border-primary-container/40'
: 'bg-surface-container-high text-on-surface-variant border border-outline-variant/40'
}`}
>
{session.role}
</span>
{/* Session Status Dot/Pill */}
<div className="hidden sm:inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full bg-surface-container-low border border-outline-variant/30">
<span className="h-1.5 w-1.5 rounded-full bg-secondary-fixed"></span>
<span className="text-[10px] font-mono text-on-surface-variant uppercase">
Active
</span>
</div>
{/* Sign Out Action */}
<button
type="button"
onClick={onSignOut}
disabled={signingOut}
aria-label="Sign out of Operations"
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-surface-container-low hover:bg-surface-container-high text-on-surface hover:text-error border border-outline-variant/30 text-xs font-semibold transition-colors focus-visible:ring-2 focus-visible:ring-primary-container focus-visible:outline-none disabled:opacity-50"
>
<span className="material-symbols-outlined text-[16px]">logout</span>
<span className="hidden xs:inline">Sign Out</span>
</button>
</div>
</header>
);
}

View File

@ -0,0 +1,53 @@
export type OperationsRole = 'owner' | 'operator';
export type ComponentHealthStatus = 'available' | 'degraded' | 'unavailable' | 'unknown';
export type HealthComponentKey =
| 'operations_api'
| 'operations_database'
| 'session_validation'
| 'audit_persistence';
export interface HealthComponentItem {
key: HealthComponentKey;
name: string;
status: ComponentHealthStatus;
description: string;
}
export interface OperationsHealth {
status: ComponentHealthStatus;
checked_at: string;
components: Record<HealthComponentKey, { status: ComponentHealthStatus; description?: string }>;
}
export interface SafeAuditEvent {
id?: string;
timestamp: string;
action: string;
result: 'success' | 'failure' | 'denied' | 'recorded' | string;
actor_identity: string;
actor_role?: string;
target_resource?: string;
reason_code?: string;
case_reference?: string;
metadata?: Record<string, string | number | boolean>;
}
export interface AuditEventsResponse {
events: SafeAuditEvent[];
next_cursor?: string | null;
total?: number;
}
export interface OperatorSession {
identity: string;
role: OperationsRole;
status: 'active' | 'expired' | 'revoked' | 'disabled';
createdAt?: string;
lastActivityAt?: string;
expiresAt?: string;
environment?: string;
}
export type OperationsNavId = 'overview' | 'audit' | 'operators' | 'session';

214
website/lib/ops-data.ts Normal file
View File

@ -0,0 +1,214 @@
import {
OperationsHealth,
SafeAuditEvent,
ComponentHealthStatus,
HealthComponentKey,
} from '../components/ops/types';
export const HEALTH_COMPONENT_METADATA: Record<
HealthComponentKey,
{ name: string; description: string }
> = {
operations_api: {
name: 'Operations API',
description: 'FastAPI core endpoint runtime & ingress',
},
operations_database: {
name: 'Operations Database',
description: 'PostgreSQL ops schema relational persistence',
},
session_validation: {
name: 'Session Validation',
description: '__Host-motorsignal_ops token verification & authority',
},
audit_persistence: {
name: 'Audit Persistence',
description: 'Immutable operational security activity persistence',
},
};
export const APPROVED_AUDIT_METADATA_KEYS = new Set([
'component',
'status_code',
'subsystem',
'duration_ms',
'policy',
'action_scope',
'session_valid',
'mfa_verified',
'migration_version',
'records_affected',
]);
export function isValidHealthStatus(status: unknown): status is ComponentHealthStatus {
return (
status === 'available' ||
status === 'degraded' ||
status === 'unavailable' ||
status === 'unknown'
);
}
export function normalizeHealthResponse(raw: unknown): OperationsHealth {
const fallbackCheckedAt = new Date().toISOString();
if (!raw || typeof raw !== 'object') {
return {
status: 'unavailable',
checked_at: fallbackCheckedAt,
components: {
operations_api: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.operations_api.description },
operations_database: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.operations_database.description },
session_validation: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.session_validation.description },
audit_persistence: { status: 'unavailable', description: HEALTH_COMPONENT_METADATA.audit_persistence.description },
},
};
}
const obj = raw as Record<string, unknown>;
const rawStatus = obj.status;
const overallStatus: ComponentHealthStatus = isValidHealthStatus(rawStatus)
? rawStatus
: 'unknown';
const checkedAt =
typeof obj.checked_at === 'string' && obj.checked_at.length > 0
? obj.checked_at
: fallbackCheckedAt;
const rawComponents =
obj.components && typeof obj.components === 'object'
? (obj.components as Record<string, unknown>)
: {};
const keys: HealthComponentKey[] = [
'operations_api',
'operations_database',
'session_validation',
'audit_persistence',
];
const components: Record<
HealthComponentKey,
{ status: ComponentHealthStatus; description: string }
> = {
operations_api: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.operations_api.description },
operations_database: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.operations_database.description },
session_validation: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.session_validation.description },
audit_persistence: { status: 'unknown', description: HEALTH_COMPONENT_METADATA.audit_persistence.description },
};
for (const key of keys) {
const rawComp = rawComponents[key] as Record<string, unknown> | undefined;
const compStatus = rawComp && isValidHealthStatus(rawComp.status)
? rawComp.status
: isValidHealthStatus(obj[key])
? (obj[key] as ComponentHealthStatus)
: overallStatus;
components[key] = {
status: compStatus,
description: (rawComp?.description as string) || HEALTH_COMPONENT_METADATA[key].description,
};
}
return {
status: overallStatus,
checked_at: checkedAt,
components,
};
}
export function sanitizeAuditEvent(raw: unknown): SafeAuditEvent | null {
if (!raw || typeof raw !== 'object') {
return null; // Fail closed
}
const obj = raw as Record<string, unknown>;
// Required: timestamp (ISO string)
if (typeof obj.timestamp !== 'string' || !obj.timestamp.trim()) {
return null;
}
const timestamp = obj.timestamp.trim();
// Required: action
if (typeof obj.action !== 'string' || !obj.action.trim()) {
return null;
}
const action = obj.action.trim();
// Required: result
if (typeof obj.result !== 'string' || !obj.result.trim()) {
return null;
}
const result = obj.result.trim();
// Required: actor_identity (exact OPS-3B contract, no actor_email alias)
if (typeof obj.actor_identity !== 'string' || !obj.actor_identity.trim()) {
return null; // Fail closed: missing verified identity
}
const actor_identity = obj.actor_identity.trim();
// Optional transport ID (unrendered in UI)
const id =
typeof obj.id === 'string' && obj.id.trim()
? obj.id.trim()
: undefined;
// Optional: actor_role
const actor_role =
typeof obj.actor_role === 'string' && obj.actor_role.trim()
? obj.actor_role.trim()
: undefined;
// Optional: target_resource (exact OPS-3B contract, no target alias)
const target_resource =
typeof obj.target_resource === 'string' && obj.target_resource.trim()
? obj.target_resource.trim()
: undefined;
// Optional: reason_code
const reason_code =
typeof obj.reason_code === 'string' && obj.reason_code.trim()
? obj.reason_code.trim()
: undefined;
// Optional: case_reference
const case_reference =
typeof obj.case_reference === 'string' && obj.case_reference.trim()
? obj.case_reference.trim()
: undefined;
// Explicit Allowlist Metadata Projection only
let metadata: Record<string, string | number | boolean> | undefined = undefined;
if (obj.metadata && typeof obj.metadata === 'object' && !Array.isArray(obj.metadata)) {
const rawMeta = obj.metadata as Record<string, unknown>;
const safeMeta: Record<string, string | number | boolean> = {};
for (const [k, v] of Object.entries(rawMeta)) {
if (!APPROVED_AUDIT_METADATA_KEYS.has(k)) {
continue; // Drop unapproved metadata key
}
if (typeof v === 'string' && v.length <= 100) {
safeMeta[k] = v;
} else if (typeof v === 'number' || typeof v === 'boolean') {
safeMeta[k] = v;
}
}
if (Object.keys(safeMeta).length > 0) {
metadata = safeMeta;
}
}
return {
id,
timestamp,
action,
result,
actor_identity,
actor_role,
target_resource,
reason_code,
case_reference,
metadata,
};
}

View File

@ -0,0 +1,446 @@
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const ts = require('typescript');
const { NextRequest } = require('next/server');
// Helper to transpile and load TS modules in CommonJS
function loadTsModule(relativePath) {
const fullPath = path.resolve(__dirname, relativePath);
const source = fs.readFileSync(fullPath, 'utf8');
const transpiled = ts.transpileModule(source, {
compilerOptions: {
module: ts.ModuleKind.CommonJS,
target: ts.ScriptTarget.ES2022,
jsx: ts.JsxEmit.React,
},
}).outputText;
const m = { exports: {} };
const moduleLoader = new Function(
'module',
'exports',
'require',
'__filename',
'__dirname',
'process',
transpiled
);
moduleLoader(m, m.exports, (reqPath) => {
if (reqPath.startsWith('.')) {
const resolved = path.resolve(path.dirname(fullPath), reqPath);
if (fs.existsSync(resolved + '.ts')) return loadTsModule(path.relative(__dirname, resolved + '.ts'));
if (fs.existsSync(resolved + '.tsx')) return loadTsModule(path.relative(__dirname, resolved + '.tsx'));
if (fs.existsSync(resolved + '/index.ts')) return loadTsModule(path.relative(__dirname, resolved + '/index.ts'));
}
return require(reqPath);
}, fullPath, path.dirname(fullPath), process);
return m.exports;
}
console.log('--- STARTING OPS-3C, OPS-3C.1 & OPS-3C.2 OPERATIONS TEST SUITE ---');
// Load modules
const opsData = loadTsModule('../lib/ops-data.ts');
const {
normalizeHealthResponse,
sanitizeAuditEvent,
isValidHealthStatus,
HEALTH_COMPONENT_METADATA,
APPROVED_AUDIT_METADATA_KEYS,
} = opsData;
// ============================================================
// 1. ISOLATED OPERATIONS SHELL & CONSUMER NAV SUPPRESSION
// ============================================================
console.log('Testing 1: Isolated Operations Shell & Consumer Nav Isolation...');
const siteHeaderSource = fs.readFileSync(path.resolve(__dirname, '../components/site-header-client.tsx'), 'utf8');
const siteFooterSource = fs.readFileSync(path.resolve(__dirname, '../components/site-footer.tsx'), 'utf8');
assert.ok(
siteHeaderSource.includes("pathname?.startsWith('/admin')") || siteHeaderSource.includes("pathname?.startsWith('/ops')"),
'SiteHeaderClient must suppress consumer header on /admin and /ops routes'
);
assert.ok(
siteFooterSource.includes("pathname?.startsWith('/admin')") || siteFooterSource.includes("pathname?.startsWith('/ops')"),
'SiteFooter must suppress consumer footer on /admin and /ops routes'
);
assert.ok(
!siteHeaderSource.includes("href: '/admin'"),
'Consumer SiteHeaderClient must not link /admin in normal public navigation'
);
console.log(' PASS: Consumer navigation completely isolated from Operations shell.');
// ============================================================
// 2. /ADMIN SAFE HANDOFF & ZERO PREVIEW QUERY AUTHENTICATION
// ============================================================
console.log('Testing 2: /admin Safe Handoff & Zero Preview Query Bypass...');
const adminPageSource = fs.readFileSync(path.resolve(__dirname, '../app/admin/page.tsx'), 'utf8');
assert.ok(
!adminPageSource.includes("preview === 'ops'") && !adminPageSource.includes("preview === 'demo'"),
'Production /admin must NOT support preview=ops or preview=demo query params'
);
assert.ok(
!adminPageSource.includes('resolvedParams.role') &&
!adminPageSource.includes('searchParams?.role') &&
!adminPageSource.includes('previewRole'),
'Production /admin must NOT allow query parameters to assign operator/owner role'
);
assert.ok(
!adminPageSource.includes('createDefaultOperationsHealth') && !adminPageSource.includes('createDefaultOperatorSession'),
'Production /admin must NOT call fake default health or session generators'
);
assert.ok(
adminPageSource.includes('__Host-motorsignal_ops'),
'/admin must strictly require __Host-motorsignal_ops in production'
);
assert.ok(
adminPageSource.includes('OperationsErrorState') && adminPageSource.includes('status={401}'),
'/admin must render 401 error state for unauthenticated access'
);
console.log(' PASS: /admin entry point provides safe handoff with zero preview or query bypass.');
// ============================================================
// 3. REAL HEALTH ENDPOINT & NORMALIZATION
// ============================================================
console.log('Testing 3: Real Health Endpoint Normalization...');
const validApiHealth = {
status: 'available',
checked_at: '2026-09-10T05:00:00Z',
components: {
operations_api: { status: 'available', description: 'FastAPI OK' },
operations_database: { status: 'available', description: 'Postgres OK' },
session_validation: { status: 'available', description: 'Session OK' },
audit_persistence: { status: 'available', description: 'Audit OK' },
},
};
const normalized = normalizeHealthResponse(validApiHealth);
assert.equal(normalized.status, 'available');
assert.equal(normalized.checked_at, '2026-09-10T05:00:00Z');
assert.equal(normalized.components.operations_api.status, 'available');
assert.equal(normalized.components.operations_database.status, 'available');
assert.equal(normalized.components.session_validation.status, 'available');
assert.equal(normalized.components.audit_persistence.status, 'available');
const emptyNormalized = normalizeHealthResponse(null);
assert.equal(emptyNormalized.status, 'unavailable');
assert.equal(emptyNormalized.components.operations_api.status, 'unavailable');
assert.equal(emptyNormalized.components.operations_database.status, 'unavailable');
assert.equal(emptyNormalized.components.session_validation.status, 'unavailable');
assert.equal(emptyNormalized.components.audit_persistence.status, 'unavailable');
console.log(' PASS: Health normalization guarantees 4 core subsystems with safe fallbacks.');
// ============================================================
// 4. AVAILABLE / DEGRADED / UNAVAILABLE / UNKNOWN STATES
// ============================================================
console.log('Testing 4: Component Health Status Transitions...');
assert.equal(isValidHealthStatus('available'), true);
assert.equal(isValidHealthStatus('degraded'), true);
assert.equal(isValidHealthStatus('unavailable'), true);
assert.equal(isValidHealthStatus('unknown'), true);
assert.equal(isValidHealthStatus('healthy'), false);
assert.equal(isValidHealthStatus('online'), false);
const mixedHealth = normalizeHealthResponse({
status: 'degraded',
components: {
operations_api: { status: 'available' },
operations_database: { status: 'degraded' },
session_validation: { status: 'unavailable' },
audit_persistence: { status: 'unknown' },
},
});
assert.equal(mixedHealth.components.operations_api.status, 'available');
assert.equal(mixedHealth.components.operations_database.status, 'degraded');
assert.equal(mixedHealth.components.session_validation.status, 'unavailable');
assert.equal(mixedHealth.components.audit_persistence.status, 'unknown');
console.log(' PASS: Subsystem health preserves exact 4 approved enum values.');
// ============================================================
// 5. MANUAL HEALTH REFRESH & NO AUTOMATIC POLLING
// ============================================================
console.log('Testing 5: Manual Refresh & Zero Automatic Polling...');
const overviewSource = fs.readFileSync(path.resolve(__dirname, '../components/ops/operations-overview.tsx'), 'utf8');
const shellSource = fs.readFileSync(path.resolve(__dirname, '../components/ops/operations-shell.tsx'), 'utf8');
assert.ok(
!overviewSource.includes('setInterval') && !overviewSource.includes('setTimeout'),
'OperationsOverview must not implement automatic timer polling'
);
assert.ok(
!shellSource.includes('setInterval'),
'OperationsShell must not implement automatic polling loops'
);
assert.ok(
overviewSource.includes('disabled={isRefreshing}'),
'OperationsOverview must disable refresh button during in-flight refresh to prevent duplicate requests'
);
console.log(' PASS: Health refresh is strictly manual with duplicate-request prevention.');
// ============================================================
// 6. ZERO FABRICATED HEALTH METRICS
// ============================================================
console.log('Testing 6: Zero Fabricated Metrics Audit...');
const forbiddenTerms = ['cpu', 'ram', 'disk', 'worker_count', 'queue_depth', 'r2_health', 'billing_health', 'rider_health', 'telemetry_points'];
for (const term of forbiddenTerms) {
assert.ok(
!overviewSource.toLowerCase().includes(term + ':') && !overviewSource.toLowerCase().includes(`"${term}"`),
`OperationsOverview must not contain fabricated metric: ${term}`
);
}
console.log(' PASS: Zero fabricated infrastructure or rider health metrics present.');
// ============================================================
// 7. OWNER AUDIT ACCESS VS 8. OPERATOR AUDIT DENIAL
// ============================================================
console.log('Testing 7 & 8: Owner Audit Access & Operator Denied UX...');
const auditSource = fs.readFileSync(path.resolve(__dirname, '../components/ops/operations-audit.tsx'), 'utf8');
assert.ok(
auditSource.includes("const isOwner = role === 'owner'") || auditSource.includes("if (!isOwner)"),
'OperationsAudit must enforce role === "owner" gate'
);
assert.ok(
auditSource.includes('You do not have authority to view Audit.') || auditSource.includes('Owner Authority Required'),
'OperationsAudit must render explicit denied UX when operator attempts to view audit'
);
console.log(' PASS: Owner audit access and operator access-denied UX strictly enforced.');
// ============================================================
// 9. AUDIT PAGINATION & BOUNDED RESULT SET
// ============================================================
console.log('Testing 9: Server Cursor Bounded Pagination...');
assert.ok(
auditSource.includes('nextCursor') && auditSource.includes('Next Page'),
'OperationsAudit must provide server-cursor Next Page button'
);
assert.ok(
!auditSource.includes('Export') && !auditSource.includes('bulk download') && !auditSource.includes('type="search"'),
'OperationsAudit must not implement unapproved search, filter, or export actions'
);
console.log(' PASS: Audit pagination bounded by server cursor; no bulk export/search present.');
// ============================================================
// 10. STRICT OPS-3B AUDIT DTO & METADATA ALLOWLIST (OPS-3C.3)
// ============================================================
console.log('Testing 10: Strict OPS-3B Audit DTO & Metadata Allowlist (OPS-3C.3)...');
// Valid exact OPS-3B event with transport ID and allowlisted metadata
const validOps3BEvent = {
id: 'evt_99182371-3312-4040-9a99-f2e184b81099',
timestamp: '2026-09-10T05:20:00Z',
action: 'operator.login',
result: 'success',
actor_identity: 'ops-admin@motorsignal.app',
actor_role: 'owner',
target_resource: 'ops.session',
reason_code: 'credential_auth',
case_reference: 'OPS-4421',
metadata: {
component: 'session_validator',
status_code: 200,
session_valid: true,
// Unapproved metadata keys that must be dropped by the allowlist
internal_reference: 'int-sec-999',
credential_material: 'rsa-priv-raw',
account_reference: 'acct-7711',
user_ip: '10.0.0.1',
},
};
const sanitized = sanitizeAuditEvent(validOps3BEvent);
assert.notEqual(sanitized, null);
assert.equal(sanitized.id, 'evt_99182371-3312-4040-9a99-f2e184b81099');
assert.equal(sanitized.timestamp, '2026-09-10T05:20:00Z');
assert.equal(sanitized.action, 'operator.login');
assert.equal(sanitized.result, 'success');
assert.equal(sanitized.actor_identity, 'ops-admin@motorsignal.app');
assert.equal(sanitized.actor_role, 'owner');
assert.equal(sanitized.target_resource, 'ops.session');
assert.equal(sanitized.reason_code, 'credential_auth');
assert.equal(sanitized.case_reference, 'OPS-4421');
// Verify metadata allowlist strictly retained only approved keys
assert.deepEqual(sanitized.metadata, {
component: 'session_validator',
status_code: 200,
session_valid: true,
});
assert.equal(sanitized.metadata.internal_reference, undefined);
assert.equal(sanitized.metadata.credential_material, undefined);
assert.equal(sanitized.metadata.account_reference, undefined);
assert.equal(sanitized.metadata.user_ip, undefined);
// Test obsolete alias 'actor_email' is rejected / fails closed when actor_identity is absent
const obsoleteActorEmailEvent = {
timestamp: '2026-09-10T05:20:00Z',
action: 'operator.login',
result: 'success',
actor_email: 'ops-admin@motorsignal.app', // obsolete alias
};
assert.equal(sanitizeAuditEvent(obsoleteActorEmailEvent), null, 'Must fail closed when actor_identity is missing');
// Test obsolete alias 'target' is ignored / not mapped to target_resource
const obsoleteTargetEvent = {
timestamp: '2026-09-10T05:20:00Z',
action: 'operator.login',
result: 'success',
actor_identity: 'ops-admin@motorsignal.app',
target: 'ops.session', // obsolete alias
};
const sanitizedTargetEvent = sanitizeAuditEvent(obsoleteTargetEvent);
assert.notEqual(sanitizedTargetEvent, null);
assert.equal(sanitizedTargetEvent.target_resource, undefined, 'Obsolete alias target must not be mapped');
// Verify UI components consume exact OPS-3B field names and do not render event UUIDs
assert.ok(auditSource.includes('event.actor_identity'), 'OperationsAudit must render event.actor_identity');
assert.ok(auditSource.includes('event.target_resource'), 'OperationsAudit must render event.target_resource');
assert.ok(auditSource.includes('event.reason_code'), 'OperationsAudit must render event.reason_code');
assert.ok(auditSource.includes('event.case_reference'), 'OperationsAudit must render event.case_reference');
assert.ok(!auditSource.includes('event.id') && !auditSource.includes('{event.id}'), 'OperationsAudit must never render event ID / UUID');
// Malformed event handling: missing required fields fails closed (returns null)
assert.equal(sanitizeAuditEvent(null), null);
assert.equal(sanitizeAuditEvent({}), null);
assert.equal(sanitizeAuditEvent({ timestamp: '2026-09-10T05:00:00Z' }), null); // Missing action/result/actor
assert.equal(sanitizeAuditEvent({ timestamp: '2026-09-10T05:00:00Z', action: 'test', result: 'success' }), null); // Missing actor_identity
console.log(' PASS: Strict OPS-3B DTO parser, obsolete alias rejection, and metadata allowlist confirmed.');
// ============================================================
// 11 & 12. NO RAW JSON & NO UUID / SECRET LEAKAGE
// ============================================================
console.log('Testing 11 & 12: Zero Raw JSON & Zero UUID/Secret Leakage...');
assert.ok(
!auditSource.includes('JSON.stringify(event.metadata'),
'Audit table must not dump raw JSON blobs'
);
console.log(' PASS: Zero raw JSON blobs or sensitive UUIDs/IPs/tokens leaked.');
// ============================================================
// 13 & 14. NO RETIRED ADMIN APIS & NO RIDER PRIVATE DATA
// ============================================================
console.log('Testing 13 & 14: Zero Retired APIs & Zero Rider Data...');
const opsDir = path.resolve(__dirname, '../components/ops');
const allOpsFiles = fs.readdirSync(opsDir);
for (const file of allOpsFiles) {
const content = fs.readFileSync(path.join(opsDir, file), 'utf8');
assert.ok(!content.includes('/api/admin'), `${file} must not reference /api/admin`);
assert.ok(!content.includes('/api/v1/admin'), `${file} must not reference /api/v1/admin`);
assert.ok(!content.includes('AdminConsole'), `${file} must not reference AdminConsole`);
assert.ok(!content.includes('rider_id'), `${file} must not reference rider_id`);
assert.ok(!content.includes('vin'), `${file} must not reference vin`);
assert.ok(!content.includes('telemetry_points'), `${file} must not reference telemetry_points`);
}
console.log(' PASS: All Operations components free of retired admin APIs and rider data.');
// ============================================================
// 15. OPERATORS CLEAN PLACEHOLDER
// ============================================================
console.log('Testing 15: Operators Clean Placeholder...');
const operatorsSource = fs.readFileSync(path.resolve(__dirname, '../components/ops/operations-operators.tsx'), 'utf8');
assert.ok(
operatorsSource.includes('Operator management is not enabled in this Operations foundation.'),
'Operators component must display exact placeholder notice'
);
assert.ok(
!operatorsSource.includes('Add Operator') && !operatorsSource.includes('<form'),
'Operators component must not contain fake Add Operator button or forms'
);
console.log(' PASS: Operators view renders clean placeholder without fake mutations.');
// ============================================================
// 16. MY SESSION VIEW
// ============================================================
console.log('Testing 16: My Session View...');
const sessionSource = fs.readFileSync(path.resolve(__dirname, '../components/ops/operations-session.tsx'), 'utf8');
assert.ok(
sessionSource.includes('Verified Identity') &&
sessionSource.includes('Operations Role') &&
sessionSource.includes('Session Status') &&
sessionSource.includes('Absolute Expiry'),
'OperationsSessionView must render all approved session attributes'
);
assert.ok(
sessionSource.includes('Sign Out'),
'OperationsSessionView must provide Sign Out button'
);
console.log(' PASS: Session view displays approved metadata and Sign Out action.');
// ============================================================
// 17. BACKEND SESSION REVOCATION ON LOGOUT (OPS-3C.2)
// ============================================================
console.log('Testing 17: Backend Session Revocation on Logout (OPS-3C.2)...');
const logoutRouteSource = fs.readFileSync(path.resolve(__dirname, '../app/api/ops/auth/logout/route.ts'), 'utf8');
assert.ok(
logoutRouteSource.includes('DELETE') && logoutRouteSource.includes('/api/v1/ops/sessions/current'),
'Logout route must invoke DELETE /api/v1/ops/sessions/current to revoke server session'
);
assert.ok(
logoutRouteSource.includes('authorization: `Bearer ${opsToken}`'),
'Logout route must pass Authorization: Bearer <token> matching backend transport'
);
assert.ok(
logoutRouteSource.includes('__Host-motorsignal_ops') && logoutRouteSource.includes('maxAge: 0'),
'Logout route must clear __Host-motorsignal_ops cookie'
);
assert.ok(
!logoutRouteSource.includes('motorsignal_access_token') && !logoutRouteSource.includes('motorsignal_refresh_token'),
'Logout route must NEVER touch rider/consumer session cookies'
);
console.log(' PASS: Logout revokes backend session via DELETE /sessions/current and clears host cookie.');
// ============================================================
// 18. TWO-STEP BOOTSTRAP: ZERO AUDIT FOR OPERATOR (OPS-3C.2)
// ============================================================
console.log('Testing 18: Two-Step Bootstrap & Operator Zero Audit Request (OPS-3C.2)...');
// Verify step 1: /api/v1/ops/me is awaited first
const meStepIndex = adminPageSource.indexOf('/api/v1/ops/me');
const healthStepIndex = adminPageSource.indexOf('/api/v1/ops/health');
assert.ok(meStepIndex !== -1 && healthStepIndex !== -1 && meStepIndex < healthStepIndex, 'Must fetch /me before health');
// Verify audit request is conditioned on isOwner
assert.ok(
adminPageSource.includes('isOwner') &&
adminPageSource.includes("fetch(`${baseUrl}/api/v1/ops/audit-events`") &&
adminPageSource.includes('Promise.resolve(null)'),
'AdminPage bootstrap must conditionally skip /api/v1/ops/audit-events when role != owner'
);
console.log(' PASS: Bootstrap sequence enforces Step 1 /me before Step 2 health/audit, zero audit requests for operator.');
// ============================================================
// 19. RESPONSIVENESS & 390PX LAYOUT AUDIT
// ============================================================
console.log('Testing 19: Responsive Layout Classes (Desktop, Tablet, 390px)...');
assert.ok(
shellSource.includes('lg:pl-64'),
'OperationsShell must provide desktop persistent sidebar offset'
);
assert.ok(
overviewSource.includes('grid-cols-1') && overviewSource.includes('sm:grid-cols-2') && overviewSource.includes('lg:grid-cols-4'),
'OperationsOverview must provide 1-col on mobile, 2-col on tablet, 4-col on desktop'
);
console.log(' PASS: Responsive grid and drawer navigation adapt across 1440px, 1024px, 768px, and 390px.');
// ============================================================
// 20. SECURITY UX & RUNTIME AUDIT
// ============================================================
console.log('Testing 20: Security UX & Third-Party Runtime Audit...');
for (const file of allOpsFiles) {
const content = fs.readFileSync(path.join(opsDir, file), 'utf8');
assert.ok(!content.includes('localStorage'), `${file} must not use localStorage`);
assert.ok(!content.includes('sessionStorage'), `${file} must not use sessionStorage`);
assert.ok(!content.includes('dangerouslySetInnerHTML'), `${file} must not use dangerouslySetInnerHTML`);
assert.ok(!content.includes('cdn.tailwindcss.com'), `${file} must not reference external CDN`);
assert.ok(!content.includes('google-analytics'), `${file} must not reference analytics`);
}
console.log(' PASS: Zero localStorage/sessionStorage auth, zero dangerouslySetInnerHTML, zero third-party CDNs.');
console.log('--- ALL OPS-3C, OPS-3C.1 & OPS-3C.2 TESTS PASSED (20/20) ---');