Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Project: versioned case note editor

Last updated: 5 Oct 20268 min read
project
IntermediateBy AITrove Editorial

Build a private case note editor for reviewer 47. The document model allows headings, paragraphs, text, emphasis, and approved links. A contenteditable surface receives browser input, but the saved document is a validated model. Composition input remains visible until committed, and input reconciliation catches edits that beforeinput could not cancel. Selection bookmarks use block ID and offset, then map through inserts, splits, merges, and formatting renders. Paste converts clipboard fragments into the narrow model; it does not store raw HTML, remote images, event attributes, or unsafe links. The server validates the same schema before saving. Group nearby typing into bounded undo steps. Autosave carries document generation, base revision, and idempotency key; a response for generation 6 cannot mark generation 7 saved. A conditional-write conflict preserves both local and server versions for review. Account switch clears private drafts and history. The editor must offer a plain-text path if rich formatting or browser-specific behavior fails.

Build contract

  • Complete an IME composition without losing provisional or committed text.
  • Apply emphasis across a selection and preserve anchor and focus positions.
  • Paste unsafe markup, then verify saved and exported content follows one policy.
  • Receive an old autosave response while a newer generation remains dirty.

Implementation checkpoint

javascript
function mayShowSaved(sentGeneration, currentGeneration, conflict) {
  return !conflict && sentGeneration === currentGeneration;
}
console.log(mayShowSaved(6, 7, false));
// Output: false

Cost and boundaries

A full snapshot per keystroke costs O(document size times history depth); grouped transactions or capped snapshots reduce memory. Parsing pasted fragments costs O(n) and needs byte and nesting limits. Rebuilding the entire DOM on each input can move the caret and stall typing. Debounced autosave reduces requests but extends unsaved time. Track edit latency, undo bytes, dirty duration, conflicts, and recovery success without collecting note text.

Failure drill

Type through an IME while the editor rerenders and confirm no character is lost. Paste a fragment with an event attribute and unsupported image, then submit the same content directly to the API. Replace a text node during emphasis and verify the caret remains at its model position. Start autosave A, type again, then deliver A last; the editor must remain dirty. Cause a revision conflict and retain both versions. Undo a grouped edit, type a new branch, and confirm redo does not replay the old branch.

Acceptance checks

  • Committed text and saved model agree after composition.
  • Paste and direct API writes share the same safety policy.
  • Caret survives model transforms.
  • A stale save response never clears newer edits.

Common Mistakes

  • Treating live editable DOM as the document authority.
  • Trusting a client paste filter as server validation.
  • Letting older autosave acknowledgments erase dirty state.

Related lessons

Editable Input, Composition, and Document Model; Selection Bookmarks and Transaction Mapping; Paste Import, Sanitization, and Link Policy; Undo History, Autosave, and Revision Conflicts.

web-tech
web-development
Storage details