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.