Files
iu 36e96cd519 feat(seed): add API test-data seeding script and make testdata target
- scripts/seed.py: stdlib HTTP client, JPEG+EXIF via optional Pillow (PNG fallback), additive-only, dry-run
- Makefile: testdata target with ALBUMS/PHOTOS/SEED/TIMEOUT and boolean flags
- README: usage section; new dev-seed-data capability spec
2026-10-11 13:27:21 +03:00

112 lines
7.7 KiB
Markdown

# Spec Delta
## Purpose
Dev-инструмент, который наполняет запущенное приложение тестовыми данными через
публичный API: альбомы, сгенерированные фотографии и сопутствующие сущности — без
прямого доступа к базе данных и хранилищу.
## ADDED Requirements
### Requirement: Запуск и аутентификация
Скрипт SHALL получать базовый URL, email и пароль из переменных окружения и SHALL
аутентифицироваться через `POST /api/auth/login`, после чего SHALL выполнять все запросы
с Bearer-токеном владельца. Пароль SHALL не приниматься аргументами командной строки и
SHALL не выводиться в поток вывода.
#### Scenario: Успешный вход
- **WHEN** заданы корректные переменные окружения и скрипт запущен
- **THEN** скрипт получает access-токен и приступает к наполнению
#### Scenario: Неверные учётные данные
- **WHEN** вход возвращает 401
- **THEN** скрипт завершается с понятным сообщением и ненулевым кодом, не создавая данных
#### Scenario: Пароль не логируется
- **WHEN** скрипт выводит ход выполнения
- **THEN** пароль и токены в вывод не попадают
### Requirement: Создание альбомов и фотографий
Скрипт SHALL создавать заданное параметрами число альбомов и фотографий в каждом от имени
аутентифицированного владельца через `POST /api/albums` и
`POST /api/albums/:id/photos`. Названия альбомов SHALL содержать метку прогона.
#### Scenario: Наполнение альбомами и фото
- **WHEN** скрипт запущен с числом альбомов и фотографий на альбом
- **THEN** создаются указанные альбомы и фотографии, а имена альбомов помечены меткой прогона
#### Scenario: Воспроизводимость
- **WHEN** задан числовой seed
- **THEN** структура и параметры генерируемых данных детерминированы для этого seed
### Requirement: Генерация изображений с EXIF
Скрипт SHALL генерировать загружаемые изображения на лету. При доступной библиотеке Pillow
он SHALL использовать JPEG с EXIF-метаданными (время съёмки, при необходимости GPS); при
отсутствии Pillow он SHALL использовать PNG без EXIF, созданный на стандартной библиотеке.
#### Scenario: Pillow доступна
- **WHEN** библиотека Pillow импортируется
- **THEN** загружаемые файлы — JPEG с датой съёмки в EXIF
#### Scenario: Pillow отсутствует
- **WHEN** библиотека Pillow недоступна
- **THEN** скрипт продолжает работу, загружая PNG без EXIF
### Requirement: Опциональные сопутствующие сущности
Скрипт SHALL создавать теги, комментарии, лайки, share-ссылки и инвайты только при явном
включении соответствующими флагами; без флагов эти сущности SHALL не создаваться.
#### Scenario: Флаги выключены
- **WHEN** скрипт запущен без опциональных флагов
- **THEN** создаются только альбомы и фотографии
#### Scenario: Сопутствующие данные включены
- **WHEN** включены флаги тегов, комментариев, лайков, share-ссылок или инвайтов
- **THEN** соответствующие сущности создаются для части фотографий или альбомов
### Requirement: Ожидание генерации вариантов
При включённом ожидании скрипт SHALL дожидаться появления превью, опрашивая
`GET /api/photos/:id` до появления `thumb_url`, с ограничением по таймауту.
#### Scenario: Варианты сгенерированы
- **WHEN** ожидание вариантов включено и варианты появились
- **THEN** скрипт продолжает после появления `thumb_url`
#### Scenario: Таймаут ожидания
- **WHEN** варианты не появились за отведённое время
- **THEN** скрипт сообщает о таймауте и продолжает, не зависая бесконечно
### Requirement: Только-добавление и сухой прогон
Скрипт SHALL работать в режиме только-добавления: SHALL не удалять и не изменять
существующие данные. Повторные запуски SHALL добавлять новые данные, различимые по метке
прогона. При сухом прогоне скрипт SHALL сообщать план и SHALL не выполнять изменяющих
запросов.
#### Scenario: Повторный запуск
- **WHEN** скрипт запускается повторно
- **THEN** существующие данные сохраняются, а новые добавляются с новой меткой прогона
#### Scenario: Сухой прогон
- **WHEN** включён режим сухого прогона
- **THEN** скрипт не отправляет запросов, изменяющих данные
### Requirement: Минимум зависимостей
Основной функционал скрипта SHALL работать на стандартной библиотеке Python, включая
HTTP-клиент; Pillow SHALL быть необязательной зависимостью.
#### Scenario: Запуск без внешних пакетов
- **WHEN** в окружении нет сторонних пакетов
- **THEN** скрипт выполняет базовое наполнение с изображениями PNG без EXIF
### Requirement: Запуск через Make-цель
Проект SHALL предоставлять Make-цель `testdata`, которая запускает скрипт наполнения и
передаёт ему числовые и булевы параметры. Цель SHALL не дублировать логику скрипта.
#### Scenario: Передача параметров
- **WHEN** цель запущена с заданными параметрами (число альбомов и фото, seed, булевы флаги)
- **THEN** соответствующие значения и флаги передаются в скрипт наполнения
#### Scenario: Значения по умолчанию
- **WHEN** цель запущена без параметров
- **THEN** используются документированные значения по умолчанию