Skip to content

Rename some labels#176

Merged
InfinityBowman merged 8 commits into
mainfrom
175-fix-complete-checklist-reconcile
Dec 27, 2025
Merged

Rename some labels#176
InfinityBowman merged 8 commits into
mainfrom
175-fix-complete-checklist-reconcile

Conversation

@InfinityBowman
Copy link
Copy Markdown
Owner

@InfinityBowman InfinityBowman commented Dec 27, 2025

Summary by CodeRabbit

  • New Features

    • AMSTAR2 checklist validation prevents completion until required items are filled
    • PDFs: open in new tab support and better handling of server/local PDF sources
    • Tab-aware navigation (back/tab params) for improved workflow
  • UI/UX Improvements

    • Score display: new tooltip component and “rating-only” display option
    • Completed/todo navigation now preserves tab context
  • Bug Fixes

    • More robust PDF text-layer handling
  • Documentation

    • Removed Contributing Guide from Resources

✏️ Tip: You can customize this high-level summary in your review settings.

@InfinityBowman InfinityBowman linked an issue Dec 27, 2025 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 27, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This PR centralizes component import aliases, adds and exports isAMSTAR2Complete(checklist) for AMSTAR2 validation, wires PDF support via pdfUrl/pdfData through layout components, introduces ScoreTooltip and showRatingOnly for ScoreTag, and updates many import paths and small navigation query changes.

Changes

