import type { Metadata } from "next"; import Link from "next/link"; import { FieldChanges } from "@/components/field-changes"; import { LiveFeed } from "@/components/live-feed"; import { Badge, Chip, Empty, Flag, PageHeader, Panel, Score } from "@/components/ui"; import { api } from "@/lib/api"; import { agoIso, relTime, typeLabel, utcDateTime } from "@/lib/format"; export const dynamic = "force-dynamic"; export const metadata: Metadata = { title: "Silent changes", description: "Pricing, terms, API limits, documentation and product pages that changed quietly — no announcement matched. Previous state, current state, exact diff." }; /** Dedicated silent-change experience (spec §23). */ export default async function SilentPage() { const [top, recent, count24] = await Promise.all([api.events({ silent_change: true, limit: 12, order: "signal", after: agoIso(48 * 3600e3) }), api.events({ silent_change: true, limit: 60 }), api.eventCount({ silent_change: true, after: agoIso(24 * 3600e3) })]); const byType = new Map(); for (const e of recent.items) byType.set(e.event_type, (byType.get(e.event_type) ?? 0) + 1); return ( <> {count24.count} in the last 24 h · first-party pages only · importance ≥ 45 · no matching announcement within 12 h} title="Silent changes" description="Something was modified without an obvious public announcement: a price quietly changed, documentation rewritten, a feature removed, terms edited, an API limit adjusted, a product page gone. Each item shows the previous state, the current state and the exact diff." actions={
{[...byType.entries()].sort((a, b) => b[1] - a[1]).slice(0, 8).map(([t, n]) => {typeLabel(t)} {n})}
} /> {top.items.length === 0 ? ( No silent change detected in this period. ) : (
    {top.items.map((e) => (
  • {e.source?.name} {e.country && } {typeLabel(e.event_type)} {relTime(e.detected_at)}
    {e.title}
    {e.field_changes?.length ? :

    {e.summary}

    }
    exact diff {e.old_snapshot_id && e.new_snapshot_id && before / after} {e.evidence_label}
  • ))}
)}
); }