Katkat

Design a Notebook App That Synchronizes Notes

HexSoftware Engineer · Onsite

Last updated

This question tests the ability to design a resilient client-server architecture for a collaborative editing application that must function reliably under network instability.

System Design: Synchronized Notebook App

Design a web-based notebook application that allows users to create and edit documents. The application must remain responsive during periods of poor network connectivity and eventually synchronize state with a backend service via a RESTful API.

Functional Requirements

  1. Users can create, update, and delete notes.
  2. Edits must be reflected immediately in the local UI.
  3. The application must synchronize local changes with the server automatically.
  4. If the server rejects an update or the network fails, the system must recover gracefully.

Non-Functional Requirements

  1. Consistency: Ensure that concurrent edits (e.g., from two devices) do not result in silent data loss.
  2. Reliability: Operations must be retried with backoff strategies when the server is unreachable.
  3. Offline-first: Users should be able to continue working without an active internet connection.

Constraints & Context

  • The external notes API is unreliable (intermittent 500 errors and timeouts).
  • Assume a client-side persistent storage mechanism (e.g., IndexedDB) is available.
  • You do not need to implement full Operational Transformation (OT) or CRDTs, but you must describe how you handle conflict resolution.

Your Task

Provide a high-level design covering:

  1. The client-side data state management (local storage vs. memory).
  2. A strategy for handling offline updates (e.g., an outgoing operation queue).
  3. How to achieve idempotency for operations sent to the API.
  4. A collision detection or merging strategy when the client and server versions differ.

Hints

Hint 1

Consider using an 'outbox' pattern to store pending operations locally before attempting to transmit them to the server.

Hint 2

To handle idempotency, include a unique client-generated Request-ID or UUID for every mutation sent to the server.

Hint 3

For conflict resolution, consider using version vectors or timestamps, or simply adopting a 'last-write-wins' policy with a documented reconciliation strategy.

Follow-up questions

  • How would you change your design if the application needed to support real-time collaborative editing between two users simultaneously?
  • What specific monitoring or logging would you implement on the client side to debug synchronization failures in the field?
  • How would you handle a scenario where a user deletes a note while offline, but the note was updated on the server by another device during that same time?