STTM
Next.js 16 · FastAPI · PostgreSQL · Web Push

Видно, что ты занят. И не видно, чем именно.

Свой день, неделя и напоминания — в одном месте. Чужая занятость видна по @username, но содержимое закрыто, если ты его закрыл. Обезличивание происходит на сервере, поэтому название записи физически не уезжает в браузер.

4
уровня видимости
3
вида записей
0
запросов из браузера к бэку
1
cookie вместо токенов в localStorage
Так это выглядит

Неделя занятости. Цветной блок — то, чем занят человек и что он готов показать. Серый — то, что он занят, но не рассказал.

СвоёЗанято, без деталей◆Напоминание
пн
28
вт
29
ср
30
чт
1
пт
2
сб
3
вс
4
00:0002:0004:0006:0008:0010:0012:0014:0016:0018:0020:0022:00
Планёрка команды09:00 — 10:00
Ревью кода11:30 — 13:00
Занято
◆Разбор почты
Занято
Тренировка19:00 — 20:30
Созвон с клиентом10:00 — 11:00
◆Занято
Прогулка16:30 — 18:30
Релиз09:30 — 12:30
Занято
Поехали гулять09:30 — 12:30
Собеседование11:00 — 12:30
Английский15:00 — 16:00
◆Оплата аренды
Занято
Воскресный обед11:00 — 12:00
Приватность

Занятость видна всем. Содержимое — не всем.

Два вопроса разделены специально. Человек может не хотеть, чтобы мир знал, что в это время он у врача, — и при этом хотеть, чтобы друзья не пришли к нему в гости.

УровеньТыДругЧужой
PRIVATEПо умолчанию. Не показывать, чем занят, безопаснее, чем показывать всемВидноСерый блокСерый блок
FRIENDSСодержимое видно друзьям в любую сторонуВидноВидноСерый блок
LISTРовно тем, кого ты назвал. Список не может быть пустымВидноПо спискуСерый блок
PUBLICВсем, у кого профиль открытВидноВидноВидно

Настоящие имя и почта необязательны. Пароль в демо-режиме хранится как есть — для проверки, не для продакшена.

Как это работает

Три шага, и всё, что нужно

  1. 1

    Описываешь занятость

    Событие — это отрезок, напоминание — точка. Наложения разрешены: «занят» и не обязан быть непротиворечивым.

  2. 2

    Выбираешь, кто увидит

    У каждой записи своя видимость. По умолчанию PRIVATE, так что забыть и открыть всё случайно нельзя.

  3. 3

    Получаешь напоминание

    Web Push приходит в браузер в назначенный момент. Одноразовый или по cron-правилу с часовым поясом.

Возможности

Что уже работает

Своя неделя и своя история

Сетка по дням с блоками и точками напоминаний. Границы окна задаёт фронт: бэк отдаёт пересекающиеся интервалы, а не лежащие внутри, поэтому событие через полночь видно в обоих днях.

Повторяющиеся правила

Cron в часовом поясе напоминания, а не сервера. «Каждый день в 9:00» считается там, где находится человек. Шестое поле cron — секунды, и об этом сервис предупреждает заранее.

Публичные @username

Страница человека по адресу /u/anna. Закрытый профиль отдаёт 404, а не 403: код 403 подтверждал бы, что имя занято, и позволял бы перебирать чужие.

Напоминания в браузере

Push подписывается в браузере, а уходит с бэка. Приватный ключ VAPID на фронт не попадает: бэк сам отдаёт публичный ключ одной ручкой.

Бэкенд не торчит наружу

Браузер знает только про Next. Идентичность берётся из подписанной cookie, а бэк видит заголовок и общий секрет, подтверждающий, что запрос пришёл от Next.

Ошибки говорят по-русски

У каждой доменной ошибки свой код и текст, а не «что-то пошло не так». Форма подсвечивает конкретное поле, а не показывает красное обвестие вокруг всей карточки.

Правила сервиса

Коротко о главном

Без мелкого шрифта: пять правил, которые определяют, что сервис вообще такое.

  1. 01

    Свою занятость видно всем, у кого профиль открыт. Это и есть смысл сервиса: «я занят» должно быть видно.

  2. 02

    Содержимое записи — другое дело. Оно не показывается никому, кроме тех, кому ты разрешил, и не уезжает в браузер.

  3. 03

    У закрытого профиля занятость не видна вообще: даже серых блоков не будет. Иначе «закрытый профиль» ничего бы не значил.

  4. 04

    Чужие записи не редактируются и не удаляются: попытка достать чужое даёт 404, как будто его нет.

  5. 05

    Уведомления приходят в браузер, а не в приложение. Браузер закрыт — уведомление пропущено, и это нормально.

Покажи неделю, а не календарь

Занятость видна всем, у кого открыт профиль. Чем именно занят — только тем, кому ты это разрешил.

Создать аккаунт