340 local checklist notes#341
Conversation
…orates into 340-rob-bug-fix
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughAdds a local Y.Text-like adapter system for checklist text fields, integrates adapter factories into LocalChecklistView (changing debounced save to read current state and clearing adapter cache on load/update/unmount), and applies minor formatting changes to auth files. Changes
Sequence DiagramsequenceDiagram
participant User
participant LocalChecklistView
participant LocalTextAdapterFactory as AdapterFactory
participant LocalTextAdapter as Adapter
participant DebouncedSave as debouncedSave
participant UpdateChecklist as updateChecklist
User->>LocalChecklistView: edit text / trigger update
LocalChecklistView->>AdapterFactory: get<...> for path (lazy)
AdapterFactory->>Adapter: return cached or new adapter
Adapter->>LocalChecklistView: adapter.change -> updateState(...)
LocalChecklistView->>AdapterFactory: clearCache() on load/update/unmount
LocalChecklistView->>debouncedSave: invoke (no args)
debouncedSave->>debouncedSave: wait (debounce)
debouncedSave->>LocalChecklistView: call getChecklist()
LocalChecklistView->>UpdateChecklist: updateChecklist(checklist)
UpdateChecklist->>Adapter: external sync (_syncValue / observers)
Adapter->>LocalChecklistView: observer notifications (value updated)
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~30 minutes Possibly Related PRs
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
✏️ 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 | 33eb6d1 | Commit Preview URL | Feb 01 2026, 12:08 AM |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@packages/web/src/components/checklist/common/LocalTextAdapter.js`:
- Around line 198-210: The forEach callbacks in _notifyUpdate and _syncValue use
concise arrow bodies causing implicit returns (lint error); update both observer
iterations in methods _notifyUpdate and _syncValue to use block arrow functions
instead (e.g., change callback => callback() to callback => { callback(); }) so
the callbacks have an explicit block body and no implicit return.
In `@packages/web/src/components/checklist/LocalChecklistView.jsx`:
- Around line 32-39: debouncedSave currently forwards only the last call's
arguments so partial updates from handleUpdate can overwrite earlier full-state
edits; change debouncedSave to always persist the component's current full
checklist state by merging incoming partial updates into the component's local
checklist state (use the component's checklist state variable) or by ignoring
args and reading the latest local state before calling
updateChecklist(params.checklistId, fullState), and apply the same change for
the other debounce usage around lines 104-115 so the backend always receives the
complete merged checklist state rather than a partial update.
🧹 Nitpick comments (1)
packages/web/src/components/checklist/LocalChecklistView.jsx (1)
215-227: Consider reducing ChecklistWithPdf prop surface.Adding more adapter props increases coupling and makes the component harder to evolve. Consider passing a single adapters object or sourcing these adapters inside ChecklistWithPdf via a store or helper.
As per coding guidelines: Components should receive at most 1-5 props for local configuration only.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/web/src/components/checklist/LocalChecklistView.jsxpackages/web/src/components/checklist/common/LocalTextAdapter.jspackages/workers/src/auth/config.tspackages/workers/src/auth/oauth-relay.ts
🧰 Additional context used
📓 Path-based instructions (18)
**/*.{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/workers/src/auth/config.tspackages/web/src/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.jsxpackages/workers/src/auth/oauth-relay.ts
packages/workers/src/**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/workers.mdc)
ALWAYS use
db.batch()for multiple related database operations in Drizzle to ensure atomicity - all operations must succeed or all fail together
Files:
packages/workers/src/auth/config.tspackages/workers/src/auth/oauth-relay.ts
packages/workers/**/*.{js,ts}
📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)
packages/workers/**/*.{js,ts}: Always usecreateDomainErrorfrom@corates/sharedfor backend error handling instead of manually creating error objects
Use predefined error constants from@corates/shared(PROJECT_ERRORS, AUTH_ERRORS, VALIDATION_ERRORS, SYSTEM_ERRORS, USER_ERRORS) instead of arbitrary error strings
Wrap database operations in try-catch blocks and return domain errors using createDomainError with SYSTEM_ERRORS.DB_ERROR
Use validation middleware (validateRequest) for request validation instead of manually validating request bodies in routes
Files:
packages/workers/src/auth/config.tspackages/workers/src/auth/oauth-relay.ts
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/workers/src/auth/config.tspackages/web/src/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.jsxpackages/workers/src/auth/oauth-relay.ts
**/*.{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/workers/src/auth/config.tspackages/web/src/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.jsxpackages/workers/src/auth/oauth-relay.ts
packages/workers/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)
packages/workers/src/**/*.{ts,tsx}: Use Zod for schema and input validation on backend services
Use Drizzle ORM for all database interactions and migrations
Use Better-Auth for authentication and user management
All project routes are org-scoped and use/api/orgs/:orgId/projects/...pattern in backend
UserequireOrgMembershipandrequireProjectAccessmiddleware for authentication in org-scoped routes
Never bypass Drizzle for database accessNever bypass Drizzle for database access - use Drizzle ORM for all database operations
Files:
packages/workers/src/auth/config.tspackages/workers/src/auth/oauth-relay.ts
**/*
📄 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/workers/src/auth/config.tspackages/web/src/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.jsxpackages/workers/src/auth/oauth-relay.ts
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/workers/src/auth/config.tspackages/web/src/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.jsxpackages/workers/src/auth/oauth-relay.ts
packages/workers/src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
packages/workers/src/**/*.ts: Use Zod for schema and input validation in backend code
Use Drizzle ORM for ALL database interactions and migrations
Use Better-Auth for authentication and user management
Never bypass Drizzle for database access
Files:
packages/workers/src/auth/config.tspackages/workers/src/auth/oauth-relay.ts
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/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.jsx
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/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.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
{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/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.jsx
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/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.jsx
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/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.jsx
{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/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.jsx
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/checklist/LocalChecklistView.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/checklist/LocalChecklistView.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/checklist/LocalChecklistView.jsx
🧠 Learnings (31)
📓 Common learnings
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
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
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 : Maintain separate answer format implementations for each checklist type (AMSTAR2, ROBINS-I, Generic) to prevent data corruption
📚 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/workers/src/auth/config.tspackages/workers/src/auth/oauth-relay.ts
📚 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/workers/src/auth/config.tspackages/workers/src/auth/oauth-relay.ts
📚 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/src/**/*.{ts,tsx} : Use import aliases from jsconfig.json as defined in the project configuration
Applied to files:
packages/workers/src/auth/config.ts
📚 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/workers/src/auth/config.tspackages/workers/src/auth/oauth-relay.ts
📚 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/web/src/**/*.{ts,tsx} : Use import aliases from jsconfig.json as defined for the project
Applied to files:
packages/workers/src/auth/config.ts
📚 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/**/*.{ts,tsx,js,jsx} : Prefer config files over hardcoding values
Applied to files:
packages/workers/src/auth/config.ts
📚 Learning: 2026-01-05T01:00:58.113Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/workers-testing.mdc:0-0
Timestamp: 2026-01-05T01:00:58.113Z
Learning: Applies to {packages/workers/src/**/*.test.js,packages/workers/src/**/__tests__/**/*.js} : Reuse provided helpers from packages/workers/src/__tests__/helpers.js (resetTestDatabase, clearProjectDOs, seedUser, seedOrganization, createTestEnv, fetchApp, json, createAuthHeaders) instead of implementing ad-hoc solutions
Applied to files:
packages/workers/src/auth/config.ts
📚 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} : Never prop-drill shared state - import stores directly
Applied to files:
packages/workers/src/auth/config.ts
📚 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/web/src/**/*.{ts,tsx} : Never prop-drill shared state; import stores directly
Applied to files:
packages/workers/src/auth/config.ts
📚 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 Drizzle ORM for ALL database interactions and migrations
Applied to files:
packages/workers/src/auth/config.ts
📚 Learning: 2026-01-17T16:10:07.531Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-17T16:10:07.531Z
Learning: Use required libraries for specific functionality: Zod for validation, Drizzle for database, Better-Auth for authentication, Ark UI for components
Applied to files:
packages/workers/src/auth/config.ts
📚 Learning: 2026-01-01T23:31:43.756Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/api-routes.mdc:0-0
Timestamp: 2026-01-01T23:31:43.756Z
Learning: Applies to packages/workers/src/routes/**/*.js : Apply authentication and authorization middleware in correct order: Authentication → Organization membership → Project access → Authorization → Validation → Route handler
Applied to files:
packages/workers/src/auth/config.ts
📚 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/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.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/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/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.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 : 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/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.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/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.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/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.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 : Use getChecklistStatus utility from `@/lib/checklist-domain.js` to determine current checklist status before performing operations
Applied to files:
packages/web/src/components/checklist/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.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,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/common/LocalTextAdapter.jspackages/web/src/components/checklist/LocalChecklistView.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} : 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/common/LocalTextAdapter.js
📚 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/checklist/LocalChecklistView.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/** : 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/LocalChecklistView.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/checklist/LocalChecklistView.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/checklist/LocalChecklistView.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/checklist/LocalChecklistView.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/checklist/LocalChecklistView.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 `cachePdf` and `getCachedPdf` from `primitives/pdfCache.js` for caching PDF data in IndexedDB
Applied to files:
packages/web/src/components/checklist/LocalChecklistView.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/checklist/LocalChecklistView.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} : Implement PDF caching strategy: check cache first, download from server if not cached, then cache the downloaded PDF
Applied to files:
packages/web/src/components/checklist/LocalChecklistView.jsx
📚 Learning: 2025-12-27T03:01:54.727Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/form-state.mdc:0-0
Timestamp: 2025-12-27T03:01:54.727Z
Learning: Applies to packages/web/src/**/*.{js,jsx} : 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()
Applied to files:
packages/workers/src/auth/oauth-relay.ts
🧬 Code graph analysis (2)
packages/web/src/components/checklist/common/LocalTextAdapter.js (1)
packages/web/src/components/checklist/LocalChecklistView.jsx (1)
createLocalAdapterFactories(42-47)
packages/web/src/components/checklist/LocalChecklistView.jsx (1)
packages/web/src/components/checklist/common/LocalTextAdapter.js (1)
createLocalAdapterFactories(17-152)
🪛 Biome (2.3.13)
packages/web/src/components/checklist/common/LocalTextAdapter.js
[error] 202-202: This callback passed to forEach() iterable method should not return a value.
Either remove this return or remove the returned value.
(lint/suspicious/useIterableCallbackReturn)
[error] 209-209: This callback passed to forEach() iterable method should not return a value.
Either remove this return or remove the returned value.
(lint/suspicious/useIterableCallbackReturn)
⏰ 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: Cursor Bugbot
- GitHub Check: Workers Builds: corates
🔇 Additional comments (8)
packages/workers/src/auth/config.ts (1)
4-4: No issues to flag in this segment.packages/workers/src/auth/oauth-relay.ts (4)
98-164: No issues to flag in this segment.
173-193: No issues to flag in this segment.
200-341: No issues to flag in this segment.
350-427: No issues to flag in this segment.packages/web/src/components/checklist/common/LocalTextAdapter.js (2)
17-151: Factory-based adapters look consistent.The path resolution and update shaping are coherent across checklist types, and the cache surface is straightforward to integrate.
176-182: Observer implementation is correct—callbacks intentionally receive no arguments.LocalTextAdapter's
observe()method invokes all registered callbacks with no parameters (callback()), and all existing consumers in NoteEditor.jsx and NotesCompareSection.jsx conform to this pattern by taking no parameters and reading state directly viayText.toString(). This is an intentional design choice for a simplified observer pattern. No code attempts to access event payloads orevent.delta.Likely an incorrect or invalid review comment.
packages/web/src/components/checklist/LocalChecklistView.jsx (1)
76-78: Cache clearing on load and unmount is a good guard against stale adapters.This keeps adapter instances aligned with the latest checklist state.
Also applies to: 99-102
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| _notifyUpdate() { | ||
| if (this._onUpdate) { | ||
| this._onUpdate(this._value); | ||
| } | ||
| this._observers.forEach(callback => callback()); | ||
| } | ||
|
|
||
| // Allow external sync of value (e.g., when checklist reloads) | ||
| _syncValue(newValue) { | ||
| if (this._value !== newValue) { | ||
| this._value = newValue; | ||
| this._observers.forEach(callback => callback()); | ||
| } |
There was a problem hiding this comment.
Biome lint error: avoid implicit returns in forEach callbacks.
Arrow expressions implicitly return, which triggers lint errors. Wrap callbacks in a block to avoid returning a value.
Proposed fix
- this._observers.forEach(callback => callback());
+ this._observers.forEach(callback => {
+ callback();
+ });
@@
- this._observers.forEach(callback => callback());
+ this._observers.forEach(callback => {
+ callback();
+ });🧰 Tools
🪛 Biome (2.3.13)
[error] 202-202: This callback passed to forEach() iterable method should not return a value.
Either remove this return or remove the returned value.
(lint/suspicious/useIterableCallbackReturn)
[error] 209-209: This callback passed to forEach() iterable method should not return a value.
Either remove this return or remove the returned value.
(lint/suspicious/useIterableCallbackReturn)
🤖 Prompt for AI Agents
In `@packages/web/src/components/checklist/common/LocalTextAdapter.js` around
lines 198 - 210, The forEach callbacks in _notifyUpdate and _syncValue use
concise arrow bodies causing implicit returns (lint error); update both observer
iterations in methods _notifyUpdate and _syncValue to use block arrow functions
instead (e.g., change callback => callback() to callback => { callback(); }) so
the callbacks have an explicit block body and no implicit return.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| } catch (err) { | ||
| console.error('Error saving checklist:', err); | ||
| } | ||
| }, 500); |
There was a problem hiding this comment.
Race condition when navigating between checklists loses or corrupts data
High Severity
The refactored debouncedSave reads params.checklistId when it fires, not when scheduled. When navigating from checklist A to B, the pending save isn't cancelled in the createEffect. If the save fires during loading, it may save A's data to B's ID (data corruption). If it fires after loading completes, A's unsaved changes are lost. The old code captured checklistId at schedule time, avoiding this issue.


Note
Medium Risk
Touches local checklist editing/persistence by changing how updates are merged and saved and by introducing a Y.Text-like adapter layer; bugs here could cause notes/comments to desync or overwrite state in IndexedDB. Auth changes are formatting-only.
Overview
Local checklists now support the same rich text note/comment editors as collaborative checklists by introducing
LocalTextAdapter(a lightweight, Y.Text-compatible string adapter) and wiring adapter factories (getQuestionNote,getRob2Text,getRobinsText) throughLocalChecklistViewintoChecklistWithPdf/GenericChecklist.Local checklist persistence is adjusted to reduce overwrite/race issues: the debounced save now persists the entire current checklist state when it fires, and adapter caches are cleared on load, on checklist updates, and on unmount to avoid stale text values.
Worker auth changes are limited to import/formatting cleanup in
auth/config.tsandauth/oauth-relay.ts(no intended behavior changes).Written by Cursor Bugbot for commit 33eb6d1. This will update automatically on new commits. Configure here.
Summary by CodeRabbit
Improvements
Bug Fixes
Style
✏️ Tip: You can customize this high-level summary in your review settings.