forked from admin/runners-calendar
feat: complete race history sprint
This commit is contained in:
@@ -6,8 +6,8 @@
|
||||
|
||||
| Контур | Версия | Уже работает |
|
||||
|---|---:|---|
|
||||
| Backend | `1.5.0` | Express + PostgreSQL, миграции и seed, строгий CRUD личных стартов, cookie-сессии, CSRF, подтверждение email, Turnstile, SMTP, смена пароля и управление сессиями, SSRF-защита обложек, `/health`, `/ready`, `/meta`, CI с PostgreSQL. |
|
||||
| Frontend | `0.8.0` | Защищённые маршруты и auth-экраны, экран аккаунта, нативные поля даты/старта, удобный ввод результатов, дашборд с последними стартами и интерактивным графиком, версия FE/BE в футере. |
|
||||
| Backend | `1.6.0` | Express + PostgreSQL, миграции и seed, строгий CRUD личных стартов, фильтры истории, cookie-сессии, CSRF, подтверждение email, Turnstile, SMTP, смена пароля и управление сессиями, SSRF-защита и восстановление обложек, `/health`, `/ready`, `/meta`, CI с PostgreSQL. |
|
||||
| Frontend | `0.9.0` | Защищённые маршруты и auth-экраны, экран аккаунта, поиск/фильтры/экспорт истории, нативные поля даты/старта, удобный ввод результатов, дашборд с последними стартами и графиком AG Charts, версия FE/BE в футере. |
|
||||
|
||||
## Правила версионирования и выпуска
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
| Очередь | BE | FE | Цель | Условие выпуска |
|
||||
|---|---:|---:|---|---|
|
||||
| P0 | `1.4.2` | `0.7.1` | Исправить риски текущего релиза и привести контракт в соответствие коду. | Нет невалидных записей, SSRF-защита, критические сценарии проверяются на PostgreSQL. |
|
||||
| P1 | `1.5.0` | `0.8.0` | Дать пользователю контроль над аккаунтом и данными, улучшить работу с историей стартов. | Управление сессиями и экспорт доступны, фильтры не ломают существующий список. |
|
||||
| P2 | `1.6.0` | `0.9.0` | Подготовка к старту: чек-листы, напоминания и календарная интеграция. | Напоминание отправляется не более одного раза, подписка/токен отзываемы. |
|
||||
| P3 | `1.7.0` | `1.0.0` | Сделать персональный календарь эксплуатационно готовым. | Восстановление из backup проверено, есть E2E критического пути и аудит доступности. |
|
||||
| P1 | `1.6.0` | `0.9.0` | Дать пользователю контроль над аккаунтом и данными, улучшить работу с историей стартов. | Управление сессиями и экспорт доступны, фильтры не ломают существующий список. |
|
||||
| P2 | `1.7.0` | `1.0.0` | Подготовка к старту: чек-листы, напоминания и календарная интеграция. | Напоминание отправляется не более одного раза, подписка/токен отзываемы. |
|
||||
| P3 | `1.8.0` | `1.1.0` | Сделать персональный календарь эксплуатационно готовым. | Восстановление из backup проверено, есть E2E критического пути и аудит доступности. |
|
||||
|
||||
`2.0.0` не планируется заранее: его поводом может быть только подтверждённая потребность в совместном доступе, командах или публичных стартах — это изменит модель владельцев и доступа.
|
||||
|
||||
@@ -51,32 +51,33 @@
|
||||
| FE-071-05 | P0 | Завершать подтверждение email понятным экраном успеха | После успешной ссылки `/verify-email?token=…` заголовок явно сообщает, что email подтверждён; ввод email, инструкция и кнопка повторной отправки не показываются. Форма повторной отправки остаётся только для недействительной/отсутствующей ссылки. |
|
||||
| FE-071-06 | P0 | Упростить ввод результата забега | Время вводится отдельными цифровыми полями «часы», «минуты», «секунды» без ручного ввода `:`. Часы — целое число ≥ 0, минуты и секунды — от 0 до 59; пустые минуты/секунды автоматически нормализуются в `0`. Итоговое время не показывает незаполненные старшие части: без часов — `MM:SS`, без часов и минут — `SS`. Место вводится числами «место» и «всего участников» (второе необязательно), проверяется, что место ≥ 1 и не больше общего числа; в текущий `finishPlace` без изменения API сохраняется `место/всего` либо только место. Старые значения `finishPlace` не теряются до редактирования результата. |
|
||||
|
||||
## P1 — BE 1.5.0 / FE 0.8.0
|
||||
## P1 — BE 1.6.0 / FE 0.9.0
|
||||
|
||||
### Backend 1.5.0
|
||||
### Backend 1.6.0
|
||||
|
||||
| ID | Приоритет | Задача | Результат / критерий приёмки |
|
||||
|---|---|---|---|
|
||||
| BE-150-01 | Готово | Управление паролем и сессиями | Выполнено в `1.5.0`: авторизованный пользователь меняет пароль после проверки текущего; все другие сессии отзываются. Есть список активных сессий с отзывом выбранной и «выйти везде». Токены и пароли в ответах/логах не появляются. |
|
||||
| BE-150-02 | P1 | Удаление аккаунта и данных | Явно подтверждённый запрос удаляет аккаунт, его сессии и личные старты транзакционно; повторный запрос идемпотентен. Перед реализацией согласовать необходимость периода восстановления. |
|
||||
| BE-150-03 | P1 | Обратносуместимая фильтрация стартов | Добавить документированные фильтры `status`, диапазон дат и диапазон дистанции, не меняя текущий ответ-массив `GET /races`. Валидация параметров и покрытие индексами — по фактическому query plan. |
|
||||
| BE-150-04 | P0 | Восстановить обложки существующих стартов | Одноразовый идемпотентный backfill безопасно извлекает `cover_image_url` из сохранённого `official_url` только для стартов без обложки. Та же существующая SSRF-защищённая логика применяется при создании старта и при изменении официальной страницы, если ручная обложка не задана; ручные URL не перезаписываются. Повторный запуск ничего не меняет, недоступные сайты пропускаются, результат содержит только агрегированную статистику. Каталог соответствий по названиям не возвращается. |
|
||||
| BE-150-03 | Готово | Обратносуместимая фильтрация стартов | Добавлены документированные фильтры `status`, диапазон дат и диапазон дистанции без изменения ответа-массива `GET /races`, с валидацией параметров. |
|
||||
| BE-150-04 | Готово | Восстановить обложки существующих стартов | Добавлен идемпотентный backfill и обновление обложки при изменении официальной страницы. SSRF-защищённая логика переиспользуется; ручные URL не перезаписываются, результат содержит агрегированную статистику. |
|
||||
|
||||
### Frontend 0.8.0
|
||||
### Frontend 0.9.0
|
||||
|
||||
| ID | Приоритет | Задача | Результат / критерий приёмки |
|
||||
|---|---|---|---|
|
||||
| FE-080-01 | Готово | Экран «Аккаунт» | Выполнено в `0.8.0`: пользователь видит подтверждённый email, меняет пароль и видит/отзывает другие сессии. Удаление аккаунта остаётся отдельной задачей BE-150-02. |
|
||||
| FE-080-02 | P1 | Поиск, фильтры и сортировка истории | Фильтры по статусу, периоду и дистанции синхронизированы с URL; поиск по названию работает без новой зависимости. Годы в селекторе строятся из данных, а не ограничены окном «-2/+4». |
|
||||
| FE-080-03 | P1 | Выгрузка личных данных | Из текущей отфильтрованной выборки пользователь скачивает CSV и одноразовый `.ics` в браузере. Сервер не нужен: данные уже принадлежат пользователю и загружены в UI. |
|
||||
| FE-080-02 | Готово | Поиск, фильтры и сортировка истории | Фильтры по статусу, периоду и дистанции, поиск по названию и сортировка синхронизированы с URL. Годы в селекторе строятся из данных. |
|
||||
| FE-080-03 | Готово | Выгрузка личных данных | Из текущей отфильтрованной выборки пользователь скачивает CSV и одноразовый `.ics` в браузере; сервер не нужен. |
|
||||
| FE-080-04 | Готово | Сделать на дашборде список последних стартов | Выполнено в `0.8.0`: «Последние старты» показывают до 5 завершённых стартов с клиентской пагинацией, фильтрами по дистанции и году и доступным переходом в старт. |
|
||||
| FE-080-05 | Готово | Связать рекорды по дистанциям со стартами | Выполнено в `0.8.0`: карточка рекорда с найденным стартом ведёт на `/races/:id` и использует существующую анимацию связанных карточек. |
|
||||
| FE-080-06 | Готово | Сделать график прогресса информативным и интерактивным | Выполнено в `0.8.0`: график имеет подписанные оси, компактные подписи, tooltip по наведению/фокусу и доступный переход в старт. |
|
||||
| FE-080-07 | P0 | Вернуть управление официальной страницей старта | Поле «Официальная страница старта» отображается при создании и редактировании любого старта, включая прошедший. Для прошедших стартов скрываются только неактуальные поля расписания. После добавления или изменения официальной страницы и сохранения backend автоматически заполняет отсутствующую обложку; локальная картинка остаётся fallback только при отсутствии или ошибке внешней обложки. |
|
||||
| FE-080-07 | Готово | Вернуть управление официальной страницей старта | Поле «Официальная страница старта» доступно для любого старта, включая прошедший; для прошедших скрываются только неактуальные поля расписания. |
|
||||
| FE-080-08 | Готово | Перевести график прогресса на AG Charts | Самописный SVG заменён на AG Charts; сохранены данные, оси, tooltip, клавиатурная доступность, переход по точке, адаптивность и пустое состояние. |
|
||||
|
||||
## P2 — BE 1.6.0 / FE 0.9.0
|
||||
## P2 — BE 1.7.0 / FE 1.0.0
|
||||
|
||||
### Backend 1.6.0
|
||||
### Backend 1.7.0
|
||||
|
||||
| ID | Приоритет | Задача | Результат / критерий приёмки |
|
||||
|---|---|---|---|
|
||||
@@ -84,7 +85,7 @@
|
||||
| BE-160-02 | P1 | Надёжные email-напоминания | Настройки пользователя и очередь напоминаний хранятся в БД; отправка идемпотентна, ошибки ретраятся ограниченно и логируются без PII. Расписание запуска — внешний cron/worker, а не `setInterval` в каждом web-инстансе. |
|
||||
| BE-160-03 | P2 | Подписка на персональный iCalendar | Выдать отдельный отзывной секретный URL только для read-only календаря пользователя. Нужны лимитирование, отсутствие email/заметок в ICS и отзыв/ротация токена. |
|
||||
|
||||
### Frontend 0.9.0
|
||||
### Frontend 1.0.0
|
||||
|
||||
| ID | Приоритет | Задача | Результат / критерий приёмки |
|
||||
|---|---|---|---|
|
||||
@@ -92,9 +93,9 @@
|
||||
| FE-090-02 | P1 | Настройки напоминаний | Опт-ин по email и выбор сроков до старта; понятно отображаются часовой пояс и факт отключения рассылки. |
|
||||
| FE-090-03 | P2 | Управление iCalendar-подпиской | Экран показывает URL только по явному действию, даёт скопировать, отозвать и выпустить новый. Одноразовый экспорт из `0.8.0` остаётся доступным без подписки. |
|
||||
|
||||
## P3 — BE 1.7.0 / FE 1.0.0
|
||||
## P3 — BE 1.8.0 / FE 1.1.0
|
||||
|
||||
### Backend 1.7.0
|
||||
### Backend 1.8.0
|
||||
|
||||
| ID | Приоритет | Задача | Результат / критерий приёмки |
|
||||
|---|---|---|---|
|
||||
@@ -102,7 +103,7 @@
|
||||
| BE-170-02 | P0 | Наблюдаемость без утечки данных | Структурированные логи с request ID, готовность БД, счётчики ошибок и alert на недоступность. Email, пароли, токены, cookie и текст заметок не логируются. |
|
||||
| BE-170-03 | P1 | Машиночитаемый API-контракт | OpenAPI-спецификация синхронизирована с маршрутам и используется в CI для проверки ключевых ответов. Это предотвращает повторное расхождение документации и реализации. |
|
||||
|
||||
### Frontend 1.0.0
|
||||
### Frontend 1.1.0
|
||||
|
||||
| ID | Приоритет | Задача | Результат / критерий приёмки |
|
||||
|---|---|---|---|
|
||||
@@ -132,3 +133,14 @@
|
||||
2. `BE-142-01` и `BE-142-02`: зафиксировать настоящий контракт и закрыть trust boundary.
|
||||
3. `BE-142-03`: убрать SSRF-риск до любого расширения автозагрузки обложек.
|
||||
4. `FE-071-01`–`FE-071-06`: устранить неверную аналитику и ошибки критических форм, включая понятное завершение подтверждения email и ввод результата.
|
||||
|
||||
## Выполненный спринт
|
||||
|
||||
**Цель:** пользователь быстро находит старты, восстанавливает данные истории, выгружает результат и видит прогресс в поддерживаемой chart-визуализации.
|
||||
|
||||
1. `BE-150-04` + `FE-080-07`: восстановление обложек существующих стартов и управление официальной страницей, включая прошедшие старты. Ручные обложки не перезаписываются; используется существующая SSRF-защищённая логика.
|
||||
2. `BE-150-03` + `FE-080-02`: фильтры по статусу, периоду и дистанции, поиск по названию, сортировка и синхронизация с URL. Обновить API-документацию и контрактные тесты.
|
||||
3. `FE-080-03`: экспорт текущей отфильтрованной выборки в CSV и одноразовый `.ics` без нового backend и зависимостей.
|
||||
4. `FE-080-08`: заменить самописный SVG-график прогресса на AG Charts. Сохранить текущие данные и метрики, подписи осей, tooltip, клавиатурную доступность, переход по точке в старт, адаптивность и пустое состояние. Не менять API и не добавлять новую обёртку поверх `PaceTrendChart`.
|
||||
|
||||
`BE-150-02` в спринт не брать до решения: удаление аккаунта сразу или с 30-дневным восстановлением.
|
||||
|
||||
Reference in New Issue
Block a user