Разделить счёт

PWA
офлайн-режим
OCR
сканирование чека
0
backend
URL #
шеринг
Vanilla JSCSS custom propertiesTesseract.jsService WorkerWeb Share APIURL hash
Роль
Идея, дизайн, разработка
Стек
Vanilla JS · PWA · Tesseract.js
Платформа
Веб / Mobile-first
Статус
Живой прод

Контекст

«Скиньте кто сколько» — универсальная боль

После кафе с компанией кто-то вечно стоит с телефоном и считает в уме, кто сколько брал. Существующие приложения либо перегружены (Splitwise — полноценный финансовый трекер), либо требуют регистрацию ради одного вечера. Нужно что-то, что открывается, считает и отправляет ссылку — за 30 секунд.

Проблема

Три точки боли за одним столиком

01

Ввод данных

Вручную суммировать и делить — медленно и легко ошибиться, особенно с чаевыми и скидками.

02

Шеринг

Скинуть итог всем участникам. Мессенджер, скрин, слова — каждый раз по-разному.

03

Трекинг

Кто уже перевёл, кто нет — держат в голове или в заметках.

Гипотеза

Минимальный флоу: 4 экрана, 0 регистраций

Если убрать всё лишнее и сделать только три операции — ввести счёт, добавить участников, отправить ссылку — приложение будет использоваться. Ключевое ограничение: никакого бэкенда. Данные не должны никуда уходить, инфраструктура должна быть нулевой.

1 Сфоткать чек (OCR)
2 Или ввести вручную
3 Добавить участников
4 Отправить ссылку

Ключевые решения

Три нетривиальных выбора

Решение #1

Шеринг через URL hash, не через сервер

Было

Первый инстинкт — сохранять сессию на бэкенде, давать короткую ссылку. Это требует сервер, БД, деплой.

Стало

Данные счёта сериализуются в URL fragment (#). Браузер не отправляет # серверу — данные никуда не уходят. Ссылка открывается мгновенно на любом устройстве без регистрации.

Почему именно так: Принцип из MedLog: если медданные не должны уходить на сервер — данные о чеке тоже. Privacy-first — не маркетинг, а архитектурное решение с нулевой инфраструктурой.

Решение #2

OCR как опция, не как основной путь

Было

Хотелось сделать OCR главным входом — «сфоткал и готово». Tesseract.js весит ~4 МБ и работает нестабильно на мятых чеках.

Стало

Два равнозначных пути: сканировать чек камерой или ввести сумму вручную. OCR показывает результат как предзаполненное поле — пользователь всегда может исправить.

Почему именно так: Инструмент должен не подводить в главный момент — когда компания ждёт, пока ты разберёшься с телефоном. Ручной ввод за 5 секунд надёжнее нестабильного OCR.

Решение #3

Vanilla JS вместо фреймворка

Было

Стандартный выбор — React. Знаком, быстро пишется, экосистема.

Стало

Vanilla JS + нативные Web API. Нет сборки, нет зависимостей кроме Tesseract.js, нет hydration-задержки.

Почему именно так: Приложение — 4 экрана с формами и простой логикой. React добавил бы 40+ КБ gzip-нагрузки и абстракцию поверх того, что браузер делает сам. Простое должно оставаться простым.

Результат

Работает, деплоится с нуля

Приложение умещается в четыре экрана: ввод счёта → участники → итог → статус оплат. Ставится на экран телефона как PWA. Работает офлайн — Service Worker кэширует всё при первом открытии. Нет сервера, нет аккаунта, нет следящей аналитики.

Главные ошибки — и что они дали

OCR переоценён для мобильного чека

URL hash не работает в некоторых мессенджерах

Рефлексия

Что вынесла

Проект за выходные — хорошая проверка приоритетов. Когда нет времени на «правильную» архитектуру, выясняется что действительно нужно. Ответ оказался тот же, что и в MedLog: данные пользователя — его данные, и это можно реализовать без сервера, если проектировать с этим с самого начала. URL hash — не хак, а честное архитектурное решение, когда оно подходит по контексту.

← Все кейсы