Задача разработки: [INVENTORY-411] Создание Alembic-миграции поля storage_mode в PostgreSQL

Карточка Jira Task: Модификация реляционной схемы данных для поддержки температурных режимов

Published

July 3, 2026

Общая информация

  • Эпик: [BPDS-CORE] Интеграция Периодической Системы и Смарт-Меток
  • Домен: INVENTORY (Склад и Транзакционный учет)
  • ID Задачи: INVENTORY-411
  • Исполнитель: Назначается
  • Текущий Статус: Ready for Dev
  • Влияние на релиз: 🔴 Критическое (Блокирует программную реализацию API-метода в задаче INVENTORY-412)

Контекст и Ссылки

Задача направлена строго на изоляцию изменений реляционного слоя СУБД. В рамках архитектурного разделения труда, структура таблиц должна быть развернута на окружениях (Dev/Stage/Prod) до того, как бэкенд-разработчики начнут развертывать логику эндпоинта.

Связанные задачи в Эпике:

  • ➡️ Блокирует следующую задачу: [INVENTORY-412] Реализация API-метода PATCH /api/v1/fridge/scan-tag

Ссылки на документацию проекта:


Техническое задание для Разработчика (Scope of Work)

Необходимо сгенерировать и отладить скрипт миграции с помощью фреймворка Alembic для СУБД PostgreSQL.

1. Модификация таблицы fridge_containers

  • Добавление поля storage_mode:
    • Тип данных: VARCHAR(20) с ограничением CHECK (storage_mode IN ('CHILLED', 'FROZEN')) либо создание нативного типа PostgreSQL ENUM('CHILLED', 'FROZEN'). По соображениям производительности миграций рекомендуется VARCHAR(20).
    • Значение по умолчанию (Default): 'CHILLED'
    • Ограничение целостности: NOT NULL
  • Добавление поля updated_at:
    • Тип данных: TIMESTAMP WITH TIME ZONE
    • Ограничение целостности: NOT NULL
    • Значение по умолчанию (Default): NOW() (серверное время PostgreSQL)

2. Спецификация скрипта миграции (upgrade / downgrade)

Скрипт должен нативно поддерживать как накат, так и полный откат изменений без потери смежных данных:

  • Функция upgrade():

    def upgrade() -> None:
        # 1. Добавление колонки storage_mode со значением по умолчанию
        op.add_column('fridge_containers', sa.Column('storage_mode', sa.String(length=20), server_default='CHILLED', nullable=false))
        # 2. Добавление колонки updated_at
        op.add_column('fridge_containers', sa.Column('updated_at', sa.TIMESTAMP(timezone=true), server_default=sa.text('now()'), nullable=false))
  • Функция downgrade():

    def downgrade() -> None:
        # Последовательное каскадное удаление колонок при откате релиза
        op.drop_column('fridge_containers', 'updated_at')
        op.drop_column('fridge_containers', 'storage_mode')

Критерии приемки задачи (Definition of Done)


Архитектурный разбор методологии ведения задач

Принцип Разделения Слоев (Database vs Application Code)

В соответствии со стандартами CI/CD проекта BPDS, изменения в структуре базы данных выносятся в полностью изолированный таск. Накатывание миграций на прод выполняется независимым стейджем пайплайна до развертывания контейнеров бэкенда. Это полностью исключает ситуацию Race Condition, когда новый код FastAPI пытается обратиться к еще не существующему в БД полю storage_mode.