Cohort / File(s) Summary
Config & Aliases
packages/web/jsconfig.json, packages/web/vite.config.js
Remove UI-specific aliases (@auth-ui, @checklist-ui, @project-ui); add/redirect component aliases (@checklist, @project); change @auth target to src/components/auth.
AMSTAR2 Validation
packages/web/src/AMSTAR2/checklist.js
Added and exported isAMSTAR2Complete(checklist) to verify all required AMSTAR2 questions have final answers; guards against invalid input.
Checklist Completion Flow
packages/web/src/components/checklist/ChecklistYjsWrapper.jsx
Use isAMSTAR2Complete to block Complete action for invalid AMSTAR2 checklists; show toast and disable Complete button with tooltip; derive back-tab from URL; compute pdfUrl via getPdfUrl.
PDF plumbing & controls
packages/web/src/components/checklist/SplitScreenLayout.jsx, packages/web/src/components/checklist/SplitPanelControls.jsx, packages/web/src/components/checklist/ChecklistWithPdf.jsx, packages/web/src/components/checklist/compare/ReconciliationWithPdf.jsx, packages/web/src/components/checklist/compare/ReconciliationWrapper.jsx
Add pdfUrl and pdfData props; create/revoke blob URLs when needed; expose external-open control; forward pdf props through layout and reconciliation components.
PDF text-layer robustness
packages/web/src/components/checklist/pdf/pdfTextSelection.js
Add defensive checks to abort text-layer work if DOM node cleaned up during async processing.
ScoreTag & Tooltip
packages/web/src/components/checklist/ScoreTag.jsx, packages/web/src/components/project/overview-tab/AMSTAR2ResultsTable.jsx
Add showRatingOnly prop to ScoreTag; extract new exported ScoreTooltip component; change header label to “Rating” and use showRatingOnly in table cells.
Split/Panel lifecycle
packages/web/src/components/checklist/SplitPanelControls.jsx, packages/web/src/components/checklist/SplitScreenLayout.jsx
Manage pdf blob lifecycle with createEffect/onCleanup/createMemo; add server vs local pdf selection logic and new external link icon.
Import path updates — layouts & routes
packages/web/src/Layout.jsx, packages/web/src/Routes.jsx, packages/web/src/components/Dashboard.jsx, packages/web/src/components/profile/ProfilePage.jsx, packages/web/src/components/project/ProjectView.jsx
Replace old alias imports with new component-based paths (e.g., @components/*@/components/*, @auth-ui@/components/auth).
Import path updates — checklist & project components
packages/web/src/components/checklist/*, packages/web/src/components/project/* (many files; see diff)
Update numerous imports from @checklist-ui/*, @project-ui/* to @/components/checklist/*, @/components/project/*; minor label text fix (“AMSTAR” → “AMSTAR2”).
Navigation query params
packages/web/src/components/project/completed-tab/CompletedTab.jsx, packages/web/src/components/project/todo-tab/ToDoTab.jsx
Append tab=completed / tab=todo query parameters when navigating to checklists.
Small tests & landing config
packages/workers/src/__tests__/admin.test.js, packages/landing/app.config.timestamp_1766853344755.js
Minor test refactor (_error variable) and add SolidStart app config file (new export).

Sequence Diagram(s)

mermaid
sequenceDiagram
participant User
participant ChecklistUI as Checklist UI (ChecklistYjsWrapper)
participant Validator as isAMSTAR2Complete
participant Toast
participant Server as Backend (complete API)

Note over ChecklistUI, Validator: New validation path for AMSTAR2 completion
User->>ChecklistUI: Click "Complete"
ChecklistUI->>Validator: validate(checklist)
alt validation fails
Validator-->>ChecklistUI: false
ChecklistUI->>Toast: show("AMSTAR2 checklist incomplete")
ChecklistUI-->>User: Disable Complete (tooltip)
else validation passes
Validator-->>ChecklistUI: true
ChecklistUI->>Server: submitComplete(checklist)
Server-->>ChecklistUI: success
ChecklistUI-->>User: Complete flow proceeds
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

Poem

🐰 I hopped through aliases, tidy and neat,
Checked AMSTAR2 so answers all meet,
PDFs now open, local or hosted by URL,
Tooltips sparkle where scores used to dwell,
A rabbit’s small refactor — neat and well!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.90% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The PR title 'Rename some labels' is vague and generic, failing to describe the actual substantial changes made throughout the codebase. Use a more descriptive title that captures the main objective, such as 'Refactor module aliases and reorganize component imports' or 'Consolidate UI-specific aliases to component-based paths'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6a1d54 and e3c45f5.

📒 Files selected for processing (3)
  • packages/docs/guides/development-workflow.md
  • packages/landing/app.config.timestamp_1766853344755.js
  • packages/workers/src/__tests__/admin.test.js

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Dec 27, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
corates e3c45f5 Commit Preview URL Dec 27 2025, 04:39 PM

@InfinityBowman InfinityBowman linked an issue Dec 27, 2025 that may be closed by this pull request
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d736630 and 15408bd.

📒 Files selected for processing (5)
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
🧰 Additional context used
📓 Path-based instructions (19)
packages/web/src/components/checklist-ui/**

📄 CodeRabbit inference engine (.cursor/rules/checklist-operations.mdc)

Use NoteEditor component from @/components/checklist-ui/common/NoteEditor.jsx for question note editing with max 2000 character limit

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
packages/web/**/!(*.test|*.spec).{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/web/**/!(*.test|*.spec).{js,ts,jsx,tsx}: Always use handleFetchError from @/lib/error-utils.js for frontend fetch calls with optional showToast parameter
Use createFormErrorSignals from @/lib/form-errors.js for handling form validation errors, field-level errors, and global errors in frontend forms

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
packages/{web,workers}/**/!(*.test|*.spec).{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/{web,workers}/**/!(*.test|*.spec).{js,ts,jsx,tsx}: Never throw string literals; always throw Error objects or return domain errors from API routes
Use isErrorCode utility from @corates/shared or @/lib/error-utils.js to check for specific error codes instead of manual error comparisons

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
packages/web/src/**/*.{js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/form-state.mdc)

packages/web/src/**/*.{js,jsx}: Save form state to IndexedDB before initiating OAuth redirects (Google Drive, ORCID) using saveFormState() with form type ('createProject' or 'addStudies') and serializable state only
Only save serializable data to IndexedDB—exclude File objects, ArrayBuffers, functions, and other non-serializable objects from form state persistence
Restore form state after OAuth redirects by checking URL restore params with getRestoreParamsFromUrl(), retrieving saved state with getFormState(), restoring to form, clearing saved state with clearFormState(), and clearing URL params with clearRestoreParamsFromUrl()
For temporary File object storage during OAuth flows (e.g., pending PDFs), use projectStore.setPendingProjectData() instead of IndexedDB, as File objects cannot be serialized
Add restore parameters to the URL after OAuth redirects in the format '?restore=&projectId=' to signal form state restoration on mount
Clear URL restore parameters after form state restoration by calling clearRestoreParamsFromUrl() to prevent stale restoration attempts on subsequent navigation
Form state persistence library functions (saveFormState, getFormState, clearFormState, getRestoreParamsFromUrl, clearRestoreParamsFromUrl) are implemented in packages/web/src/lib/formStatePersistence.js and should be imported from @/lib/formStatePersistence.js

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)

packages/web/src/**/*.{js,jsx,ts,tsx}: Always use uploadPdf from @api/pdf-api.js for uploading PDF files. Pass object with projectId, studyId, tag ('primary' or 'supplementary'), and fileName
Validate PDF files on frontend by checking file.type includes 'pdf' and file.size is within MAX_PDF_SIZE limit (full validation is done on backend)
Use cachePdf and getCachedPdf from @primitives/pdfCache.js for caching PDF data in IndexedDB
Implement PDF caching strategy: check cache first, download from server if not cached, then cache the downloaded PDF
Store only PDF metadata in Yjs (id, name, size, tag, uploadedAt, uploadedBy), never store PDF binary data in Yjs as it is too large
Use importFromGoogleDrive from @api/google-drive.js for importing PDFs from Google Drive. Pass fileId, projectId, studyId, and tag
Save form state using saveFormState from @/lib/formStatePersistence.js before triggering OAuth redirects for Google Drive
Use addPdfToStudy operation from useProject hook to add PDFs to a study, passing id, name, size, tag, uploadedAt, and uploadedBy
Use removePdfFromStudy operation from useProject hook to remove PDFs from a study
Use pdfPreviewStore from @/stores/pdfPreviewStore.js for managing PDF preview state (openPreview, closePreview, getPreview methods)
Use downloadPdf from @api/pdf-api.js to download PDFs from server, then cache the result using cachePdf
Always cache PDFs after download and check cache before downloading to avoid redundant downloads
Use PDF operations from useProject hook instead of bypassing through direct API calls

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)

Use PdfViewer component from @/components/checklist-ui/pdf/PdfViewer.jsx for displaying PDFs, passing pdfData as ArrayBuffer, fileName, readOnly, and onPageChange

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
{packages/web/**,packages/landing/**}/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{jsx,tsx}: NEVER destructure props in SolidJS components - access props directly or wrap in functions to maintain reactivity
Use external stores in packages/web/src/stores/ for shared/cross-feature state instead of prop-drilling
Keep SolidJS components lean and focused on rendering - move business logic to stores, primitives, or utilities
Create reusable logic in primitives (hooks) in packages/web/src/primitives/ and import them into components
Use Solid's Show component for conditional rendering instead of ternary operators
Use Solid's For component for rendering lists instead of Array.map()
Use the children helper when manipulating props.children in SolidJS components

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}: Use createSignal for simple reactive values in SolidJS components
Use createStore for complex objects and arrays that need granular reactivity in SolidJS
Use createMemo for computed/derived values that depend on reactive state in SolidJS
Always clean up SolidJS effects that create subscriptions or timers using onCleanup
Import stores directly in components and use store read/write action pattern - read from store, write via actions store
Prefer derived state with createMemo or signals over effects whenever possible
Use local createSignal or createStore for local component state; use external stores for shared/cross-feature state

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
packages/{web,ui}/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

packages/{web,ui}/**/*.{js,jsx,ts,tsx}: Import UI components from '@corates/ui' package instead of local components directories
Use solid-icons library for icons instead of emojis or other icon sources
Use Tailwind CSS classes for styling UI components
Apply responsive design using mobile-first approach with Tailwind CSS

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
packages/web/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

Use import aliases from jsconfig.json (e.g., @/, @components/, @auth-ui/, @checklist-ui/, @project-ui/, @routes/, @primitives/, @api/, @config/, @lib/) instead of relative paths

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/yjs-sync.mdc)

**/*.{js,jsx,ts,tsx}: Use the useProject hook for managing Yjs connections with reference counting instead of creating Y.Doc instances directly
Never create Y.Doc instances directly; always use the connection registry managed by useProject
Access Y.Doc connection state via projectStore.getConnectionState(projectId) instead of checking connection state directly
Read Yjs-synced data from projectStore (using getStudies, getChecklist, etc.) rather than accessing Y.Doc maps/arrays directly
Use operation functions from useProject or projectActionsStore for writing data instead of directly modifying Y.Doc
Don't store Y.Doc references in component state; always retrieve the connection through useProject
Handle connection cleanup via onCleanup() in Solid.js components or equivalent cleanup patterns, calling disconnect() when the component unmounts

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*: NEVER use emojis anywhere - not in code, comments, documentation, plan files, commit messages, or examples
Do NOT use unicode symbols - unicode symbols are forbidden anywhere in the codebase

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,jsx,js}: For UI icons, use solid-icons library or SVGs only (never emojis)
Prefer modern ES6+ syntax and features
Use import aliases from jsconfig.json as defined in the ui-components.mdc documentation
Prefer config files over hardcoding values
Ensure browser compatibility (Safari is usually problematic)
Group related components in subdirectories with barrel exports
Use Ark UI components from @corates/ui package, not local component implementations
Use solid-icons icon library (e.g., solid-icons/bi, solid-icons/fi) for icons
Comments should explain WHY something is being done, not WHAT the code is doing
Comment to explain why a particular approach or workaround was chosen
Comment to clarify intent when code could be misread or misunderstood
Comment to provide context from external systems, specs, or requirements
Comment to document assumptions, edge cases, or limitations
Do NOT comment by narrating what the code is doing
Do NOT duplicate function or variable names in plain English comments
Do NOT leave stale comments that contradict the code
Do NOT reference removed or obsolete code paths in comments

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
packages/web/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/**/*.{ts,tsx,jsx}: Do NOT prop-drill application state in SolidJS - import stores directly where needed
Do NOT destructure props in SolidJS - access props.field directly or wrap in function: () => props.field
SolidJS components should receive at most 1-5 props (local config only, not shared state)
Move business logic to stores, utilities, or primitives (not in components) in SolidJS

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

For UI icons, use solid-icons library or SVGs only (never emojis)

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

Prefer modern ES6+ syntax and features

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
packages/web/src/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

packages/web/src/**/*.{ts,tsx,jsx}: Use import aliases from jsconfig.json
Use Ark UI components from @corates/ui package, NOT local components
Do NOT prop-drill application state; import stores directly where needed
Use createMemo for derived values
Move business logic to stores, utilities, or primitives (not components)

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
packages/web/src/components/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

packages/web/src/components/**/*.{ts,tsx,jsx}: Group related components in subdirectories with barrel exports
Do NOT destructure props; access props.field directly or wrap in function: () => props.field
Components should receive at most 1-5 props (local config only, not shared state)

Files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
packages/web/src/components/project-ui/**/*.{js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/form-state.mdc)

Form state should include serializable metadata when handling files (name, size, type) and use the store's pendingPdfs pattern for actual File objects that persist across redirects

Files:

  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
🧠 Learnings (21)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Checklist status transitions follow sequence: in_progress → completed (when all questions answered) → reconciled (after reconciliation complete)
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Use scoreChecklist utility from @/AMSTAR2/checklist.js to determine quality assessment rating: 'High' | 'Moderate' | 'Low' | 'Critically Low'
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Handle multi-part AMSTAR2 questions correctly: q9 (parts a, b), q11 (parts a, b) require separate answer entries
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : AMSTAR2 answers must use matrix format: array of column arrays with boolean values representing checkbox selections per column
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Use getChecklistStatus utility from @/lib/checklist-domain.js to determine current checklist status before performing operations
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/AMSTAR2/checklist-compare.js} : Use compareChecklists utility from checklist-compare.js for comparing reviewer checklists
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Maintain separate answer format implementations for each checklist type (AMSTAR2, ROBINS-I, Generic) to prevent data corruption
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js,packages/web/src/AMSTAR2/checklist-compare.js} : Store final answers in the reconciled checklist itself, not in reconciliation progress metadata
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/ROBINS-I/** : Use scoreChecklist utility from @/ROBINS-I/checklist.js to determine risk of bias rating: 'Low' | 'Moderate' | 'Serious' | 'Critical'
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js,packages/web/src/primitives/useProject/checklists.js : Use checklist operations from useProject hook (createChecklist, updateChecklistAnswer, getChecklistData) instead of manually updating checklist structure
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Use getChecklistStatus utility from @/lib/checklist-domain.js to determine current checklist status before performing operations

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js,packages/web/src/AMSTAR2/checklist-compare.js} : Store final answers in the reconciled checklist itself, not in reconciliation progress metadata

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/AMSTAR2/checklist-compare.js} : Use compareChecklists utility from checklist-compare.js for comparing reviewer checklists

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js,packages/web/src/primitives/useProject/checklists.js : Use checklist operations from useProject hook (createChecklist, updateChecklistAnswer, getChecklistData) instead of manually updating checklist structure

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Checklist status transitions follow sequence: in_progress → completed (when all questions answered) → reconciled (after reconciliation complete)

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Use scoreChecklist utility from @/AMSTAR2/checklist.js to determine quality assessment rating: 'High' | 'Moderate' | 'Low' | 'Critically Low'

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Handle multi-part AMSTAR2 questions correctly: q9 (parts a, b), q11 (parts a, b) require separate answer entries

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Maintain separate answer format implementations for each checklist type (AMSTAR2, ROBINS-I, Generic) to prevent data corruption

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : AMSTAR2 answers must use matrix format: array of column arrays with boolean values representing checkbox selections per column

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/AMSTAR2/checklist.js
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/primitives/useProject/checklists.js : Store question notes as Y.Text objects obtained from useProject hook via getQuestionNote operation to enable collaborative editing

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/lib/checklist-domain.js : Register and retrieve checklists using checklist-registry: getChecklistType and getChecklistComponent functions

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/ROBINS-I/** : Use scoreChecklist utility from @/ROBINS-I/checklist.js to determine risk of bias rating: 'Low' | 'Moderate' | 'Serious' | 'Critical'

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createSignal for simple reactive values in SolidJS components

Applied to files:

  • packages/web/src/components/project-ui/overview-tab/ChartSection.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/lib/checklist-domain.js,packages/web/src/AMSTAR2/checklist-compare.js} : Reconciliation structure should contain checklist1Id, checklist2Id, and reconciledChecklistId

Applied to files:

  • packages/web/src/AMSTAR2/checklist.js
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js} : Multi-part answers (q9a, q9b, q11a, q11b) should be stored as objects with answer matrix and critical flag properties

Applied to files:

  • packages/web/src/AMSTAR2/checklist.js
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to packages/web/src/components/checklist-ui/compare/** : Use multiPartAnswersEqual helper to compare multi-part answers between reviewers

Applied to files:

  • packages/web/src/AMSTAR2/checklist.js
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to packages/web/src/components/checklist-ui/compare/** : Auto-fill final answer with reviewer1's answer when reviewers agree and no final answer exists

Applied to files:

  • packages/web/src/AMSTAR2/checklist.js
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to packages/web/src/components/checklist-ui/compare/** : Use Y.Text objects for collaborative editing of question notes in reconciliation

Applied to files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/** : Use NoteEditor component from @/components/checklist-ui/common/NoteEditor.jsx for question note editing with max 2000 character limit

Applied to files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Use Solid's Show component for conditional rendering instead of ternary operators

Applied to files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
🧬 Code graph analysis (2)
packages/web/src/components/checklist-ui/ScoreTag.jsx (2)
packages/web/src/checklist-registry/types.js (3)
  • DEFAULT_CHECKLIST_TYPE (60-60)
  • DEFAULT_CHECKLIST_TYPE (60-60)
  • getChecklistMetadata (67-69)
packages/ui/src/components/index.ts (1)
  • Tooltip (31-31)
packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx (1)
packages/web/src/components/checklist-ui/ScoreTag.jsx (2)
  • ScoreTooltip (71-88)
  • ScoreTag (52-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (11)
packages/web/src/components/project-ui/overview-tab/ChartSection.jsx (1)

106-108: LGTM - Label updated to reflect AMSTAR2 terminology.

The chart title has been correctly updated from "AMSTAR" to "AMSTAR2", aligning with the PR objectives.

packages/web/src/AMSTAR2/checklist.js (1)

201-246: LGTM - Validation logic correctly enforces AMSTAR2 completion requirements.

The isAMSTAR2Complete function correctly validates that all 18 required question keys (including multi-part q9a, q9b, q11a, q11b) have final answers in the last column. The implementation properly handles the AMSTAR2 matrix format and follows the established patterns for multi-part question handling.

Based on learnings, multi-part AMSTAR2 questions require separate answer entries, which this function correctly checks.

packages/web/src/components/project-ui/overview-tab/AMSTAR2ResultsTable.jsx (3)

4-4: LGTM - ScoreTooltip import added for enhanced UI.

The import correctly brings in the new ScoreTooltip component alongside the existing ScoreTag.


175-177: LGTM - Header enhanced with rating label and tooltip.

The header now displays "Rating" with an inline ScoreTooltip, providing users with contextual guidance about AMSTAR2 ratings.


189-189: LGTM - Table cells use showRatingOnly for cleaner display.

The showRatingOnly prop simplifies the cell display by showing only the rating value without the "Rating:" prefix, which is appropriate for table rows since the header already establishes context.

packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (4)

16-16: LGTM - Import added for AMSTAR2 validation.

The isAMSTAR2Complete function is correctly imported to support the new validation gate.


266-273: LGTM - Validation gate prevents incomplete checklist completion.

The validation check correctly prevents users from marking incomplete AMSTAR2 checklists as complete, with clear error messaging to guide users.

Based on learnings, checklist status transitions follow the sequence: in_progress → completed → reconciled, and this gate ensures the transition to completed only occurs when validation passes.


316-327: LGTM - Type-aware validation logic.

The isChecklistValid memo correctly applies AMSTAR2-specific validation while allowing other checklist types to complete without additional constraints. This maintains backward compatibility and follows the principle of maintaining separate implementations for each checklist type.

Based on learnings, separate answer format implementations are maintained for each checklist type to prevent data corruption.


383-393: LGTM - Button state reflects validation status.

The completion button is appropriately disabled when the checklist is invalid, with a helpful tooltip and visual styling to communicate the requirement to users.

packages/web/src/components/checklist-ui/ScoreTag.jsx (2)

52-69: LGTM - Conditional rendering adds flexibility.

The showRatingOnly prop allows the component to render in two modes: a compact rating-only view for tables, and a full view with "Rating:" prefix and tooltip for standalone usage. The conditional logic is clear and follows SolidJS best practices.


71-88: LGTM - ScoreTooltip extraction improves reusability.

Extracting the tooltip logic into a dedicated ScoreTooltip component is a good refactor that enables independent usage in table headers and other locations while maintaining consistent behavior.

Comment thread packages/web/src/components/checklist-ui/ScoreTag.jsx Outdated
@InfinityBowman InfinityBowman linked an issue Dec 27, 2025 that may be closed by this pull request
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (1)

330-335: LGTM!

The getBackTab function correctly reads the tab query parameter from the URL with a sensible fallback to "overview". This enables proper back-navigation to the originating tab.

Note: The commented-out console.log on Line 332 can be removed in a future cleanup.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15408bd and 72af74e.

📒 Files selected for processing (5)
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
🧰 Additional context used
📓 Path-based instructions (19)
packages/web/**/!(*.test|*.spec).{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/web/**/!(*.test|*.spec).{js,ts,jsx,tsx}: Always use handleFetchError from @/lib/error-utils.js for frontend fetch calls with optional showToast parameter
Use createFormErrorSignals from @/lib/form-errors.js for handling form validation errors, field-level errors, and global errors in frontend forms

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/{web,workers}/**/!(*.test|*.spec).{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/{web,workers}/**/!(*.test|*.spec).{js,ts,jsx,tsx}: Never throw string literals; always throw Error objects or return domain errors from API routes
Use isErrorCode utility from @corates/shared or @/lib/error-utils.js to check for specific error codes instead of manual error comparisons

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/**/*.{js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/form-state.mdc)

packages/web/src/**/*.{js,jsx}: Save form state to IndexedDB before initiating OAuth redirects (Google Drive, ORCID) using saveFormState() with form type ('createProject' or 'addStudies') and serializable state only
Only save serializable data to IndexedDB—exclude File objects, ArrayBuffers, functions, and other non-serializable objects from form state persistence
Restore form state after OAuth redirects by checking URL restore params with getRestoreParamsFromUrl(), retrieving saved state with getFormState(), restoring to form, clearing saved state with clearFormState(), and clearing URL params with clearRestoreParamsFromUrl()
For temporary File object storage during OAuth flows (e.g., pending PDFs), use projectStore.setPendingProjectData() instead of IndexedDB, as File objects cannot be serialized
Add restore parameters to the URL after OAuth redirects in the format '?restore=&projectId=' to signal form state restoration on mount
Clear URL restore parameters after form state restoration by calling clearRestoreParamsFromUrl() to prevent stale restoration attempts on subsequent navigation
Form state persistence library functions (saveFormState, getFormState, clearFormState, getRestoreParamsFromUrl, clearRestoreParamsFromUrl) are implemented in packages/web/src/lib/formStatePersistence.js and should be imported from @/lib/formStatePersistence.js

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/components/project-ui/**/*.{js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/form-state.mdc)

Form state should include serializable metadata when handling files (name, size, type) and use the store's pendingPdfs pattern for actual File objects that persist across redirects

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)

packages/web/src/**/*.{js,jsx,ts,tsx}: Always use uploadPdf from @api/pdf-api.js for uploading PDF files. Pass object with projectId, studyId, tag ('primary' or 'supplementary'), and fileName
Validate PDF files on frontend by checking file.type includes 'pdf' and file.size is within MAX_PDF_SIZE limit (full validation is done on backend)
Use cachePdf and getCachedPdf from @primitives/pdfCache.js for caching PDF data in IndexedDB
Implement PDF caching strategy: check cache first, download from server if not cached, then cache the downloaded PDF
Store only PDF metadata in Yjs (id, name, size, tag, uploadedAt, uploadedBy), never store PDF binary data in Yjs as it is too large
Use importFromGoogleDrive from @api/google-drive.js for importing PDFs from Google Drive. Pass fileId, projectId, studyId, and tag
Save form state using saveFormState from @/lib/formStatePersistence.js before triggering OAuth redirects for Google Drive
Use addPdfToStudy operation from useProject hook to add PDFs to a study, passing id, name, size, tag, uploadedAt, and uploadedBy
Use removePdfFromStudy operation from useProject hook to remove PDFs from a study
Use pdfPreviewStore from @/stores/pdfPreviewStore.js for managing PDF preview state (openPreview, closePreview, getPreview methods)
Use downloadPdf from @api/pdf-api.js to download PDFs from server, then cache the result using cachePdf
Always cache PDFs after download and check cache before downloading to avoid redundant downloads
Use PDF operations from useProject hook instead of bypassing through direct API calls

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)

