Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/docs/audits/landing-simplify-2026-03-21.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,49 @@ Full review of `/packages/landing/src` (477 source files) for code reuse, qualit
## Bugs Found and Fixed (discovered during audit work)

### B1. ROB2 optional question marking too aggressive

- **Files**: `components/checklist/ROB2Checklist/DomainSection.tsx`
- **Problem**: Questions 4.2-4.5 showed "(Optional)" when no answers were given. `getRequiredQuestions` returns only the entry-point question with no answers, so everything else looked optional.
- **Fix**: Added `hasAnyAnswer` guard -- questions only marked optional once the user has started answering in that domain.
- [x] Fixed

### B2. Immer stack overflow on reconciliation "Use This"

- **Files**: `stores/projectStore.ts`, `primitives/useProject/sync.ts`
- **Problem**: `persistStats` called `JSON.stringify` on an Immer draft proxy inside `produce`, causing stack overflow. Also ROB2 Y.Text objects leaked into Immer via `toJSON()`.
- **Fix**: Moved `persistStats` outside Immer `produce`. Added explicit ROB2 Y.Text serialization in `sync.ts`.
- [x] Fixed

### B3. ROB2 reconciliation navbar pills not expanding

- **Files**: `components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsx`, `engine/useReconciliationEngine.ts`, `engine/types.ts`, all adapter navbar-utils
- **Problem**: Two issues: (1) Radix Collapsible only supports vertical expand, not horizontal. (2) Engine stored `item.section` (display name like "Domain 1: Bias...") but navbar compared against section keys ("domain1") -- they never matched.
- **Fix**: Replaced Radix Collapsible with CSS `max-width` transition. Added `sectionKey` field to `ReconciliationNavItem`. All adapters and navbar-utils now use `sectionKey` consistently.
- [x] Fixed

### B4. PreliminaryPage Y.Text value bleeding between fields

- **Files**: `components/project/reconcile-tab/rob2-reconcile/pages/PreliminaryPage.tsx`, `adapter.tsx`
- **Problem**: When navigating between preliminary text field pages, the `onFinalChange` closure captured the new field's key but the effect fired with the old field's Y.Text value, writing it to the wrong field.
- **Fix**: Added `key={currentItem.key}` on PreliminaryPage in the adapter (forces remount per field). Used `useEffectEvent` for the sync callback to avoid stale closures.
- [x] Fixed

### B5. Aim selection clearing text fields in ROB2 checklist

- **Files**: `components/checklist/ROB2Checklist/PreliminarySection.tsx`
- **Problem**: All preliminary handlers spread `...preliminaryState` when updating, overwriting Y.Text fields with stale/empty string values. Clicking the aim radio after typing text wiped the text.
- **Fix**: Changed handlers to only send the changed field (e.g. `{ aim: value }` instead of `{ ...preliminaryState, aim: value }`). The ROB2 handler's `updateAnswer` already does field-level merging.
- [x] Fixed

### B6. Presence not working in ROB2 reconciliation

- **Files**: `project/ConnectionPool.ts`
- **Problem**: `getAwareness` was a method on the `ConnectionPool` class but was not included in `buildOpsMap`. `ReconciliationWrapper` destructured it from the ops map and got `undefined`.
- **Fix**: Added `getAwareness` to the flat ops map in `buildOpsMap`.
- [x] Fixed

### B7. ROB2 e2e test only smoke-tested reconciliation

- **Files**: `e2e/rob2-workflow.spec.ts`
- **Problem**: Test verified reconciliation page loaded but never clicked "Use This", navigated through items, or saved. Would not have caught B2, B3, B4, or B5.
- **Fix**: Extended test to walk through all 34 reconciliation items (clicking "Use This", selecting directions, checking sources), verify summary, save, and confirm finalization.
Expand Down
43 changes: 24 additions & 19 deletions packages/docs/audits/rob2-visualizations-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
The project has AMSTAR2 visualizations (traffic light heatmap + distribution stacked bar chart) but no ROB2 equivalents. ROB2 assessments are fully functional (checklist, scoring, reconciliation) but there's no way to visualize finalized ROB2 results at the project overview level.

Standard robvis-style ROB2 visualizations show:

- **Traffic light plot**: rows = studies, columns = 5 bias domains + Overall
- **Summary plot**: horizontal stacked bars showing % Low / Some concerns / High per domain

## Data Differences: ROB2 vs AMSTAR2

| Aspect | AMSTAR2 | ROB2 |
|--------|---------|------|
| Columns | 16 flat questions (Q1-Q16) | 5 domains + Overall (6 columns) |
| Values | yes, partial yes, no, no ma | Low, Some concerns, High |
| Legend items | 4 | 3 |
| Branching | None | Domain 2a vs 2b based on aim |
| consolidatedAnswers | Set in sync.ts via `getAMSTAR2Answers()` | **Not currently set** |
| Aspect | AMSTAR2 | ROB2 |
| ------------------- | ---------------------------------------- | ------------------------------- |
| Columns | 16 flat questions (Q1-Q16) | 5 domains + Overall (6 columns) |
| Values | yes, partial yes, no, no ma | Low, Some concerns, High |
| Legend items | 4 | 3 |
| Branching | None | Domain 2a vs 2b based on aim |
| consolidatedAnswers | Set in sync.ts via `getAMSTAR2Answers()` | **Not currently set** |

