intermediate

Local-first apps

Моделируйте offline writes, sync, conflicts, migrations и merge semantics, когда SQLite поддерживает local-first UX.

Local-first приложения делают on-device SQLite источником правды для UX: чтение и запись офлайн, затем sync сверяет с сервером или пирами.

Задачи проектирования:

  • **Офлайн-запись**: очередь мутаций с client-generated ID (UUID) до успешного sync
  • **Разрешение конфликтов**: last-write-wins, version vectors, CRDT или доменный merge
  • **Миграции**: версия схемы на релиз; частичные апгрейды на устройствах
  • **Протокол sync**: push/pull дельт, tombstones для удалений, backoff и идемпотентность
					CREATE TABLE notes (
  id TEXT PRIMARY KEY,
  body TEXT NOT NULL,
  updated_at INTEGER NOT NULL,
  deleted INTEGER DEFAULT 0,
  sync_version INTEGER DEFAULT 0
);

-- Pull изменений с курсора
SELECT * FROM notes WHERE sync_version > ? OR updated_at > ?;
				

SQLite даёт мгновенный UI; слой sync владеет границами консистентности. CRDT или ElectricSQL/LiteFS меняют эксплуатацию, но не суть компромисса.

На интервью: офлайн create → reconnect → conflict; tombstones и идемпотентный sync; локальная консистентность UX vs authority сервера.

Типовые ошибки: server auto-increment ломает офлайн create; sync целых таблиц; удаления не распространяются; политика конфликтов не определена до жалоб пользователей.

Компромисс — отзывчивый офлайн UX против сложности sync, конфликтов и тестирования на разных версиях устройств.

Чеклист:

  • Client ID для офлайн create.
  • Явная политика конфликтов и удалений (tombstone).
  • Версионированные миграции на устройстве.
  • Идемпотентный sync с курсорами или change feed.