Use PdfViewer component from @/components/checklist-ui/pdf/PdfViewer.jsx for displaying PDFs, passing pdfData as ArrayBuffer, fileName, readOnly, and onPageChange

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
{packages/web/**,packages/landing/**}/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{jsx,tsx}: NEVER destructure props in SolidJS components - access props directly or wrap in functions to maintain reactivity
Use external stores in packages/web/src/stores/ for shared/cross-feature state instead of prop-drilling
Keep SolidJS components lean and focused on rendering - move business logic to stores, primitives, or utilities
Create reusable logic in primitives (hooks) in packages/web/src/primitives/ and import them into components
Use Solid's Show component for conditional rendering instead of ternary operators
Use Solid's For component for rendering lists instead of Array.map()
Use the children helper when manipulating props.children in SolidJS components

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}: Use createSignal for simple reactive values in SolidJS components
Use createStore for complex objects and arrays that need granular reactivity in SolidJS
Use createMemo for computed/derived values that depend on reactive state in SolidJS
Always clean up SolidJS effects that create subscriptions or timers using onCleanup
Import stores directly in components and use store read/write action pattern - read from store, write via actions store
Prefer derived state with createMemo or signals over effects whenever possible
Use local createSignal or createStore for local component state; use external stores for shared/cross-feature state

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/{web,ui}/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

packages/{web,ui}/**/*.{js,jsx,ts,tsx}: Import UI components from '@corates/ui' package instead of local components directories
Use solid-icons library for icons instead of emojis or other icon sources
Use Tailwind CSS classes for styling UI components
Apply responsive design using mobile-first approach with Tailwind CSS

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

Use import aliases from jsconfig.json (e.g., @/, @components/, @auth-ui/, @checklist-ui/, @project-ui/, @routes/, @primitives/, @api/, @config/, @lib/) instead of relative paths

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/yjs-sync.mdc)

