Skip to content

Fix row doc cell updates#340

Merged
appflowy merged 4 commits into
mainfrom
fix_row_doc_cell_updates
May 14, 2026
Merged

Fix row doc cell updates#340
appflowy merged 4 commits into
mainfrom
fix_row_doc_cell_updates

Conversation

@appflowy
Copy link
Copy Markdown
Contributor

@appflowy appflowy commented May 14, 2026

Description


Checklist

General

  • I've included relevant documentation or comments for the changes introduced.
  • I've tested the changes in multiple environments (e.g., different browsers, operating systems).

Testing

  • I've added or updated tests to validate the changes introduced for AppFlowy Web.

Feature-Specific

  • For feature additions, I've added a preview (video, screenshot, or demo) in the "Feature Preview" section.
  • I've verified that this feature integrates seamlessly with existing functionality.

Summary by Sourcery

Ensure database row documents and cells are created and ready before applying cell and calendar time updates, and adapt calendar event handlers to the new async update flow.

Bug Fixes:

  • Recover from missing row documents when updating individual cells by lazily creating/loading the row before committing changes.
  • Prevent calendar time updates from silently failing by waiting for row data to be ready and rejecting when the row doc cannot be loaded.

Enhancements:

  • Refactor cell update logic into dedicated helpers that safely wait for row data availability with a timeout and centralize Yjs write operations.
  • Export cell update hooks from a separate dispatch module to simplify reuse by other parts of the database layer.

Tests:

  • Add hook tests to verify that cell and calendar time update hooks ensure missing row docs, correctly persist data, and handle failure when rows cannot be loaded.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 14, 2026

Reviewer's Guide

Refactors cell update logic to be row-doc aware and resilient to missing row data, centralizing it in a dedicated dispatch module, adding async handling for calendar interactions, and introducing tests to ensure rows are ensured/loaded before cell updates are applied.

Sequence diagram for async row-aware cell update flow

sequenceDiagram
  actor User
  participant FullCalendar
  participant useCalendarEvents
  participant useUpdateStartEndTimeCell as updateCell
  participant DatabaseContext as useDatabaseContext
  participant waitForWritableRowTarget
  participant writeCellToRow

  User->>FullCalendar: drag/resize event
  FullCalendar->>useCalendarEvents: handleEventDrop/handleEventResize
  useCalendarEvents->>useCalendarEvents: updateEventTime(rowId, startTimestamp, endTimestamp, isAllDay)
  useCalendarEvents->>updateCell: updateCell(rowId, fieldId, startTimestamp, endTimestamp, isAllDay)

  activate updateCell
  updateCell->>DatabaseContext: rowMap[rowId]
  alt rowDoc and writable target exist
    updateCell->>writeCellToRow: writeCellToRow(rowDoc, row, cells, fieldId, FieldType.DateTime, data, dateOpts)
  else rowDoc or target missing
    updateCell->>DatabaseContext: ensureRow(rowId)
    DatabaseContext-->>updateCell: rowDoc
    updateCell->>waitForWritableRowTarget: waitForWritableRowTarget(rowDoc)
    waitForWritableRowTarget-->>updateCell: { row, cells } | null
    alt target ready
      updateCell->>writeCellToRow: writeCellToRow(rowDoc, row, cells, fieldId, FieldType.DateTime, data, dateOpts)
    else timed out / null
      updateCell->>updateCell: Log.warn("Row doc not ready for cell update")
    end
  end
  deactivate updateCell
Loading

File-Level Changes

Change Details Files
Refactor cell update hook to ensure row docs exist and are writable before updating cells, with shared helpers for date-cell handling.
  • Replaced useRowMap with useDatabaseContext to gain access to rowMap and ensureRow.
  • Introduced helper types and functions (CellUpdateData, DateCellOptions, WritableRowTarget, getWritableRowTarget, waitForWritableRowTarget, writeCellToRow) to encapsulate row/cell lookup and mutation semantics, including a timeout-based wait for row readiness.
  • Updated useUpdateCellDispatch to asynchronously ensure the row document via ensureRow, wait for row data to become available, then write cell data using writeCellToRow inside a Yjs transaction, with structured logging and error handling.
