add presence#322
Conversation
📝 WalkthroughWalkthroughAdds real-time presence to reconciliation views: new UI components (avatars, pulsing rings, remote cursors), a presence hook using Yjs awareness, deterministic user color utilities, and wiring across reconciliation pages to surface who is viewing and where cursors are. Changes
Sequence DiagramsequenceDiagram
participant Local as Local Client
participant Awareness as Yjs Awareness
participant Hook as useReconciliationPresence
participant UI as Presence UI (Avatars/Cursors/Pills)
participant Remote as Remote Client
Local->>Awareness: publish local awareness (page, cursor, metadata)
Awareness-->>Hook: awareness change event
activate Hook
Hook->>Hook: filter by checklistType, group usersByPage, compute visibleUsers
Hook->>UI: emit remoteUsers, usersByPage, container scroll updates
deactivate Hook
UI->>UI: render PresenceAvatars, QuestionPresenceIndicator, RemoteCursors (positioned by scroll)
Remote->>Awareness: publish remote awareness (page, cursor)
Awareness-->>Hook: awareness change event
activate Hook
Hook->>UI: update cursors/avatars (stale detection/throttling applied)
deactivate Hook
UI->>Local: user clicks avatar -> navigate to target page (via navbarStore)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
✏️ Tip: You can disable this entire section by setting Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
corates | 0e33c25 | Commit Preview URL | Jan 24 2026, 07:04 PM |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@packages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsx`:
- Around line 19-21: visibleUsers calls props.users.slice and other spots read
props.users.length without guarding for undefined; update visibleUsers (and any
other uses like length checks around lines referenced) to treat users as an
empty array when absent (e.g., use props.users ?? [] or a local const users =
props.users ?? [] and then use users.slice and users.length) so .slice and
.length never throw during initial load; reference visibleUsers and maxRings
when making the change.
🧹 Nitpick comments (2)
packages/web/src/components/project/reconcile-tab/PresenceAvatars.jsx (2)
69-74: Redundant background-color styling on AvatarFallback.The
AvatarFallbackapplies both a Tailwind class (user.color.bg) and an inline style forbackground-color. The inline style will override the class, making the class ineffective. Consider removing the redundant class.Suggested fix
<AvatarFallback - class={`${user.color.bg} text-white`} + class='text-white' style={{ 'background-color': user.color.hex }} >
60-66: Add explicittype="button"to prevent unintended form submissions.The avatar button lacks an explicit
typeattribute. If this component is ever rendered inside a form, clicking it could trigger form submission.Suggested fix
<button + type='button' onClick={() => props.onUserClick?.(user.userId, user.currentPage)}
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
packages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/lib/userColors.jspackages/web/src/primitives/useProject/index.jspackages/web/src/primitives/useReconciliationPresence.js
🧰 Additional context used
📓 Path-based instructions (14)
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/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
packages/web/src/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)
packages/web/src/**/*.{js,jsx,ts,tsx}: Always useuploadPdffrom@api/pdf-api.jsfor 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)
UsecachePdfandgetCachedPdffrom@primitives/pdfCache.jsfor 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
UseimportFromGoogleDrivefrom@api/google-drive.jsfor importing PDFs from Google Drive. Pass fileId, projectId, studyId, and tag
Save form state usingsaveFormStatefrom@/lib/formStatePersistence.jsbefore triggering OAuth redirects for Google Drive
UseaddPdfToStudyoperation fromuseProjecthook to add PDFs to a study, passing id, name, size, tag, uploadedAt, and uploadedBy
UseremovePdfFromStudyoperation fromuseProjecthook to remove PDFs from a study
UsepdfPreviewStorefrom@/stores/pdfPreviewStore.jsfor managing PDF preview state (openPreview, closePreview, getPreview methods)
UsedownloadPdffrom@api/pdf-api.jsto download PDFs from server, then cache the result usingcachePdf
Always cache PDFs after download and check cache before downloading to avoid redundant downloads
Use PDF operations fromuseProjecthook instead of bypassing through direct API calls
Files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
{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
{packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx}: NEVER destructure props in SolidJS components - it breaks reactivity. Access props directly (e.g., props.name) or wrap in a function (e.g., () => props.name)
Store imports should access store data directly from external stores (packages/web/src/stores/) rather than receiving store data via props
Use createSignal for simple, reactive values in SolidJS
Use createStore for complex objects and nested state in SolidJS, with nested updates using setState pattern (e.g., setState('items', items => [...items, newItem]))
Use createMemo for derived/computed values in SolidJS to maintain reactivity
Use local createSignal or createStore for local component state
Components should receive at most 1-5 props for local configuration only
Move business logic to stores, utilities, or SolidJS primitives rather than keeping it in component code
Files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/yjs-sync.mdc)
**/*.{js,jsx,ts,tsx}: Use theuseProjecthook 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/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
packages/web/src/**
📄 CodeRabbit inference engine (.cursor/rules/organizations.mdc)
packages/web/src/**: Use human-readable slug in frontend URLs: /orgs/:orgSlug/...
Use orgId (UUID) for API calls, not orgSlug, when making fetch requests to backend endpoints
Files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
packages/web/**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)
packages/web/**/*.{js,ts,jsx,tsx}: UseapiFetchfor all frontend API calls instead of raw fetch to automatically handle JSON parsing, errors, and toast notifications
UsehandleFetchErrorfor wrapping legacy raw fetch calls in frontend code (legacy pattern, prefer apiFetch)
Use error utility functions likeisErrorCodefrom error-utils to check specific error types instead of direct string comparisons
Files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
packages/{web,workers}/**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)
Never throw string literals; always throw Error objects or return domain errors from API routes
Files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
{packages/web/src/stores/**/*.{js,jsx,ts,tsx},packages/web/src/**/*.{js,jsx,ts,tsx}}
📄 CodeRabbit inference engine (.github/instructions/solidjs.instructions.md)
Shared or cross-feature state should use external stores located in packages/web/src/stores/
Files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)
**/*.{js,ts,jsx,tsx}: Prefer modern ES6+ syntax and features
Comments should explain why something is being done, not what the code is doing
Reserve comments for explaining intent, context, workarounds, assumptions, edge cases, or limitations
Use TODO(agent): prefix for incomplete work or flagged items with brief description and relevant doc references
Files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
**/*
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Never use emojis or unicode symbols anywhere in code, comments, documentation, plan files, commit messages, or examples
Files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
packages/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
packages/**/*.{ts,tsx,js,jsx}: Prefer modern ES6+ syntax and features
Prefer config files over hardcoding values
Keep files small, focused, and modular - extract large files into sub-modules or separate utilities
Each file should handle one coherent responsibility
Comments should explain WHY something is being done or provide context, not repeat what the code is saying
Do NOT narrate what code is doing, don't duplicate function/variable names in comments, and don't leave stale comments that contradict the code
Use the Agent TODO convention// TODO(agent): Brief descriptionfor incomplete work, flagging items for future attention, known limitations, and documentation section referencesUse TODO(agent) convention with brief description and relevant doc section references for incomplete work or flagged issues
Files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/lib/userColors.jspackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
packages/web/src/**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/pdf-handling.mdc)
Use
PdfViewercomponent from@/components/checklist-ui/pdf/PdfViewer.jsxfor displaying PDFs, passing pdfData as ArrayBuffer, fileName, readOnly, and onPageChange
Files:
packages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.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 componentsUse Show and For components for conditional and list rendering in SolidJS
Files:
packages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
packages/web/**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)
Use
createFormErrorSignalsfor form error handling in frontend forms to manage field-level and global error states
Files:
packages/web/src/components/project/reconcile-tab/PresenceAvatars.jsxpackages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/RemoteCursors.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
🧠 Learnings (38)
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use the `useProject` hook for managing Yjs connections with reference counting instead of creating Y.Doc instances directly
Applied to files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
📚 Learning: 2025-12-27T03:01:35.601Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/durable-objects.mdc:0-0
Timestamp: 2025-12-27T03:01:35.601Z
Learning: Applies to packages/workers/src/durable-objects/**/ProjectDoc.{js,ts} : Use y-websocket protocol with message type 1 for awareness (presence) messages in ProjectDoc
Applied to files:
packages/web/src/primitives/useProject/index.jspackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/primitives/useReconciliationPresence.js
📚 Learning: 2026-01-01T23:32:17.698Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/organizations.mdc:0-0
Timestamp: 2026-01-01T23:32:17.698Z
Learning: Applies to packages/web/src/primitives/useOrg* : Use useOrgProjectContext hook to combine org and project context, providing basePath and path builder functions (getStudyPath, getChecklistPath)
Applied to files:
packages/web/src/primitives/useProject/index.js
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Access Y.Doc connection state via projectStore.getConnectionState(projectId) instead of checking connection state directly
Applied to files:
packages/web/src/primitives/useProject/index.js
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
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/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:14.854Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.854Z
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/project/reconcile-tab/QuestionPresenceIndicator.jsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/primitives/useReconciliationPresence.js
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
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/project/reconcile-tab/QuestionPresenceIndicator.jsx
📚 Learning: 2026-01-17T00:25:12.518Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/instructions/solidjs.instructions.md:0-0
Timestamp: 2026-01-17T00:25:12.518Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Use Show and For components for conditional and list rendering in SolidJS
Applied to files:
packages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsx
📚 Learning: 2025-12-27T03:02:05.951Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.951Z
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/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsx
📚 Learning: 2025-12-27T03:02:14.854Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.854Z
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/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
📚 Learning: 2025-12-27T03:02:14.854Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.854Z
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/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:05.951Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/pdf-handling.mdc:0-0
Timestamp: 2025-12-27T03:02:05.951Z
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/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsx
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
Learning: Applies to packages/web/src/components/checklist-ui/**,packages/web/src/ROBINS-I/** : ROBINS-I answers must use string format: 'Y' | 'PY' | 'PN' | 'N' | 'NI' | 'NA' with optional comment field
Applied to files:
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsx
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
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/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsxpackages/web/src/primitives/useReconciliationPresence.js
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
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/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
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/project/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsx
📚 Learning: 2025-12-27T03:02:14.854Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.854Z
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/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:14.854Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.854Z
Learning: Applies to packages/web/src/components/checklist-ui/compare/** : Use SingleQuestionPage component for standard single-part questions (q1-q8, q10, q12-q16)
Applied to files:
packages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsx
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
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/reconcile-tab/amstar2-reconcile/Navbar.jsxpackages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsx
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
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/project/reconcile-tab/amstar2-reconcile/Navbar.jsx
📚 Learning: 2025-12-27T03:02:14.854Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.854Z
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/reconcile-tab/ReconciliationWithPdf.jsx
📚 Learning: 2026-01-17T00:25:35.716Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/corates.mdc:0-0
Timestamp: 2026-01-17T00:25:35.716Z
Learning: Applies to packages/workers/src/**/*.{ts,tsx} : Use Better-Auth for authentication and user management
Applied to files:
packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use operation functions from useProject or projectActionsStore for writing data instead of directly modifying Y.Doc
Applied to files:
packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2026-01-17T16:09:36.920Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-17T16:09:36.920Z
Learning: Applies to packages/workers/src/**/*.ts : Use Better-Auth for authentication and user management
Applied to files:
packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2026-01-17T00:25:35.716Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/corates.mdc:0-0
Timestamp: 2026-01-17T00:25:35.716Z
Learning: Applies to packages/workers/src/**/*.{ts,tsx} : Use `requireOrgMembership` and `requireProjectAccess` middleware for authentication in org-scoped routes
Applied to files:
packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to packages/web/src/primitives/useProject/**, packages/web/src/stores/projectStore.js : When access is denied (user removed or project deleted), the connection automatically triggers cleanup: IndexedDB data cleared, connection closed, store cleared, and user redirected
Applied to files:
packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
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/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2026-01-17T16:09:36.920Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2026-01-17T16:09:36.920Z
Learning: Applies to packages/{web,landing}/src/**/*.{ts,tsx} : Use `createStore` for complex state objects in SolidJS
Applied to files:
packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Don't store Y.Doc references in component state; always retrieve the connection through useProject
Applied to files:
packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2026-01-17T00:25:12.518Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/instructions/solidjs.instructions.md:0-0
Timestamp: 2026-01-17T00:25:12.518Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{js,jsx,ts,tsx} : Use createStore for complex objects and nested state in SolidJS, with nested updates using setState pattern (e.g., setState('items', items => [...items, newItem]))
Applied to files:
packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:01:35.601Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/durable-objects.mdc:0-0
Timestamp: 2025-12-27T03:01:35.601Z
Learning: Applies to packages/workers/src/durable-objects/**/ProjectDoc.{js,ts} : Check user membership in project before allowing WebSocket connection in ProjectDoc
Applied to files:
packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:50.087Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/yjs-sync.mdc:0-0
Timestamp: 2025-12-27T03:02:50.087Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Never create Y.Doc instances directly; always use the connection registry managed by useProject
Applied to files:
packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
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/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
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/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:01:06.933Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/checklist-operations.mdc:0-0
Timestamp: 2025-12-27T03:01:06.933Z
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/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:14.854Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.854Z
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/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:14.854Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/reconciliation.mdc:0-0
Timestamp: 2025-12-27T03:02:14.854Z
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/components/project/reconcile-tab/ReconciliationWrapper.jsx
📚 Learning: 2025-12-27T03:02:26.947Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-27T03:02:26.947Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx} : Create reusable logic in primitives (hooks) in packages/web/src/primitives/ and import them into components
Applied to files:
packages/web/src/primitives/useReconciliationPresence.js
🧬 Code graph analysis (5)
packages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsx (2)
packages/web/src/components/project/reconcile-tab/PresenceAvatars.jsx (1)
visibleUsers(30-30)packages/web/src/lib/userColors.js (1)
index(69-69)
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsx (4)
packages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsx (3)
containerRef(50-50)containerScrollY(51-51)presence(69-75)packages/web/src/primitives/useReconciliationPresence.js (1)
useReconciliationPresence(30-251)packages/web/src/components/project/reconcile-tab/PresenceAvatars.jsx (1)
PresenceAvatars(28-108)packages/web/src/components/project/reconcile-tab/RemoteCursors.jsx (1)
RemoteCursors(44-92)
packages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsx (2)
packages/web/src/components/project/reconcile-tab/amstar2-reconcile/navbar-utils.js (1)
getQuestionTooltip(59-70)packages/web/src/components/project/reconcile-tab/QuestionPresenceIndicator.jsx (1)
QuestionPresenceIndicator(18-62)
packages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsx (4)
packages/web/src/primitives/useReconciliationPresence.js (1)
useReconciliationPresence(30-251)packages/web/src/components/project/reconcile-tab/PresenceAvatars.jsx (1)
PresenceAvatars(28-108)packages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsx (1)
Navbar(30-47)packages/web/src/components/project/reconcile-tab/RemoteCursors.jsx (1)
RemoteCursors(44-92)
packages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsx (4)
packages/web/src/components/checklist/AMSTAR2Checklist/AMSTAR2Checklist.jsx (3)
containerRef(344-344)containerRef(474-474)containerRef(677-677)packages/web/src/primitives/useReconciliationPresence.js (1)
useReconciliationPresence(30-251)packages/web/src/components/project/reconcile-tab/PresenceAvatars.jsx (1)
PresenceAvatars(28-108)packages/web/src/components/project/reconcile-tab/RemoteCursors.jsx (1)
RemoteCursors(44-92)
⏰ 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). (2)
- GitHub Check: Workers Builds: corates
- GitHub Check: prettier
🔇 Additional comments (19)
packages/web/src/primitives/useProject/index.js (1)
371-373: Awareness accessor looks good.Exposing awareness through the connection manager keeps the Yjs access centralized and guarded.
packages/web/src/lib/userColors.js (1)
67-71: Deterministic color mapping looks solid.The hash-based selection provides stable user colors with a clear fallback.
packages/web/src/components/project/reconcile-tab/RemoteCursors.jsx (1)
44-90: Cursor overlay implementation looks good.Scroll-adjusted positioning and pointer-events-none are appropriate for this overlay use case.
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsIReconciliationWithPdf.jsx (1)
69-146: Presence wiring in the reconciliation panel looks good.The container ref and scroll tracking integrate cleanly with the presence hook and cursor overlay.
packages/web/src/primitives/useReconciliationPresence.js (1)
55-206: The concern about awareness reactivity is not applicable here. The parent ProjectView callsuseProject(projectId)which automatically establishes the connection before rendering child routes. Since the connection and awareness are created synchronously duringconnect(), and ReconciliationWrapper only mounts after its parent has initialized, awareness is guaranteed to be available whenuseReconciliationPresenceruns. The early return pattern (if (!aw) return) is appropriate defensive programming. No changes needed.packages/web/src/components/project/reconcile-tab/PresenceAvatars.jsx (1)
28-51: LGTM - Clean reactive patterns.The component correctly uses reactive getters (
maxVisible,visibleUsers,overflowCount) and accesses props directly without destructuring, maintaining SolidJS reactivity. The avatar URL construction logic handles both full URLs and API paths appropriately.packages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2ReconciliationWithPdf.jsx (3)
69-76: LGTM - Presence hook integration follows correct patterns.The presence hook is correctly configured with reactive getters for all options (
getAwareness,getCurrentPage,checklistType,currentUser,containerRef). This ensures proper reactivity tracking and cleanup is handled internally by the hook viaonCleanup.
140-161: LGTM - Container and cursor overlay structure is correct.The container properly uses
relativepositioning withoverflow-auto, and theRemoteCursorsoverlay is positioned correctly within it. The scroll handler updatescontainerScrollYwhich is passed toRemoteCursorsfor proper cursor position adjustment.
108-118: LGTM - Presence avatars integration in header.The presence avatars are correctly wired to navigate to the clicked user's page via
navbarStore.goToPage. ThegetPageLabeluses "Item" which is appropriate for ROB2 terminology.packages/web/src/components/project/reconcile-tab/amstar2-reconcile/Navbar.jsx (3)
33-41: LGTM - Correct prop passing pattern for presence data.The
usersByPageMap is accessed correctly with.get(index())and falls back to an empty array. Props are accessed directly without destructuring, maintaining SolidJS reactivity.
66-74: LGTM - Tooltip enhancement with viewer names.The tooltip correctly combines base tooltip info with viewer names using a pipe separator. Using
createMemoensures efficient recomputation only when dependencies change.
85-88: LGTM - Presence indicator placement.The
QuestionPresenceIndicatoris correctly rendered only for non-current pages, avoiding visual clutter on the active page. The component placement inside the button ensures proper visual association.packages/web/src/components/project/reconcile-tab/ReconciliationWithPdf.jsx (3)
68-80: LGTM - Presence hook and scroll tracking setup.The presence hook configuration and scroll handling follow correct SolidJS patterns. All options use reactive getters, and the scroll handler properly updates
containerScrollY.
107-122: LGTM - Header presence integration.The presence avatars and navbar integration is correct. The
onUserClickcorrectly usesgoToQuestionfor AMSTAR2 navigation, andusersByPage()is properly invoked to pass the memo value.
139-162: LGTM - Container and reconciliation panel structure.The container correctly wraps the reconciliation content with the
RemoteCursorsoverlay. The structure matches the ROB2 version, ensuring consistent presence behavior across checklist types.packages/web/src/components/project/reconcile-tab/ReconciliationWrapper.jsx (4)
60-69: LGTM - Current user memo for presence.The
currentUsermemo correctly derives user information from the authenticated user, returningnullwhen not available. The structure matches whatuseReconciliationPresenceexpects (id,name,image).
513-516: LGTM - Presence props correctly passed to reconciliation components.The
getAwareness,currentUser, andchecklistTypeprops are consistently passed to all three reconciliation components. ThecurrentUseris correctly passed as a memo reference (not invoked), allowing child components to maintain reactivity.
549-551: LGTM - ROB2 presence props.Consistent with AMSTAR2, the ROB2 reconciliation receives the same presence props with the appropriate
checklistType='ROB2'.
586-588: LGTM - ROBINS_I presence props.Consistent with the other reconciliation types, ROBINS_I receives the same presence props with
checklistType='ROBINS_I'.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.