Skip to content

Conversation

@marcodejongh
Copy link
Owner

  • Add GATT operation queue to serialize Bluetooth writes, preventing
    "GATT operation already in progress" errors when rapidly switching
    climbs
  • Support "latest only" semantics so that when multiple climbs are
    queued rapidly, only the most recent one gets sent to the board
  • Add defensive null checks in queue reducer to handle corrupted queue
    data from IndexedDB or WebSocket, fixing "Cannot read properties of
    undefined (reading 'climb')" crash

- Add GATT operation queue to serialize Bluetooth writes, preventing
  "GATT operation already in progress" errors when rapidly switching
  climbs
- Support "latest only" semantics so that when multiple climbs are
  queued rapidly, only the most recent one gets sent to the board
- Add defensive null checks in queue reducer to handle corrupted queue
  data from IndexedDB or WebSocket, fixing "Cannot read properties of
  undefined (reading 'climb')" crash
@vercel
Copy link

vercel bot commented Jan 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
boardsesh Building Building Preview, Comment Jan 3, 2026 4:39am

@claude
Copy link

claude bot commented Jan 3, 2026

Claude Review

Ready to merge - Minor issues noted below, but nothing blocking.

Issues

  1. Type narrowing inconsistency - gatt-queue.ts:63: Resolving superseded operations with undefined may cause type mismatches since Promise<T> could resolve to undefined when T doesn't include undefined. This is documented behavior but callers should be aware.

  2. Missing tests - The new gatt-queue.ts has no test coverage. This is a critical piece of infrastructure managing Bluetooth serialization. Consider adding tests for:

    • Basic queue serialization
    • "Latest only" key semantics (superseding pending ops)
    • Error handling/rejection propagation
    • Queue clearing behavior
  3. Defensive filtering inconsistency - reducer.ts:136: The DELTA_REMOVE_QUEUE_ITEM case uses item.uuid without defensive ?. chaining, while other cases like DELTA_ADD_QUEUE_ITEM:114 use qItem?.climb?.uuid. If corrupted items exist in the queue, this could throw.

  4. DELTA_REORDER_QUEUE_ITEM not defensive - reducer.ts:152: Accesses newQueue[oldIndex].uuid without null check, inconsistent with the defensive approach added elsewhere.

- Add needsResync flag to QueueState to track when corrupted data was filtered
- Expose triggerResync function from persistent session context
- Update QueueContext to observe the flag and trigger resync automatically
- Update test files with new state property
@claude
Copy link

claude bot commented Jan 3, 2026

Claude Review

Ready to merge - Minor issues noted below, but nothing blocking.

Issues

  1. Missing tests for GATT queue - packages/web/app/components/board-bluetooth-control/gatt-queue.ts has no unit tests. The queue logic (especially the "latest only" semantics with key-based cancellation) should have tests covering edge cases like concurrent operations and key collision.

  2. Potential race in resync trigger - packages/web/app/components/graphql-queue/QueueContext.tsx:334-338: The resync effect clears needsResync before calling triggerResync(). If triggerResync() fails or the component unmounts, the corrupted state flag is lost. Consider clearing the flag after successful resync confirmation.

  3. Type safety gap - packages/web/app/components/board-bluetooth-control/gatt-queue.ts:63: Resolving superseded operations with undefined may not match caller expectations. The operation returns Promise<T> but resolves with undefined when superseded, which could cause issues if callers expect a meaningful return value.

Notes

  • Documentation in docs/websocket-implementation.md does not need updates - this PR adds defensive handling for corrupted data but doesn't change the documented WebSocket architecture or flow.

The GATT operation error just logs to console and isn't urgent.
Keep only the reducer fix that prevents crashes from corrupted
queue data and triggers automatic resync.
@claude
Copy link

claude bot commented Jan 3, 2026

Claude Review

Ready to merge - Minor issues noted below, but nothing blocking.

Issues

  1. Missing test coverage for new functionality - The PR adds new reducer actions (CLEAR_RESYNC_FLAG) and state (needsResync) but doesn't include unit tests for:

    • Corrupted data filtering in INITIAL_QUEUE_DATA and UPDATE_QUEUE
    • The CLEAR_RESYNC_FLAG action
    • Null/undefined item handling in DELTA_ADD_QUEUE_ITEM
    • Defensive null checks added to DELTA_UPDATE_CURRENT_CLIMB

    Consider adding tests in packages/web/app/components/queue-control/__tests__/reducer.test.ts

  2. Potential resync loop (QueueContext.tsx:328-341) - If triggerResync() returns data that still contains corrupted items (e.g., from a corrupted IndexedDB that is the source of truth), this could create a continuous resync loop. The flag is cleared before resync, so it should be safe, but consider adding a backoff or max retry limit.

@marcodejongh marcodejongh merged commit 397b744 into main Jan 3, 2026
4 of 6 checks passed
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.

3 participants