**/*.{js,jsx,ts,tsx}: Use the useProject hook for managing Yjs connections with reference counting instead of creating Y.Doc instances directly
Never create Y.Doc instances directly; always use the connection registry managed by useProject
Access Y.Doc connection state via projectStore.getConnectionState(projectId) instead of checking connection state directly
Read Yjs-synced data from projectStore (using getStudies, getChecklist, etc.) rather than accessing Y.Doc maps/arrays directly
Use operation functions from useProject or projectActionsStore for writing data instead of directly modifying Y.Doc
Don't store Y.Doc references in component state; always retrieve the connection through useProject
Handle connection cleanup via onCleanup() in Solid.js components or equivalent cleanup patterns, calling disconnect() when the component unmounts

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*: NEVER use emojis anywhere - not in code, comments, documentation, plan files, commit messages, or examples
Do NOT use unicode symbols - unicode symbols are forbidden anywhere in the codebase

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,jsx,js}: For UI icons, use solid-icons library or SVGs only (never emojis)
Prefer modern ES6+ syntax and features
Use import aliases from jsconfig.json as defined in the ui-components.mdc documentation
Prefer config files over hardcoding values
Ensure browser compatibility (Safari is usually problematic)
Group related components in subdirectories with barrel exports
Use Ark UI components from @corates/ui package, not local component implementations
Use solid-icons icon library (e.g., solid-icons/bi, solid-icons/fi) for icons
Comments should explain WHY something is being done, not WHAT the code is doing
Comment to explain why a particular approach or workaround was chosen
Comment to clarify intent when code could be misread or misunderstood
Comment to provide context from external systems, specs, or requirements
Comment to document assumptions, edge cases, or limitations
Do NOT comment by narrating what the code is doing
Do NOT duplicate function or variable names in plain English comments
Do NOT leave stale comments that contradict the code
Do NOT reference removed or obsolete code paths in comments

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/**/*.{ts,tsx,jsx}: Do NOT prop-drill application state in SolidJS - import stores directly where needed
Do NOT destructure props in SolidJS - access props.field directly or wrap in function: () => props.field
SolidJS components should receive at most 1-5 props (local config only, not shared state)
Move business logic to stores, utilities, or primitives (not in components) in SolidJS

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

For UI icons, use solid-icons library or SVGs only (never emojis)

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

Prefer modern ES6+ syntax and features

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

packages/web/src/**/*.{ts,tsx,jsx}: Use import aliases from jsconfig.json
Use Ark UI components from @corates/ui package, NOT local components
Do NOT prop-drill application state; import stores directly where needed
Use createMemo for derived values
Move business logic to stores, utilities, or primitives (not components)

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/components/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

packages/web/src/components/**/*.{ts,tsx,jsx}: Group related components in subdirectories with barrel exports
Do NOT destructure props; access props.field directly or wrap in function: () => props.field
Components should receive at most 1-5 props (local config only, not shared state)

Files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/components/checklist-ui/**

📄 CodeRabbit inference engine (.cursor/rules/checklist-operations.mdc)

Use NoteEditor component from @/components/checklist-ui/common/NoteEditor.jsx for question note editing with max 2000 character limit

Files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
🧠 Learnings (34)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Checklist status transitions follow sequence: in_progress → completed (when all questions answered) → reconciled (after reconciliation complete)
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Use scoreChecklist utility from @/AMSTAR2/checklist.js to determine quality assessment rating: 'High' | 'Moderate' | 'Low' | 'Critically Low'
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Handle multi-part AMSTAR2 questions correctly: q9 (parts a, b), q11 (parts a, b) require separate answer entries
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/AMSTAR2/checklist-compare.js} : Use compareChecklists utility from checklist-compare.js for comparing reviewer checklists
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js,packages/web/src/AMSTAR2/checklist-compare.js} : Store final answers in the reconciled checklist itself, not in reconciliation progress metadata
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/ROBINS-I/** : Use scoreChecklist utility from @/ROBINS-I/checklist.js to determine risk of bias rating: 'Low' | 'Moderate' | 'Serious' | 'Critical'
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Use getChecklistStatus utility from @/lib/checklist-domain.js to determine current checklist status before performing operations
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : AMSTAR2 answers must use matrix format: array of column arrays with boolean values representing checkbox selections per column
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Maintain separate answer format implementations for each checklist type (AMSTAR2, ROBINS-I, Generic) to prevent data corruption
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js,packages/web/src/primitives/useProject/checklists.js : Use checklist operations from useProject hook (createChecklist, updateChecklistAnswer, getChecklistData) instead of manually updating checklist structure
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js,packages/web/src/primitives/useProject/checklists.js : Use checklist operations from useProject hook (createChecklist, updateChecklistAnswer, getChecklistData) instead of manually updating checklist structure

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/primitives/useProject/checklists.js : Store question notes as Y.Text objects obtained from useProject hook via getQuestionNote operation to enable collaborative editing

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Use getChecklistStatus utility from @/lib/checklist-domain.js to determine current checklist status before performing operations

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:54.715Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/form-state.mdc:0-0
Timestamp: 2025-12-27T03:01:54.715Z
Learning: Applies to packages/web/src/**/*.{js,jsx} : Add restore parameters to the URL after OAuth redirects in the format '?restore=<formType>&projectId=<projectId>' to signal form state restoration on mount

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Checklist status transitions follow sequence: in_progress → completed (when all questions answered) → reconciled (after reconciliation complete)

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `addPdfToStudy` operation from `useProject` hook to add PDFs to a study, passing id, name, size, tag, uploadedAt, and uploadedBy

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `removePdfFromStudy` operation from `useProject` hook to remove PDFs from a study

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Use `PdfViewer` component from `@/components/checklist-ui/pdf/PdfViewer.jsx` for displaying PDFs, passing pdfData as ArrayBuffer, fileName, readOnly, and onPageChange

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Always use `uploadPdf` from `api/pdf-api.js` for uploading PDF files. Pass object with projectId, studyId, tag ('primary' or 'supplementary'), and fileName

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/AMSTAR2/checklist-compare.js} : Use compareChecklists utility from checklist-compare.js for comparing reviewer checklists

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js} : Store reconciliation progress metadata (IDs and optional currentPage) in the study's Y.Map reconciliation property

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/lib/checklist-domain.js,packages/web/src/AMSTAR2/checklist-compare.js} : Reconciliation structure should contain checklist1Id, checklist2Id, and reconciledChecklistId

Applied to files:

  • packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Use scoreChecklist utility from @/AMSTAR2/checklist.js to determine quality assessment rating: 'High' | 'Moderate' | 'Low' | 'Critically Low'

Applied to files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/ROBINS-I/** : Use scoreChecklist utility from @/ROBINS-I/checklist.js to determine risk of bias rating: 'Low' | 'Moderate' | 'Serious' | 'Critical'

Applied to files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to packages/web/src/components/checklist-ui/compare/** : Use Y.Text objects for collaborative editing of question notes in reconciliation

Applied to files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/** : Use NoteEditor component from @/components/checklist-ui/common/NoteEditor.jsx for question note editing with max 2000 character limit

Applied to files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Handle multi-part AMSTAR2 questions correctly: q9 (parts a, b), q11 (parts a, b) require separate answer entries

Applied to files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T15:42:01.068Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-27T15:42:01.068Z
Learning: Applies to **/*.{ts,tsx,jsx,js} : Comment to clarify intent when code could be misread or misunderstood

Applied to files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Use Solid's Show component for conditional rendering instead of ternary operators

Applied to files:

  • packages/web/src/components/checklist-ui/ScoreTag.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use PDF operations from `useProject` hook instead of bypassing through direct API calls

Applied to files:

  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `cachePdf` and `getCachedPdf` from `primitives/pdfCache.js` for caching PDF data in IndexedDB

Applied to files:

  • packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js,packages/web/src/AMSTAR2/checklist-compare.js} : Store final answers in the reconciled checklist itself, not in reconciliation progress metadata