src/application/database-yjs/dispatch/cell.ts
Make the calendar-specific start/end time cell update hook robust to missing row docs and reuse the shared row/cell helpers.
  • Updated useUpdateStartEndTimeCell to use useDatabaseContext, calling ensureRow and waitForWritableRowTarget when the row document or row data is missing.
  • Adjusted the hook to throw a clear error when the row doc cannot be prepared for updates and to update cells via the WritableRowTarget structure, including last_modified timestamps.
  • Retained date field semantics (FieldType.DateTime, include_time, is_range, end_timestamp) while routing writes through the new shared helpers.
src/application/database-yjs/dispatch/cell.ts
Centralize export of cell dispatch hooks and remove legacy inline implementations from the main dispatch file.
  • Deleted the old implementations of updateDateCell, useUpdateCellDispatch, and useUpdateStartEndTimeCell from src/application/database-yjs/dispatch.ts.
  • Re-exported useUpdateCellDispatch and useUpdateStartEndTimeCell from the new src/application/database-yjs/dispatch/cell module.
src/application/database-yjs/dispatch.ts
Align FullCalendar event update flows with the now-async cell update API.
  • Made updateEventTime in useCalendarEvents async and awaited the injected updateCell hook.
  • Updated handleEventDrop and handleEventResize to be async and await updateEventTime so calendar UI changes are properly sequenced with underlying Yjs updates.
src/components/database/fullcalendar/hooks/useCalendarEvents.ts
Ensure event creation in the calendar waits for underlying cell updates to complete.
  • Made handleEventReceive in CalendarContent async and awaited updateEventTime when moving items from NoDate into the calendar view.
src/components/database/fullcalendar/CalendarContent.tsx
Add tests to verify row ensuring behavior for cell and calendar updates, including failure modes.
  • Created Yjs-based helpers to construct database and row documents for tests, including field setup.
  • Added tests for useUpdateCellDispatch to confirm it calls ensureRow when the row doc is missing and successfully writes cell data once the row is created.
  • Added tests for useUpdateStartEndTimeCell to ensure it both succeeds when ensureRow returns a doc (writing date metadata correctly) and rejects when the row cannot be loaded, matching the new error behavior.
src/application/database-yjs/__tests__/useUpdateCellDispatch.test.tsx

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In writeCellToRow, the guard typeof data === 'string' || typeof data === 'number' is inconsistent with CellUpdateData (which excludes number) and updateDateCell (which expects a string), so you can tighten the type and drop the number branch to avoid confusion and potential misuse.
  • The fixed ROW_DATA_WAIT_MS = 3000 timeout in waitForWritableRowTarget is a hidden magic value; consider either documenting why 3s is appropriate or making it configurable so callers can tune behavior for different environments.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `writeCellToRow`, the guard `typeof data === 'string' || typeof data === 'number'` is inconsistent with `CellUpdateData` (which excludes `number`) and `updateDateCell` (which expects a string), so you can tighten the type and drop the `number` branch to avoid confusion and potential misuse.
- The fixed `ROW_DATA_WAIT_MS = 3000` timeout in `waitForWritableRowTarget` is a hidden magic value; consider either documenting why 3s is appropriate or making it configurable so callers can tune behavior for different environments.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

appflowy and others added 2 commits May 14, 2026 12:05
# Conflicts:
#	src/application/database-yjs/__tests__/useUpdateCellDispatch.test.tsx
#	src/application/database-yjs/dispatch/cell.ts
Row dispatch hooks no longer return a Promise after the merge from main,
so `await` on the result is a lint error and a no-op.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@appflowy appflowy merged commit 620b9cf into main May 14, 2026
13 checks passed
@appflowy appflowy deleted the fix_row_doc_cell_updates branch May 14, 2026 07:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant