Дневник питания - оффлайн и без сервера

Врач попросил вести дневник питания - время и что съел. Все готовые приложения хотят регистрацию, подписку, и именно времени приёма пищи - нет у многих. Написал своё: eat.x-crm.in - открыл, записал, закрыл. Бесплатно, с синхронизацией через гугл аккаунт.
Что умеет
- Записи за секунды - textarea + время (подставляется само), Ctrl+Enter. Каждая строка - отдельная позиция приёма пищи
- Работает оффлайн - service worker кэширует оболочку, данные живут в IndexedDB браузера. В метро, в самолёте - без разницы
- Ставится как приложение - пункт «Установить приложение» в меню кладёт значок на рабочий стол Android/десктопа, запускается в своём окне без адресной строки
- Синхронизация между устройствами - опционально, через ваш Google Диск
- Версия для печати - Ctrl+P или пункт «Печать»: чистый список с полными датами, чёрным по белому. То, ради чего всё затевалось - отдать врачу бумажку
- Экспорт и импорт JSON - резервная копия одним файлом, импорт сливает без дублей
Без сервера - это как?
Буквально: бэкенда нет. Статика лежит на GitHub Pages, а синхронизация ходит из браузера напрямую в Google Drive API - в скрытую папку приложения (appDataFolder), которую не видно среди файлов Диска и до которой другие приложения не дотянутся.
Авторизация - Google Identity Services, token flow: никакого client_secret, никакого промежуточного сервера, который читает ваши данные. Access token живёт около часа и продлевается только по клику - при запуске приложение не открывает никаких окон и вообще не ходит в сеть.
Источник истины - локальная база. Облако лишь реплика: слияние по правилу last-write-wins на каждую запись, удаления разносятся tombstone-ами и вычищаются через 30 дней. Одновременная правка на двух устройствах не превращается в кашу - побеждает более поздняя версия.
Приватность
Данные хранятся ровно в двух местах: в вашем браузере и (если включили синхронизацию) в скрытой папке вашего Google Диска. Промежуточных серверов нет, аналитики нет, cookies нет. Отозвать доступ можно в настройках Google-аккаунта - приложение при этом продолжит работать локально.
Не залогинившись, получаете то же самое минус синхронизация - для дневника «на неделю для врача» и этого хватает.
Под капотом
React 19 + TypeScript + Vite, vite-plugin-pwa (Workbox), IndexedDB через idb. Логика слияния - чистые функции, покрытые тестами через node --test без Jest. Деплой - GitHub Actions на поддомен, public/CNAME в артефакте.
Исходники открыты: github.com/william-aqn/eat. Форкается в свой вариант за вечер: словарь нового языка - один файл, замена облака - один адаптер (RemoteStore), палитра - CSS-переменные в :root.
Ссылки
- Приложение: eat.x-crm.in
- Код: github.com/william-aqn/eat