Applied to files:

  • packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Maintain separate answer format implementations for each checklist type (AMSTAR2, ROBINS-I, Generic) to prevent data corruption

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createSignal for simple reactive values in SolidJS components

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Prefer derived state with createMemo or signals over effects whenever possible

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createMemo for computed/derived values that depend on reactive state in SolidJS

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use local createSignal or createStore for local component state; use external stores for shared/cross-feature state

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T15:42:01.068Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-27T15:42:01.068Z
Learning: Applies to packages/web/**/*.{ts,tsx} : Use `createMemo` for derived values in SolidJS

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createStore for complex objects and arrays that need granular reactivity in SolidJS

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T15:42:01.068Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-27T15:42:01.068Z
Learning: Applies to packages/web/**/*.{ts,tsx} : Use `createStore` for complex state objects in SolidJS

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/lib/checklist-domain.js : Register and retrieve checklists using checklist-registry: getChecklistType and getChecklistComponent functions

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : AMSTAR2 answers must use matrix format: array of column arrays with boolean values representing checkbox selections per column

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/ROBINS-I/** : Use shouldStopAssessment utility from @/ROBINS-I/checklist.js to check if Section B indicates critical risk of bias requiring assessment termination

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
🧬 Code graph analysis (2)
packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx (8)
packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (1)
  • navigate (20-20)
packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx (1)
  • navigate (17-17)
packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx (1)
  • navigate (37-37)
packages/web/src/components/project-ui/ProjectDashboard.jsx (1)
  • navigate (17-17)
packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx (1)
  • navigate (23-23)
packages/web/src/components/project-ui/ProjectView.jsx (1)
  • navigate (35-35)
packages/web/src/components/project-ui/reconcile-tab/ReconcileTab.jsx (1)
  • navigate (17-17)
packages/web/src/components/sidebar/ChecklistTreeItem.jsx (1)
  • navigate (11-11)
packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx (8)
packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (1)
  • navigate (20-20)
packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx (1)
  • navigate (18-18)
packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx (1)
  • navigate (37-37)
packages/web/src/components/project-ui/ProjectDashboard.jsx (1)
  • navigate (17-17)
packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx (1)
  • navigate (23-23)
packages/web/src/components/project-ui/ProjectView.jsx (1)
  • navigate (35-35)
packages/web/src/components/project-ui/reconcile-tab/ReconcileTab.jsx (1)
  • navigate (17-17)
packages/web/src/components/sidebar/ChecklistTreeItem.jsx (1)
  • navigate (11-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (11)
packages/web/src/components/project-ui/completed-tab/CompletedTab.jsx (1)

27-29: LGTM!

The addition of the ?tab=completed query parameter enables tab-aware navigation, allowing the checklist view to know which tab the user navigated from. This pattern is consistent with the similar change in ToDoTab.jsx.

packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx (1)

50-52: LGTM!

The addition of the ?tab=todo query parameter enables proper back-navigation from the checklist view. This change is consistent with the tab-aware routing pattern established across the PR.

packages/web/src/components/checklist-ui/pdf/pdfTextSelection.js (2)

40-42: Good defensive programming.

The guard after the async getTextContent() operation prevents processing text items if cleanup ran during the await. This avoids potential errors from manipulating a detached DOM element.


99-101: Good defensive programming.

The guard before appending spans prevents DOM manipulation if cleanup ran mid-loop. This is especially important in the async rendering path where cleanup could be triggered at any point.

packages/web/src/components/checklist-ui/ScoreTag.jsx (2)

52-69: LGTM!

The conditional rendering based on showRatingOnly is implemented correctly, and the extraction of ScoreTooltip improves reusability. The reactive signal pattern showRatingOnly() is appropriate for deriving the prop value.


71-88: LGTM!

The extracted ScoreTooltip component is well-structured and follows SolidJS reactivity patterns correctly with createMemo for derived values. This extraction improves code organization and reusability across different contexts (e.g., in AMSTAR2ResultsTable as noted in the AI summary).

packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (5)

2-2: LGTM!

The useLocation import and usage are correct for reading URL query parameters in SolidJS Router.

Also applies to: 21-21


16-16: LGTM!

The isAMSTAR2Complete import correctly brings in the validation utility for AMSTAR2 checklists, aligning with the learnings that recommend using the scoreChecklist utility from the AMSTAR2 module.


267-274: LGTM!

The validation check before completion prevents users from marking incomplete AMSTAR2 checklists as complete, with clear error messaging. This validation respects the checklist status transition sequence (in_progress → completed) as per the learnings.


317-328: LGTM!

The isChecklistValid memo correctly implements type-specific validation:

  • Returns true for non-AMSTAR2 checklists (no validation required)
  • For AMSTAR2, delegates to the isAMSTAR2Complete utility

This follows the principle of maintaining separate implementations for each checklist type as per the learnings.


370-389: LGTM!

The button correctly:

  • Disables when the checklist is invalid
  • Shows a descriptive tooltip explaining why completion is blocked
  • Applies appropriate disabled styling with cursor-not-allowed

This provides clear user feedback and prevents invalid state transitions.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (1)

337-342: Remove commented-out console.log.

The commented-out console.log on line 339 should be removed to keep the codebase clean.

Proposed cleanup
   const getBackTab = () => {
-    // console.log('location', location.search);
     const tabFromUrl = new URLSearchParams(location.search).get('tab');
     return tabFromUrl || 'overview';
   };

As per coding guidelines: Don't leave stale comments or debug artifacts.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72af74e and 01a64c6.

📒 Files selected for processing (6)
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
🧰 Additional context used
📓 Path-based instructions (22)
packages/web/src/components/checklist-ui/**

📄 CodeRabbit inference engine (.cursor/rules/checklist-operations.mdc)

Use NoteEditor component from @/components/checklist-ui/common/NoteEditor.jsx for question note editing with max 2000 character limit

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/**/!(*.test|*.spec).{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/web/**/!(*.test|*.spec).{js,ts,jsx,tsx}: Always use handleFetchError from @/lib/error-utils.js for frontend fetch calls with optional showToast parameter
Use createFormErrorSignals from @/lib/form-errors.js for handling form validation errors, field-level errors, and global errors in frontend forms

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/{web,workers}/**/!(*.test|*.spec).{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/{web,workers}/**/!(*.test|*.spec).{js,ts,jsx,tsx}: Never throw string literals; always throw Error objects or return domain errors from API routes
Use isErrorCode utility from @corates/shared or @/lib/error-utils.js to check for specific error codes instead of manual error comparisons

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/**/*.{js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/form-state.mdc)

packages/web/src/**/*.{js,jsx}: Save form state to IndexedDB before initiating OAuth redirects (Google Drive, ORCID) using saveFormState() with form type ('createProject' or 'addStudies') and serializable state only
Only save serializable data to IndexedDB—exclude File objects, ArrayBuffers, functions, and other non-serializable objects from form state persistence
Restore form state after OAuth redirects by checking URL restore params with getRestoreParamsFromUrl(), retrieving saved state with getFormState(), restoring to form, clearing saved state with clearFormState(), and clearing URL params with clearRestoreParamsFromUrl()
For temporary File object storage during OAuth flows (e.g., pending PDFs), use projectStore.setPendingProjectData() instead of IndexedDB, as File objects cannot be serialized
Add restore parameters to the URL after OAuth redirects in the format '?restore=&projectId=' to signal form state restoration on mount
Clear URL restore parameters after form state restoration by calling clearRestoreParamsFromUrl() to prevent stale restoration attempts on subsequent navigation
Form state persistence library functions (saveFormState, getFormState, clearFormState, getRestoreParamsFromUrl, clearRestoreParamsFromUrl) are implemented in packages/web/src/lib/formStatePersistence.js and should be imported from @/lib/formStatePersistence.js

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)

packages/web/src/**/*.{js,jsx,ts,tsx}: Always use uploadPdf from @api/pdf-api.js for uploading PDF files. Pass object with projectId, studyId, tag ('primary' or 'supplementary'), and fileName
Validate PDF files on frontend by checking file.type includes 'pdf' and file.size is within MAX_PDF_SIZE limit (full validation is done on backend)
Use cachePdf and getCachedPdf from @primitives/pdfCache.js for caching PDF data in IndexedDB
Implement PDF caching strategy: check cache first, download from server if not cached, then cache the downloaded PDF
Store only PDF metadata in Yjs (id, name, size, tag, uploadedAt, uploadedBy), never store PDF binary data in Yjs as it is too large
Use importFromGoogleDrive from @api/google-drive.js for importing PDFs from Google Drive. Pass fileId, projectId, studyId, and tag
Save form state using saveFormState from @/lib/formStatePersistence.js before triggering OAuth redirects for Google Drive
Use addPdfToStudy operation from useProject hook to add PDFs to a study, passing id, name, size, tag, uploadedAt, and uploadedBy
Use removePdfFromStudy operation from useProject hook to remove PDFs from a study
Use pdfPreviewStore from @/stores/pdfPreviewStore.js for managing PDF preview state (openPreview, closePreview, getPreview methods)
Use downloadPdf from @api/pdf-api.js to download PDFs from server, then cache the result using cachePdf
Always cache PDFs after download and check cache before downloading to avoid redundant downloads
Use PDF operations from useProject hook instead of bypassing through direct API calls

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)

Use PdfViewer component from @/components/checklist-ui/pdf/PdfViewer.jsx for displaying PDFs, passing pdfData as ArrayBuffer, fileName, readOnly, and onPageChange

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
{packages/web/**,packages/landing/**}/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{jsx,tsx}: NEVER destructure props in SolidJS components - access props directly or wrap in functions to maintain reactivity
Use external stores in packages/web/src/stores/ for shared/cross-feature state instead of prop-drilling
Keep SolidJS components lean and focused on rendering - move business logic to stores, primitives, or utilities
Create reusable logic in primitives (hooks) in packages/web/src/primitives/ and import them into components
Use Solid's Show component for conditional rendering instead of ternary operators
Use Solid's For component for rendering lists instead of Array.map()
Use the children helper when manipulating props.children in SolidJS components

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}: Use createSignal for simple reactive values in SolidJS components
Use createStore for complex objects and arrays that need granular reactivity in SolidJS
Use createMemo for computed/derived values that depend on reactive state in SolidJS
Always clean up SolidJS effects that create subscriptions or timers using onCleanup
Import stores directly in components and use store read/write action pattern - read from store, write via actions store
Prefer derived state with createMemo or signals over effects whenever possible
Use local createSignal or createStore for local component state; use external stores for shared/cross-feature state

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/{web,ui}/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

packages/{web,ui}/**/*.{js,jsx,ts,tsx}: Import UI components from '@corates/ui' package instead of local components directories
Use solid-icons library for icons instead of emojis or other icon sources
Use Tailwind CSS classes for styling UI components
Apply responsive design using mobile-first approach with Tailwind CSS

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

Use import aliases from jsconfig.json (e.g., @/, @components/, @auth-ui/, @checklist-ui/, @project-ui/, @routes/, @primitives/, @api/, @config/, @lib/) instead of relative paths

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/yjs-sync.mdc)

