P.9: Comparisons Draft-with-Opus drafter
+495 / −87 files
Files changed
- Msrc/app/hall/admin/comparisons/[id]/edit/page.tsx+9 / −0
- Asrc/app/hall/admin/comparisons/draft-with-opus/page.tsx+125 / −0
- Msrc/app/hall/admin/comparisons/new/page.tsx+10 / −0
- Msrc/app/hall/admin/comparisons/page.tsx+15 / −7
- Msrc/app/hall/admin/layout.tsx+1 / −0
- Msrc/shared/comparisons/actions.ts+109 / −1
- Asrc/shared/comparisons/opus-drafter.ts+226 / −0
Diff
Lines reveal in sequence as you scroll. First 20 lines per file shown — expand for the rest.
src/app/hall/admin/comparisons/[id]/edit/page.tsx+9 / −0tsx| @@ -23,6 +23,7 @@ interface Props { | |
| aiNotePublished?: string; | |
| aiNoteDiscarded?: string; | |
| operatorResponseSaved?: string; | |
| + | opusDrafted?: string; |
| }>; | |
| } | |
| @@ -38,6 +39,7 @@ export default async function EditComparisonPage({ params, searchParams }: Props | |
| aiNotePublished, | |
| aiNoteDiscarded, | |
| operatorResponseSaved, | |
| + | opusDrafted, |
| } = await searchParams; | |
| const db = getDb(); | |
| @@ -106,6 +108,13 @@ export default async function EditComparisonPage({ params, searchParams }: Props | |
| Operator response saved. | |
| </p> | |
| )} |
src/app/hall/admin/comparisons/draft-with-opus/page.tsx+125 / −0tsx| @@ -0,0 +1,125 @@ | |
| + | import Link from "next/link"; |
| + | import { getDb } from "@/shared/db/client"; |
| + | import { incumbents } from "@/shared/db/schema/incumbents"; |
| + | import { listFeatures } from "@/shared/features/queries"; |
| + | import { draftComparisonWithOpusAction } from "@/shared/comparisons/actions"; |
| + | |
| + | export const metadata = { title: "Draft a Comparison with Opus" }; |
| + | export const dynamic = "force-dynamic"; |
| + | |
| + | export default async function DraftWithOpusPage() { |
| + | const db = getDb(); |
| + | const [incumbentRows, featureRows] = await Promise.all([ |
| + | db.select().from(incumbents).orderBy(incumbents.displayName), |
| + | listFeatures({ limit: 500 }).catch(() => []), |
| + | ]); |
| + | |
| + | return ( |
| + | <div className="px-6 py-12 md:py-16"> |
| + | <div className="mx-auto max-w-[44rem]"> |
src/app/hall/admin/comparisons/new/page.tsx+10 / −0tsx| @@ -33,6 +33,16 @@ export default async function NewComparisonPage() { | |
| citations are in place — the publish action validates that ≥2 | |
| citations have non-empty quotes. | |
| </p> | |
| + | <p className="mt-3 font-sans text-xs text-stone-500"> |
| + | Faster path:{" "} |
| + | <Link |
| + | href="/hall/admin/comparisons/draft-with-opus" |
| + | className="font-medium text-stone-900 underline decoration-stone-300 underline-offset-4 hover:decoration-stone-900" |
| + | > |
| + | draft the four prose sections with Opus |
| + | </Link> |
| + | {" "}— Claude returns a typed draft in ~10–20 sec, you add citations and edit. |
| + | </p> |
| {incumbentRows.length === 0 ? ( | |
| <div className="mt-8 rounded-xl border border-amber-200 bg-amber-50 px-6 py-5"> |
src/app/hall/admin/comparisons/page.tsx+15 / −7tsx| @@ -37,16 +37,24 @@ export default async function AdminComparisonsIndexPage() { | |
| return ( | |
| <div className="px-6 py-12 md:py-16"> | |
| <div className="mx-auto max-w-[64rem]"> | |
| − | <div className="flex items-baseline justify-between"> |
| + | <div className="flex flex-wrap items-baseline justify-between gap-3"> |
| <h1 className="font-serif text-3xl font-bold tracking-tight text-stone-900 md:text-4xl"> | |
| Comparisons | |
| </h1> | |
| − | <Link |
| − | href="/hall/admin/comparisons/new" |
| − | className="rounded-md bg-stone-900 px-4 py-2 font-sans text-sm font-medium text-[#FDFBF7] hover:bg-stone-700" |
| − | > |
| − | New Comparison → |
| − | </Link> |
| + | <div className="flex items-center gap-2"> |
| + | <Link |
| + | href="/hall/admin/comparisons/draft-with-opus" |
| + | className="rounded-md border border-stone-900 bg-white px-4 py-2 font-sans text-sm font-medium text-stone-900 hover:bg-stone-100" |
| + | > |
src/app/hall/admin/layout.tsx+1 / −0tsx| @@ -32,6 +32,7 @@ export default async function AdminLayout({ | |
| <span className="text-stone-300">·</span> | |
| <Link href="/hall/admin/comparisons" className="text-stone-700 hover:text-stone-900">Comparisons</Link> | |
| <Link href="/hall/admin/comparisons/new" className="text-stone-700 hover:text-stone-900">New comparison</Link> | |
| + | <Link href="/hall/admin/comparisons/draft-with-opus" className="text-stone-700 hover:text-stone-900">Draft w/ Opus</Link> |
| <span className="text-stone-300">·</span> | |
| <Link href="/hall/admin/questions" className="text-stone-700 hover:text-stone-900">Questions</Link> | |
| <Link href="/hall/admin/questions/new" className="text-stone-700 hover:text-stone-900">New question</Link> |