## Implementation Plan

Expand All @@ -30,7 +31,7 @@ Add a new function that extracts domain-level judgments into a chart-friendly fo
export interface ROB2ConsolidatedAnswers {
aim: 'ASSIGNMENT' | 'ADHERING' | null;
domain2Variant: '2a' | '2b';
judgments: (string | null)[]; // [D1, D2, D3, D4, D5, Overall] -- 6 entries
judgments: (string | null)[]; // [D1, D2, D3, D4, D5, Overall] -- 6 entries
}
```

Expand Down Expand Up @@ -59,6 +60,7 @@ Move the `exportChart` function from `ChartSection.tsx` into a shared utility. U
**File (new)**: `packages/landing/src/components/charts/ROB2Robvis.tsx`

D3-based SVG component mirroring `AMSTARRobvis.tsx` with these differences:

- **6 columns**: D1, D2, D3, D4, D5, Overall (instead of 16)
- **Color map**: `{ low: '#10b981', 'some concerns': '#facc15', high: '#ef4444' }`
- **Greyscale map**: `{ low: '#1b1b1b', 'some concerns': '#484848', high: '#727272' }`
Expand All @@ -69,10 +71,11 @@ D3-based SVG component mirroring `AMSTARRobvis.tsx` with these differences:
- Same patterns: `useImperativeHandle`, `ResizeObserver`, `useLayoutEffect` for label width, D3 imperative draw

Data interface:

```typescript
interface ROB2RobvisDataItem {
label: string;
judgments: (string | null)[]; // 6 entries
judgments: (string | null)[]; // 6 entries
}
```

Expand All @@ -81,6 +84,7 @@ interface ROB2RobvisDataItem {
**File (new)**: `packages/landing/src/components/charts/ROB2Distribution.tsx`

D3-based SVG component mirroring `AMSTARDistribution.tsx` with these differences:

- **6 bars** (D1-D5 + Overall) instead of 16
- **3 stacked categories** (Low, Some concerns, High) instead of 4
- Same color/greyscale maps as ROB2Robvis
Expand All @@ -93,6 +97,7 @@ D3-based SVG component mirroring `AMSTARDistribution.tsx` with these differences
**File (new)**: `packages/landing/src/components/project/overview-tab/ROB2ChartSection.tsx`

Parallel to existing `ChartSection.tsx`. Responsibilities:

- Filter studies for finalized ROB2 checklists (`type === 'ROB2'`, `status === CHECKLIST_STATUS.FINALIZED`)
- Extract `consolidatedAnswers.judgments` from each
- Manage state: custom labels, greyscale, titles, transparent export, settings modal
Expand All @@ -109,16 +114,16 @@ Add `ROB2ChartSection` alongside `ChartSection` in the Figures collapsible secti

## Files Modified (summary)

| File | Action |
|------|--------|
| `packages/shared/src/checklists/rob2/answers.ts` | Add `getConsolidatedAnswers` |
| `packages/landing/src/primitives/useProject/sync.ts` | Add ROB2 consolidation block |
| `packages/landing/src/components/charts/export-chart.ts` | **New** -- extracted utility |
| `packages/landing/src/components/charts/ROB2Robvis.tsx` | **New** -- traffic light chart |
| `packages/landing/src/components/charts/ROB2Distribution.tsx` | **New** -- distribution chart |
| `packages/landing/src/components/project/overview-tab/ROB2ChartSection.tsx` | **New** -- orchestrator |
| `packages/landing/src/components/project/overview-tab/OverviewTab.tsx` | Add ROB2ChartSection |
| `packages/landing/src/components/project/overview-tab/ChartSection.tsx` | Import exportChart from shared util |
| File | Action |
| --------------------------------------------------------------------------- | ----------------------------------- |
| `packages/shared/src/checklists/rob2/answers.ts` | Add `getConsolidatedAnswers` |
| `packages/landing/src/primitives/useProject/sync.ts` | Add ROB2 consolidation block |
| `packages/landing/src/components/charts/export-chart.ts` | **New** -- extracted utility |
| `packages/landing/src/components/charts/ROB2Robvis.tsx` | **New** -- traffic light chart |
| `packages/landing/src/components/charts/ROB2Distribution.tsx` | **New** -- distribution chart |
| `packages/landing/src/components/project/overview-tab/ROB2ChartSection.tsx` | **New** -- orchestrator |
| `packages/landing/src/components/project/overview-tab/OverviewTab.tsx` | Add ROB2ChartSection |
| `packages/landing/src/components/project/overview-tab/ChartSection.tsx` | Import exportChart from shared util |

## Verification

Expand Down
Loading
Loading