**/*.{js,jsx,ts,tsx}: Use the useProject hook for managing Yjs connections with reference counting instead of creating Y.Doc instances directly
Never create Y.Doc instances directly; always use the connection registry managed by useProject
Access Y.Doc connection state via projectStore.getConnectionState(projectId) instead of checking connection state directly
Read Yjs-synced data from projectStore (using getStudies, getChecklist, etc.) rather than accessing Y.Doc maps/arrays directly
Use operation functions from useProject or projectActionsStore for writing data instead of directly modifying Y.Doc
Don't store Y.Doc references in component state; always retrieve the connection through useProject
Handle connection cleanup via onCleanup() in Solid.js components or equivalent cleanup patterns, calling disconnect() when the component unmounts

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*: NEVER use emojis anywhere - not in code, comments, documentation, plan files, commit messages, or examples
Do NOT use unicode symbols - unicode symbols are forbidden anywhere in the codebase

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,jsx,js}: For UI icons, use solid-icons library or SVGs only (never emojis)
Prefer modern ES6+ syntax and features
Use import aliases from jsconfig.json as defined in the ui-components.mdc documentation
Prefer config files over hardcoding values
Ensure browser compatibility (Safari is usually problematic)
Group related components in subdirectories with barrel exports
Use Ark UI components from @corates/ui package, not local component implementations
Use solid-icons icon library (e.g., solid-icons/bi, solid-icons/fi) for icons
Comments should explain WHY something is being done, not WHAT the code is doing
Comment to explain why a particular approach or workaround was chosen
Comment to clarify intent when code could be misread or misunderstood
Comment to provide context from external systems, specs, or requirements
Comment to document assumptions, edge cases, or limitations
Do NOT comment by narrating what the code is doing
Do NOT duplicate function or variable names in plain English comments
Do NOT leave stale comments that contradict the code
Do NOT reference removed or obsolete code paths in comments

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/**/*.{ts,tsx,jsx}: Do NOT prop-drill application state in SolidJS - import stores directly where needed
Do NOT destructure props in SolidJS - access props.field directly or wrap in function: () => props.field
SolidJS components should receive at most 1-5 props (local config only, not shared state)
Move business logic to stores, utilities, or primitives (not in components) in SolidJS

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

For UI icons, use solid-icons library or SVGs only (never emojis)

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

Prefer modern ES6+ syntax and features

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

packages/web/src/**/*.{ts,tsx,jsx}: Use import aliases from jsconfig.json
Use Ark UI components from @corates/ui package, NOT local components
Do NOT prop-drill application state; import stores directly where needed
Use createMemo for derived values
Move business logic to stores, utilities, or primitives (not components)

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
packages/web/src/components/**/*.{ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

packages/web/src/components/**/*.{ts,tsx,jsx}: Group related components in subdirectories with barrel exports
Do NOT destructure props; access props.field directly or wrap in function: () => props.field
Components should receive at most 1-5 props (local config only, not shared state)

Files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
{packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js,packages/web/src/AMSTAR2/checklist-compare.js}

📄 CodeRabbit inference engine (.cursor/rules/reconciliation.mdc)

Store final answers in the reconciled checklist itself, not in reconciliation progress metadata

Files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
packages/web/src/components/checklist-ui/compare/**

📄 CodeRabbit inference engine (.cursor/rules/reconciliation.mdc)

packages/web/src/components/checklist-ui/compare/**: Use MultiPartQuestionPage component for multi-part questions (q9 and q11)
Use SingleQuestionPage component for standard single-part questions (q1-q8, q10, q12-q16)
Use multiPartAnswersEqual helper to compare multi-part answers between reviewers
Auto-fill final answer with reviewer1's answer when reviewers agree and no final answer exists
Use Y.Text objects for collaborative editing of question notes in reconciliation

Files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
{packages/web/src/components/checklist-ui/compare/**,packages/web/src/AMSTAR2/checklist-compare.js}

📄 CodeRabbit inference engine (.cursor/rules/reconciliation.mdc)

Use compareChecklists utility from checklist-compare.js for comparing reviewer checklists

Files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
{packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js}

📄 CodeRabbit inference engine (.cursor/rules/reconciliation.mdc)

{packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js}: Store reconciliation progress metadata (IDs and optional currentPage) in the study's Y.Map reconciliation property
Multi-part answers (q9a, q9b, q11a, q11b) should be stored as objects with answer matrix and critical flag properties

Files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
🧠 Learnings (33)
📓 Common learnings
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Checklist status transitions follow sequence: in_progress → completed (when all questions answered) → reconciled (after reconciliation complete)
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Use scoreChecklist utility from @/AMSTAR2/checklist.js to determine quality assessment rating: 'High' | 'Moderate' | 'Low' | 'Critically Low'
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Handle multi-part AMSTAR2 questions correctly: q9 (parts a, b), q11 (parts a, b) require separate answer entries
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/AMSTAR2/checklist-compare.js} : Use compareChecklists utility from checklist-compare.js for comparing reviewer checklists
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js,packages/web/src/AMSTAR2/checklist-compare.js} : Store final answers in the reconciled checklist itself, not in reconciliation progress metadata
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Use getChecklistStatus utility from @/lib/checklist-domain.js to determine current checklist status before performing operations
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : AMSTAR2 answers must use matrix format: array of column arrays with boolean values representing checkbox selections per column
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/ROBINS-I/** : Use scoreChecklist utility from @/ROBINS-I/checklist.js to determine risk of bias rating: 'Low' | 'Moderate' | 'Serious' | 'Critical'
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Maintain separate answer format implementations for each checklist type (AMSTAR2, ROBINS-I, Generic) to prevent data corruption
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js,packages/web/src/primitives/useProject/checklists.js : Use checklist operations from useProject hook (createChecklist, updateChecklistAnswer, getChecklistData) instead of manually updating checklist structure
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{jsx,tsx} : Use `PdfViewer` component from `@/components/checklist-ui/pdf/PdfViewer.jsx` for displaying PDFs, passing pdfData as ArrayBuffer, fileName, readOnly, and onPageChange

Applied to files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/AMSTAR2/checklist-compare.js} : Use compareChecklists utility from checklist-compare.js for comparing reviewer checklists

Applied to files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T15:42:01.068Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-27T15:42:01.068Z
Learning: Applies to **/*.{ts,tsx,jsx,js} : Comment to provide context from external systems, specs, or requirements

Applied to files:

  • packages/web/src/components/checklist-ui/SplitScreenLayout.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js} : Store reconciliation progress metadata (IDs and optional currentPage) in the study's Y.Map reconciliation property

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/components/checklist-ui/compare/**,packages/web/src/lib/checklist-domain.js,packages/web/src/AMSTAR2/checklist-compare.js} : Store final answers in the reconciled checklist itself, not in reconciliation progress metadata

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `addPdfToStudy` operation from `useProject` hook to add PDFs to a study, passing id, name, size, tag, uploadedAt, and uploadedBy

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Always use `uploadPdf` from `api/pdf-api.js` for uploading PDF files. Pass object with projectId, studyId, tag ('primary' or 'supplementary'), and fileName

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use PDF operations from `useProject` hook instead of bypassing through direct API calls

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to {packages/web/src/lib/checklist-domain.js,packages/web/src/AMSTAR2/checklist-compare.js} : Reconciliation structure should contain checklist1Id, checklist2Id, and reconciledChecklistId

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `removePdfFromStudy` operation from `useProject` hook to remove PDFs from a study

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `pdfPreviewStore` from `@/stores/pdfPreviewStore.js` for managing PDF preview state (openPreview, closePreview, getPreview methods)

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Use getChecklistStatus utility from @/lib/checklist-domain.js to determine current checklist status before performing operations

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `downloadPdf` from `api/pdf-api.js` to download PDFs from server, then cache the result using `cachePdf`

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/lib/checklist-domain.js : Register and retrieve checklists using checklist-registry: getChecklistType and getChecklistComponent functions

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:05.939Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.939Z
Learning: Applies to packages/web/src/**/*.{js,jsx,ts,tsx} : Use `cachePdf` and `getCachedPdf` from `primitives/pdfCache.js` for caching PDF data in IndexedDB

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js,packages/web/src/primitives/useProject/checklists.js : Use checklist operations from useProject hook (createChecklist, updateChecklistAnswer, getChecklistData) instead of manually updating checklist structure

Applied to files:

  • packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx
  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/primitives/useProject/checklists.js : Store question notes as Y.Text objects obtained from useProject hook via getQuestionNote operation to enable collaborative editing

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:54.715Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/form-state.mdc:0-0
Timestamp: 2025-12-27T03:01:54.715Z
Learning: Applies to packages/web/src/components/project-ui/**/*.{js,jsx} : Form state should include serializable metadata when handling files (name, size, type) and use the store's pendingPdfs pattern for actual File objects that persist across redirects

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
📚 Learning: 2025-12-27T03:02:14.843Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.843Z
Learning: Applies to packages/web/src/components/checklist-ui/compare/** : Use Y.Text objects for collaborative editing of question notes in reconciliation

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx
  • packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createMemo for computed/derived values that depend on reactive state in SolidJS

Applied to files:

  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Prefer derived state with createMemo or signals over effects whenever possible

Applied to files:

  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Keep SolidJS components lean and focused on rendering - move business logic to stores, primitives, or utilities

Applied to files:

  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
📚 Learning: 2025-12-27T15:42:01.068Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-27T15:42:01.068Z
Learning: Applies to packages/web/**/*.{ts,tsx} : Use `createMemo` for derived values in SolidJS

Applied to files:

  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Use Solid's Show component for conditional rendering instead of ternary operators

Applied to files:

  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
📚 Learning: 2025-12-27T03:02:26.927Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.927Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createSignal for simple reactive values in SolidJS components

