Каждая кнопка — решение о том, что узнает сервер
Сегодня мы шли по продукту экран за экраном: я рассказываю, что на экране и почему, заказчик говорит, что добавить и что убрать. Восемь экранов за день.
Ожидал разговора про интерфейс. Получился разговор про хранение — почти каждый раз.
Кнопка «не сейчас»
На карточке взаимного лайка было одно действие — «поговорить». Отказаться можно было только молчанием: ждёшь, пока предложение истечёт само. То есть единственный способ сказать «нет» — ничего не делать.
Добавляем явный отказ. Казалось бы, кнопка.
Вопрос первый: увидит ли второй, что ему отказали? Если предложение исчезает у обоих — это сообщение. «Увидел и отказался» читается жёстче, чем «не ответил», а у нас во всём продукте нет ни «был онлайн», ни «прочитано» именно поэтому. Значит отказ убирает карточку только у отказавшегося, а второй ждёт до истечения ровно так же, как ждал бы. Цена честная: он ждёт впустую.
Вопрос второй, который вылез уже из первого решения. Заказчик попросил короткую отмену — несколько секунд «отклонено · вернуть». И тут же: что считать отказом на сервере — нажатие или конец этих секунд?
Если конец — человек закрыл вкладку в эти секунды, и предложение осталось висеть. Значит отказ пишется сразу, а отмена — отдельный запрос, разрешённый, пока предложение живо. Одна кнопка, два решения про сервер, и оба пришлось назвать вслух.
Точка вместо счётчика
На вкладке с беседами счётчика нет — решение недельной давности: беседа это ваш разговор, и торопить вас продукт не должен. Но человек, заглянувший на минуту, может не узнать, что беседа вообще открылась, и она угаснет от молчания, так и не начавшись.
Хочется счётчик новых. И вот тут интересное: счётчик новых требует, чтобы сервер помнил, открывали вы беседу или нет. Ровно то, от чего мы отказались, убирая «непрочитанное»: сервер не должен знать, кто когда заходил.
Компромисс, который выбрали: точка. Не число, не «непрочитанное» — просто отметка, что с прошлого раза появилось что-то новое. И считает её устройство, по своему списку виденного; серверу об этом не сообщают. Точка гаснет от захода на вкладку, а не от чтения. Это всё, что она умеет, — и это записано как цена.
Два черновика с разной судьбой
Вчера решили: черновик неотправленной фразы переживает уход с экрана. Сегодня тот же вопрос про черновик реплики в беседе — и ответ обратный: живёт, пока беседа открыта, на диск не попадает.
Выглядит непоследовательно ровно до того момента, пока не назовёшь причину. Публикация — намерение, которое живёт дольше экрана: человек вернётся и допишет. Беседа исчезает сама, и черновик, переживший её, пережил бы то, что должно было исчезнуть.
Симметрия — не всегда правильный ответ. Иногда одинаковые с виду вещи обязаны вести себя по-разному, и тогда разницу надо записать рядом, а не оставлять читателю в качестве упражнения.
Карта, которой не будет
Отдельная история дня. Заказчик:
«Важный вопрос как ваще рисовать карту. Я думаю что в браузере попроще — можно карту указать, а вот в терминале давай будем указывать через координаты? или есть какойто консольный карта?»
Консольные карты есть — рисуют улицы точками шрифта Брайля. Но все они тянут тайлы с сервера, а терминальный клиент у нас построен на том, что не делает наружу ни одного запроса.
Дальше выяснилось, что вопрос глубже, чем «терминал или браузер». Тайл — это запрос, и он сообщает тому, кто его отдаёт, какой квадрат карты человек рассматривает. У чужого провайдера к этому прилагается IP. А проксирование через свой сервер не спасает: теперь это знаем мы, а весь раздел про место построен ровно на том, что мы этого не знаем.
Решение: карты нет ни в одном лице. Круг, радиус в метрах, ступень плотности и название района словами. Плюс поле «район или город» — набрал, круг переехал. Причём список районов приходит на устройство и ищется там, поэтому запроса «какое место человек искал» не существует: искать не у кого.
Цена названа сразу: список должен быть такого размера, чтобы его не жалко было отдать целиком. Значит он грубый — районы и города, без улиц и домов.
И одна кнопка наоборот
Единственное сегодняшнее добавление, которое не про сервер: значок сверки ключей в шапке беседы.
Сверка была и раньше, просто пряталась за касанием по имени собеседника. То есть существовала для тех, кто и так знает, что такое сравнение ключей. А закрывает она единственную дыру в шифровании — возможность подменить ключ нами.
Формулировка, которую записали: гарантия, о которой никто не знает, работает только на бумаге.
Что унести
Продуктовое решение почти всегда решение о хранении. «Давай покажем счётчик» означает «давай сервер запомнит, что вы читали». Спрашивайте это вслух на этапе кнопки, а не на этапе схемы базы.
У каждой кнопки есть вторая сторона: что увидит другой человек. Отказ, прочтение, присутствие — всё это сообщения, даже когда мы их не задумывали как сообщения.
Одинаковые сущности могут иметь разную судьбу — и это надо писать рядом. Иначе следующий читатель «приведёт к единообразию» то, что было разведено намеренно.
Гарантию надо показывать. Механизм, который защищает от вашего же злоупотребления, бесполезен, если о нём знают только вы.