From 3ffeea6329b0a33626b68948b4923a4abd0b7fe6 Mon Sep 17 00:00:00 2001 From: Francis Li Date: Fri, 16 Oct 2026 05:23:41 -0700 Subject: [PATCH] feat(scaling): progress from Linear and collapsed detail sections Co-authored-by: Toshi --- app/scaling/components/Progress.tsx | 62 +++++++++++++++++++++ app/scaling/components/Tag.tsx | 1 + app/scaling/components/firstScreen.test.tsx | 20 +++++++ app/scaling/page.test.tsx | 14 +++++ app/scaling/page.tsx | 55 +++++------------- 5 files changed, 110 insertions(+), 42 deletions(-) create mode 100644 app/scaling/components/Progress.tsx create mode 100644 app/scaling/page.test.tsx diff --git a/app/scaling/components/Progress.tsx b/app/scaling/components/Progress.tsx new file mode 100644 index 0000000..15451ae --- /dev/null +++ b/app/scaling/components/Progress.tsx @@ -0,0 +1,62 @@ +import { Card } from '../../components/ui/Card'; +import { EmptyState } from '../../components/ui/EmptyState'; +import { Text } from '../../components/ui/Text'; +import type { WorkItem } from '../snapshot.mjs'; +import { Info } from './Info'; +import { Tag } from './Tag'; + +export function Progress({ work }: { work: WorkItem[] }) { + return ( +
+ Progress + {work.length === 0 ? ( + + ) : ( + + {work.map((w) => )} + + )} + Expected effects are not summed. +
+ ); +} + +function Row({ item: w }: { item: WorkItem }) { + const l = w.linear; + return ( +
+ + {w.title} + +

Hypothesis: {w.hypothesis}

+

Change: {w.change}

+

Owner: {w.owner ?? 'none assigned'}

+
+ + +
+ {l ? ( + + + + + {l.scopeDone}/{l.scopeTotal} + + ) : null} +

Expected: {w.expected ?? 'Not estimated'}

+ {w.evidence && w.realized ?

Realized: {w.realized}

: null} +
+ {[w.evidence, l && { label: 'Linear', url: l.url }, ...w.links].map((link) => link ? ( + {link.label} + ) : null)} +
+
+ ); +} diff --git a/app/scaling/components/Tag.tsx b/app/scaling/components/Tag.tsx index 5fe623d..cb83d08 100644 --- a/app/scaling/components/Tag.tsx +++ b/app/scaling/components/Tag.tsx @@ -2,6 +2,7 @@ const LABEL: Record = { measured: 'Measured', modeled: 'Modeled', estimated: 'Estimated', 'not-measured': 'Not measured', 'not-modeled': 'Not modeled', 'not-established': 'Not established', provisional: 'Provisional', unset: 'Unset', + da: 'DA', execution: 'Execution', state: 'State', networking: 'Networking', }; export function Tag({ tag }: { tag: string }) { diff --git a/app/scaling/components/firstScreen.test.tsx b/app/scaling/components/firstScreen.test.tsx index b7419e8..5f95aa2 100644 --- a/app/scaling/components/firstScreen.test.tsx +++ b/app/scaling/components/firstScreen.test.tsx @@ -6,6 +6,7 @@ import { describe, expect, it } from 'vitest'; import type { Snapshot } from '../snapshot.mjs'; import { CeilingCards } from './CeilingCards'; import { Guardrails } from './Guardrails'; +import { Progress } from './Progress'; // Synthetic data only: real snapshots are internal and never committed. function fixture(): Snapshot { @@ -48,3 +49,22 @@ describe('Guardrails', () => { expect(rows[3]).not.toMatch(/bg-bds-(green|red)/); }); }); + +describe('Progress', () => { + it('shows Linear state and a labelled bar when linked, and proposed with no bar otherwise', () => { + const [linked, proposed] = renderToStaticMarkup().split('px-4 py-3').slice(1); + expect(linked).toContain('>started<'); + expect(linked).toContain('aria-label="4 of 10 issues done"'); + expect(linked).toContain('width:40%'); + expect(linked).toContain('Realized:'); + expect(linked).toContain('href="https://example.com/synthetic/linear/project"'); + expect(proposed).toContain('>proposed<'); + expect(proposed).not.toContain('progressbar'); + expect(proposed).not.toContain('Realized:'); + }); + + it('hides realized without evidence', () => { + const [item] = fixture().work; + expect(renderToStaticMarkup()).not.toContain('Realized:'); + }); +}); diff --git a/app/scaling/page.test.tsx b/app/scaling/page.test.tsx new file mode 100644 index 0000000..75068a7 --- /dev/null +++ b/app/scaling/page.test.tsx @@ -0,0 +1,14 @@ +import { fileURLToPath } from 'node:url'; + +import { renderToStaticMarkup } from 'react-dom/server'; +import { expect, it, vi } from 'vitest'; + +import ScalingPage from './page'; + +it('collapses each detail section by default with its title and row count', async () => { + vi.stubEnv('SCALING_SNAPSHOT_PATH', fileURLToPath(new URL('./fixtures/synthetic.v2.json', import.meta.url))); + const html = renderToStaticMarkup(await ScalingPage()); + expect(html).toMatch(/
]*>]*>Data availability<\/h2>]*> · 2 rows<\/span>/); + expect(html).not.toContain('
+ + {snapshot.sections.map((section) => ( -
-
- {section.title} - {section.summary} -
- +
+ + {section.title} + · {section.metrics.length} {section.metrics.length === 1 ? 'row' : 'rows'} + {section.summary} + + {section.metrics.map((m) => (
@@ -91,27 +95,16 @@ export default async function ScalingPage() { ))} {section.gaps.length > 0 ? ( -
+
Missing evidence
    {section.gaps.map((gap) =>
  • {gap}
  • )}
) : null} -
+
))} -
- What we're working on - {snapshot.work.length === 0 ? ( - - ) : ( -
- {snapshot.work.map((w) => )} -
- )} -
- Experiment results: Benchmarks ·{' '} Load tests @@ -160,28 +153,6 @@ function MetricDetails({ metric, snapshot }: { metric: Metric; snapshot: Snapsho ); } -function WorkCard({ item }: { item: WorkItem }) { - const rows = [ - ['Hypothesis', item.hypothesis], - ['Change', item.change], - ['Expected impact', item.expected ?? 'Not estimated'], - ['Realized impact', item.realized ?? 'Not measured'], - ]; - return ( - - {item.title} - {item.status} · {item.owner ?? 'No owner assigned'} - {rows.map(([term, text]) => ( -

{term}: {text}

- ))} -
- {item.evidence ? : null} - {item.links.map((l) => )} -
-
- ); -} - function ExternalLink({ link }: { link: { label: string; url: string } }) { return (