Applied to files:

  • packages/web/src/components/checklist-ui/SplitPanelControls.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Checklist status transitions follow sequence: in_progress → completed (when all questions answered) → reconciled (after reconciliation complete)

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Use scoreChecklist utility from @/AMSTAR2/checklist.js to determine quality assessment rating: 'High' | 'Moderate' | 'Low' | 'Critically Low'

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/** : Handle multi-part AMSTAR2 questions correctly: q9 (parts a, b), q11 (parts a, b) require separate answer entries

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:02:50.075Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.075Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Read Yjs-synced data from projectStore (using getStudies, getChecklist, etc.) rather than accessing Y.Doc maps/arrays directly

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/ROBINS-I/** : Use scoreChecklist utility from @/ROBINS-I/checklist.js to determine risk of bias rating: 'Low' | 'Moderate' | 'Serious' | 'Critical'

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/ROBINS-I/** : Use shouldStopAssessment utility from @/ROBINS-I/checklist.js to check if Section B indicates critical risk of bias requiring assessment termination

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.918Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.918Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/AMSTAR2/**,packages/web/src/ROBINS-I/**,packages/web/src/lib/checklist-domain.js : Maintain separate answer format implementations for each checklist type (AMSTAR2, ROBINS-I, Generic) to prevent data corruption

Applied to files:

  • packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx
🧬 Code graph analysis (2)
packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx (5)
packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (3)
  • pdfUrl (331-335)
  • pdfFileName (26-26)
  • params (19-19)
packages/web/src/components/checklist-ui/SplitPanelControls.jsx (1)
  • pdfUrl (61-64)
packages/web/src/components/checklist-ui/LocalChecklistView.jsx (2)
  • pdfFileName (25-25)
  • params (19-19)
packages/web/src/api/pdf-api.js (1)
  • getPdfUrl (102-104)
packages/web/src/components/project-ui/ProjectView.jsx (1)
  • params (34-34)
packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (3)
packages/web/src/components/sidebar/Sidebar.jsx (1)
  • location (19-19)
packages/web/src/AMSTAR2/checklist.js (1)
  • isAMSTAR2Complete (208-246)
packages/web/src/api/pdf-api.js (1)
  • getPdfUrl (102-104)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (10)
packages/web/src/components/checklist-ui/ChecklistWithPdf.jsx (1)

27-27: LGTM! Clean prop pass-through.

The pdfUrl prop addition and propagation to SplitScreenLayout is straightforward and aligns with the PDF URL flow established across the PR.

Also applies to: 37-38

packages/web/src/components/checklist-ui/SplitScreenLayout.jsx (1)

15-16: LGTM! Clear documentation and prop forwarding.

The documentation comments explain the purpose of the new props, and the forwarding to SplitPanelControls is consistent with the component's pass-through pattern.

Also applies to: 97-98

packages/web/src/components/checklist-ui/compare/ReconciliationWithPdf.jsx (2)

87-87: Verify the hardcoded false for showSecondPanel.

The PDF panel visibility is now hardcoded to false, replacing the previous dynamic hasPdf() check. This means the PDF panel won't be shown by default even when a PDF is available. If this is intentional (e.g., to give users more workspace initially), consider adding a comment explaining the design decision.


90-91: LGTM! PDF URL and data forwarding.

The pdfUrl and pdfData props are correctly forwarded to SplitScreenLayout, enabling the PDF viewer integration.

packages/web/src/components/checklist-ui/compare/ReconciliationWrapper.jsx (1)

153-158: LGTM! Clean PDF URL generation.

The memo correctly derives the PDF URL from the current pdfFileName, and the null check prevents unnecessary URL generation. The pattern aligns with similar implementations in ChecklistYjsWrapper.jsx.

packages/web/src/components/checklist-ui/SplitPanelControls.jsx (1)

130-146: LGTM! External link UI for PDF.

The "Open in new tab" button provides good UX for viewing PDFs externally. The conditional rendering based on hasPdf() is appropriate.

packages/web/src/components/checklist-ui/ChecklistYjsWrapper.jsx (4)

267-274: LGTM! Excellent safety validation before completion.

The validation check prevents users from marking incomplete AMSTAR2 checklists as complete, with a clear error message. This aligns with the completeness requirements and improves data quality.


317-328: LGTM! Clean validation logic.

The isChecklistValid memo correctly delegates to isAMSTAR2Complete for AMSTAR2 checklists and allows completion for other checklist types by default. The pattern is clear and maintainable.


330-335: LGTM! PDF URL generation.

The pdfUrl memo correctly derives the URL from pdfFileName using getPdfUrl, with appropriate null handling.


379-389: LGTM! Enhanced UX with disabled state.

The disabled state, tooltip, and visual styling provide clear feedback when the checklist cannot be completed. The tooltip message explains the requirement, improving user understanding.

Comment on lines +26 to +76
// Track blob URL separately for cleanup
let blobUrlRef = null;

// Manage blob URL lifecycle with effect
createEffect(() => {
const pdfUrl = props.pdfUrl;
const pdfData = props.pdfData;

// Clean up previous blob URL
if (blobUrlRef) {
try {
URL.revokeObjectURL(blobUrlRef);
} catch (_err) {
// Ignore errors during cleanup
}
blobUrlRef = null;
}

// If we have a server URL, no blob URL needed
if (pdfUrl) {
return;
}

// If we have PDF data, create a blob URL
if (pdfData) {
try {
const blob = new Blob([pdfData], { type: 'application/pdf' });
blobUrlRef = URL.createObjectURL(blob);
} catch (_err) {
console.warn('Failed to create blob URL from PDF data:', _err);
}
}
});

// Get the effective PDF URL (server URL or blob URL)
const pdfUrl = createMemo(() => {
if (props.pdfUrl) return props.pdfUrl;
return blobUrlRef || null;
});

// Clean up blob URLs on unmount
onCleanup(() => {
if (blobUrlRef) {
try {
URL.revokeObjectURL(blobUrlRef);
} catch (_err) {
// Ignore errors during cleanup
}
blobUrlRef = null;
}
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical reactivity issue with blobUrlRef.

The blobUrlRef variable (line 27) is not reactive, which breaks the reactivity chain:

  1. When props.pdfData changes, the effect (lines 30-58) runs and updates blobUrlRef
  2. However, the pdfUrl memo (lines 61-64) won't re-run because blobUrlRef is not a signal
  3. The UI will display stale blob URLs or fail to update when PDF data changes

Solution: Use a signal for blob URL management:

-  let blobUrlRef = null;
+  const [blobUrl, setBlobUrl] = createSignal(null);

   createEffect(() => {
     const pdfUrl = props.pdfUrl;
     const pdfData = props.pdfData;

-    if (blobUrlRef) {
+    const currentBlobUrl = blobUrl();
+    if (currentBlobUrl) {
       try {
-        URL.revokeObjectURL(blobUrlRef);
+        URL.revokeObjectURL(currentBlobUrl);
       } catch (_err) {
         // Ignore errors during cleanup
       }
-      blobUrlRef = null;
+      setBlobUrl(null);
     }

     if (pdfUrl) {
       return;
     }

     if (pdfData) {
       try {
         const blob = new Blob([pdfData], { type: 'application/pdf' });
-        blobUrlRef = URL.createObjectURL(blob);
+        setBlobUrl(URL.createObjectURL(blob));
       } catch (_err) {
         console.warn('Failed to create blob URL from PDF data:', _err);
       }
     }
   });

   const pdfUrl = createMemo(() => {
     if (props.pdfUrl) return props.pdfUrl;
-    return blobUrlRef || null;
+    return blobUrl() || null;
   });

   onCleanup(() => {
-    if (blobUrlRef) {
+    const currentBlobUrl = blobUrl();
+    if (currentBlobUrl) {
       try {
-        URL.revokeObjectURL(blobUrlRef);
+        URL.revokeObjectURL(currentBlobUrl);
       } catch (_err) {
         // Ignore errors during cleanup
       }
-      blobUrlRef = null;
+      setBlobUrl(null);
     }
   });
Proposed fix for reactivity
-  // Track blob URL separately for cleanup
-  let blobUrlRef = null;
+  // Track blob URL with signal for reactivity
+  const [blobUrl, setBlobUrl] = createSignal(null);

   // Manage blob URL lifecycle with effect
   createEffect(() => {
     const pdfUrl = props.pdfUrl;
     const pdfData = props.pdfData;

     // Clean up previous blob URL
-    if (blobUrlRef) {
+    const currentBlobUrl = blobUrl();
+    if (currentBlobUrl) {
       try {
-        URL.revokeObjectURL(blobUrlRef);
+        URL.revokeObjectURL(currentBlobUrl);
       } catch (_err) {
         // Ignore errors during cleanup
       }
-      blobUrlRef = null;
+      setBlobUrl(null);
     }

     // If we have a server URL, no blob URL needed
     if (pdfUrl) {
       return;
     }

     // If we have PDF data, create a blob URL
     if (pdfData) {
       try {
         const blob = new Blob([pdfData], { type: 'application/pdf' });
-        blobUrlRef = URL.createObjectURL(blob);
+        setBlobUrl(URL.createObjectURL(blob));
       } catch (_err) {
         console.warn('Failed to create blob URL from PDF data:', _err);
       }
     }
   });

   // Get the effective PDF URL (server URL or blob URL)
   const pdfUrl = createMemo(() => {
     if (props.pdfUrl) return props.pdfUrl;
-    return blobUrlRef || null;
+    return blobUrl() || null;
   });

   // Clean up blob URLs on unmount
   onCleanup(() => {
-    if (blobUrlRef) {
+    const currentBlobUrl = blobUrl();
+    if (currentBlobUrl) {
       try {
-        URL.revokeObjectURL(blobUrlRef);
+        URL.revokeObjectURL(currentBlobUrl);
       } catch (_err) {
         // Ignore errors during cleanup
       }
-      blobUrlRef = null;
+      setBlobUrl(null);
     }
   });

Based on learnings: SolidJS reactivity requires signals for values that need to trigger re-renders.

🤖 Prompt for AI Agents
In packages/web/src/components/checklist-ui/SplitPanelControls.jsx around lines
26 to 76, blobUrlRef is a plain variable so updates don't trigger reactivity and
pdfUrl memo won't update; replace blobUrlRef with a Solid signal (createSignal)
and use its setter inside the effect to set and clear the blob URL (store the
previous URL in a local var for revocation when creating a new one), update the
pdfUrl createMemo to read the signal value instead of the plain variable, ensure
all URL.revokeObjectURL calls revoke the current signal value and then set the
signal to null in both the effect cleanup and onCleanup, and import createSignal
where necessary; keep try/catch around Blob/createObjectURL and revoke calls as
before.

@InfinityBowman InfinityBowman merged commit 60d389e into main Dec 27, 2025
1 of 3 checks passed
@InfinityBowman InfinityBowman deleted the 175-fix-complete-checklist-reconcile branch December 27, 2025 16:38
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/components/checklist/compare/ReconciliationWithPdf.jsx (1)

49-49: hasPdf memo doesn't account for pdfUrl prop.

The hasPdf memo only checks props.pdfData and props.pdfLoading, but doesn't consider props.pdfUrl. If a server-hosted PDF URL is provided without local pdfData, the PDF viewer panel will be incorrectly hidden.

Proposed fix
   // Check if we have PDF to show (reactive)
-  const hasPdf = createMemo(() => !!(props.pdfData || props.pdfLoading));
+  const hasPdf = createMemo(() => !!(props.pdfUrl || props.pdfData || props.pdfLoading));
♻️ Duplicate comments (1)
packages/web/src/components/checklist/SplitPanelControls.jsx (1)

26-76: Critical reactivity issue with blobUrlRef remains unaddressed.

As flagged in a previous review, blobUrlRef is a plain variable, not a signal. The pdfUrl memo (lines 61-64) reads blobUrlRef but won't re-run when its value changes because plain variables don't trigger reactivity in SolidJS. This means the UI will display stale blob URLs when props.pdfData changes.

Use createSignal instead of a plain variable.

🧹 Nitpick comments (2)
packages/web/src/Routes.jsx (1)

3-21: Import paths correctly updated, with minor style inconsistency.

The import paths have been properly updated to the new @/components/ pattern. Note that lines 16-17 use @components/ while other imports use @/components/ - both are valid per jsconfig.json, but consider using a consistent style throughout.

Optional: Consistent import style
-import BillingPage from '@components/billing/BillingPage.jsx';
-import NotFoundPage from '@components/NotFoundPage.jsx';
+import BillingPage from '@/components/billing/BillingPage.jsx';
+import NotFoundPage from '@/components/NotFoundPage.jsx';
packages/web/src/components/checklist/ChecklistYjsWrapper.jsx (1)

337-342: Remove commented-out debug code.

Line 339 contains a commented-out console.log statement that should be removed before merging.

Proposed fix
   // Determine back button navigation from tab query param
   const getBackTab = () => {
-    // console.log('location', location.search);
     const tabFromUrl = new URLSearchParams(location.search).get('tab');
     return tabFromUrl || 'overview';
   };

Comment on lines +71 to +88
export function ScoreTooltip(props) {
const infoUrl = createMemo(() => getInfoUrl(props.checklistType));
const tooltipContent = createMemo(() => getTooltipContent(props.checklistType));

return (
<Tooltip content={tooltipContent()} placement='bottom' openDelay={200}>
<a
href={infoUrl()}
target='_blank'
rel='noreferrer'
class='mt-0.5 inline-flex items-center justify-center rounded-full p-0.5 opacity-70 hover:opacity-100 focus:opacity-100 focus:ring-2 focus:ring-blue-500 focus:outline-none'
aria-label={`Open ${getChecklistMetadata(props.checklistType).name} guidance in a new tab`}
>
<FaSolidCircleInfo size={12} />
</a>
</Tooltip>
);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix reactivity issue in aria-label.

Line 82 directly accesses props.checklistType inside an expression, which breaks SolidJS reactivity. Prop access in JSX must be wrapped in a function or computed via a memo.

Proposed fix

Create a memo for the metadata and use it in the aria-label:

 export function ScoreTooltip(props) {
   const infoUrl = createMemo(() => getInfoUrl(props.checklistType));
   const tooltipContent = createMemo(() => getTooltipContent(props.checklistType));
+  const metadata = createMemo(() => getChecklistMetadata(props.checklistType));
 
   return (
     <Tooltip content={tooltipContent()} placement='bottom' openDelay={200}>
       <a
         href={infoUrl()}
         target='_blank'
         rel='noreferrer'
         class='mt-0.5 inline-flex items-center justify-center rounded-full p-0.5 opacity-70 hover:opacity-100 focus:opacity-100 focus:ring-2 focus:ring-blue-500 focus:outline-none'
-        aria-label={`Open ${getChecklistMetadata(props.checklistType).name} guidance in a new tab`}
+        aria-label={`Open ${metadata().name} guidance in a new tab`}
       >
         <FaSolidCircleInfo size={12} />
       </a>
     </Tooltip>
   );
 }
🤖 Prompt for AI Agents
In packages/web/src/components/checklist/ScoreTag.jsx around lines 71 to 88, the
aria-label accesses props.checklistType directly which breaks SolidJS
reactivity; wrap the derived metadata in a memo and use that memo in the
aria-label. Create a createMemo (e.g., const metadata = createMemo(() =>
getChecklistMetadata(props.checklistType))) alongside the existing memos and
replace getChecklistMetadata(props.checklistType).name usage with
metadata().name so the aria-label reads the reactive memo value rather than
directly accessing the prop.

Comment on lines +14 to +16
'@auth': path.resolve(__dirname, 'src/components/auth'),
'@checklist': path.resolve(__dirname, 'src/components/checklist'),
'@project': path.resolve(__dirname, 'src/components/project'),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cat -n packages/web/vite.config.js | head -30

Repository: InfinityBowman/corates

Length of output: 1463


🏁 Script executed:

cat -n packages/web/jsconfig.json

Repository: InfinityBowman/corates

Length of output: 745


🏁 Script executed:

# Check for imports using both old and new alias patterns
echo "=== Searching for old @auth-ui imports ==="
rg '@auth-ui' packages/web/src --type=js --type=jsx --type=ts --type=tsx | head -20

echo "=== Searching for new @auth imports ==="
rg "from ['\"]@auth" packages/web/src --type=js --type=jsx --type=ts --type=tsx | head -20

echo "=== Searching for old @checklist-ui imports ==="
rg '@checklist-ui' packages/web/src --type=js --type=jsx --type=ts --type=tsx | head -20

echo "=== Searching for new @checklist imports ==="
rg "from ['\"]@checklist" packages/web/src --type=js --type=jsx --type=ts --type=tsx | head -20

echo "=== Searching for old @project-ui imports ==="
rg '@project-ui' packages/web/src --type=js --type=jsx --type=ts --type=tsx | head -20

echo "=== Searching for new @project imports ==="
rg "from ['\"]@project" packages/web/src --type=js --type=jsx --type=ts --type=tsx | head -20

Repository: InfinityBowman/corates

Length of output: 515


🏁 Script executed:

# Search for any imports using new aliases
echo "=== Searching for @auth imports (any case) ==="
rg '@auth' packages/web/src --max-count=10

echo "=== Searching for @checklist imports ==="
rg '@checklist' packages/web/src --max-count=10

echo "=== Searching for @project imports ==="
rg '@project' packages/web/src --max-count=10

echo "=== Searching for @auth-ui imports ==="
rg '@auth-ui' packages/web/src --max-count=10

echo "=== Searching for @checklist-ui imports ==="
rg '@checklist-ui' packages/web/src --max-count=10

echo "=== Searching for @project-ui imports ==="
rg '@project-ui' packages/web/src --max-count=10

Repository: InfinityBowman/corates

Length of output: 317


🏁 Script executed:

# Check what the learnings reference for correct alias patterns
echo "=== Checking cursor rules file for alias definitions ==="
cat packages/web/.cursor/rules/ui-components.mdc 2>/dev/null | head -50

Repository: InfinityBowman/corates

Length of output: 122


🏁 Script executed:

# Find the cursor rules file location
find . -name "ui-components.mdc" -o -name "*rules*" -type f | grep -v node_modules | head -20

Repository: InfinityBowman/corates

Length of output: 99


🏁 Script executed:

# Search for actual import statements to see what patterns are used
echo "=== Sample imports from components ==="
fd -e js -e jsx -e ts -e tsx packages/web/src | head -5 | xargs -I {} head -20 {}

echo "=== Check for relative path imports in components ==="
rg "from ['\"]\.\./" packages/web/src/components --max-count=5

Repository: InfinityBowman/corates

Length of output: 2003


🏁 Script executed:

# Check if the rules file exists at the path mentioned in learnings
ls -la packages/web/.cursor/rules/ 2>/dev/null || echo "Directory not found"
cat .cursor/rules/ui-components.mdc 2>/dev/null | head -100

Repository: InfinityBowman/corates

Length of output: 2853


🏁 Script executed:

# Get more of the cursor rules file to understand the full context
cat .cursor/rules/ui-components.mdc | grep -A 5 -B 5 "@auth\|@checklist\|@project"

Repository: InfinityBowman/corates

Length of output: 808


Alias definitions are incorrect and don't match project standards.

The aliases in vite.config.js and jsconfig.json are missing the -ui suffix and pointing to wrong directory names. According to .cursor/rules/ui-components.mdc, the correct aliases should be:

  • @auth-ui/*src/components/auth-ui/*
  • @checklist-ui/*src/components/checklist-ui/*
  • @project-ui/*src/components/project-ui/*

Fix the aliases in both vite.config.js (lines 14-16) and jsconfig.json (lines 7-9) to match the documented standards.

🤖 Prompt for AI Agents
In packages/web/vite.config.js around lines 14-16 and jsconfig.json around lines
7-9, the alias keys and target paths are incorrect; update each alias to include
the -ui suffix and point to the corresponding -ui directories with wildcard
mapping. Specifically, replace '@auth' -> '@auth-ui/*' mapping to
'src/components/auth-ui/*', '@checklist' -> '@checklist-ui/*' to
'src/components/checklist-ui/*', and '@project' -> '@project-ui/*' to
'src/components/project-ui/*' so both vite.config.js and jsconfig.json match the
.cursor/rules/ui-components.mdc standard.

This was referenced Jan 3, 2026
This was referenced Jan 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Button to open pdf in new tab Fix complete checklist reconcile Cannot mark checklist complete with missing fields

1 participant