- 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
112 lines
7.7 KiB
Markdown
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** используются документированные значения по умолчанию
|