# dev-seed-data Specification ## Purpose Dev-инструмент, который наполняет запущенное приложение тестовыми данными через публичный API: альбомы, сгенерированные фотографии и сопутствующие сущности — без прямого доступа к базе данных и хранилищу. ## 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 содержать метку прогона. При включённом флаге видео скрипт SHALL дополнительно загружать видео-фикстуры. #### Scenario: Наполнение альбомами и фото - **WHEN** скрипт запущен с числом альбомов и фотографий на альбом - **THEN** создаются указанные альбомы и фотографии, а имена альбомов помечены меткой прогона #### Scenario: Воспроизводимость - **WHEN** задан числовой seed - **THEN** структура и параметры генерируемых данных детерминированы для этого seed #### Scenario: Флаг видео - **WHEN** скрипт запущен с включённым флагом видео - **THEN** помимо изображений часть альбомов получает видео-фикстуры ### 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** используются документированные значения по умолчанию ### Requirement: Наполнение видео При включённом флаге видео скрипт SHALL загружать видео-фикстуру через общий эндпоинт загрузки; если генерация видео недоступна, скрипт SHALL пропускать видео и продолжать без ошибки. #### Scenario: Видео включено - **WHEN** включён флаг видео - **THEN** в часть альбомов загружаются видео-фикстуры, различимые по метке прогона #### Scenario: Генерация недоступна - **WHEN** видео-инструменты недоступны, а флаг видео включён - **THEN** скрипт пропускает видео и продолжает наполнение