2026-01-05 07:15:50 +07:00
|
|
|
|
"""Seed shop items (frames, titles, consumables)
|
|
|
|
|
|
|
|
|
|
|
|
Revision ID: 024_seed_shop_items
|
|
|
|
|
|
Revises: 023_add_shop_system
|
|
|
|
|
|
Create Date: 2025-01-05
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
from typing import Sequence, Union
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
|
|
|
|
from alembic import op
|
|
|
|
|
|
import sqlalchemy as sa
|
|
|
|
|
|
from sqlalchemy import inspect
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
|
|
|
|
revision: str = '024_seed_shop_items'
|
|
|
|
|
|
down_revision: Union[str, None] = '023_add_shop_system'
|
|
|
|
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def table_exists(table_name: str) -> bool:
|
|
|
|
|
|
bind = op.get_bind()
|
|
|
|
|
|
inspector = inspect(bind)
|
|
|
|
|
|
return table_name in inspector.get_table_names()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def upgrade() -> None:
|
|
|
|
|
|
if not table_exists('shop_items'):
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
now = datetime.utcnow()
|
|
|
|
|
|
|
|
|
|
|
|
# Таблица shop_items
|
|
|
|
|
|
shop_items = sa.table(
|
|
|
|
|
|
'shop_items',
|
|
|
|
|
|
sa.column('id', sa.Integer),
|
|
|
|
|
|
sa.column('item_type', sa.String),
|
|
|
|
|
|
sa.column('code', sa.String),
|
|
|
|
|
|
sa.column('name', sa.String),
|
|
|
|
|
|
sa.column('description', sa.Text),
|
|
|
|
|
|
sa.column('price', sa.Integer),
|
|
|
|
|
|
sa.column('rarity', sa.String),
|
|
|
|
|
|
sa.column('asset_data', sa.JSON),
|
|
|
|
|
|
sa.column('is_active', sa.Boolean),
|
|
|
|
|
|
sa.column('created_at', sa.DateTime),
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# === Рамки аватара ===
|
|
|
|
|
|
frames = [
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'frame',
|
|
|
|
|
|
'code': 'frame_bronze',
|
|
|
|
|
|
'name': 'Бронзовая рамка',
|
|
|
|
|
|
'description': 'Простая бронзовая рамка для начинающих',
|
|
|
|
|
|
'price': 50,
|
|
|
|
|
|
'rarity': 'common',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'border_color': '#CD7F32',
|
|
|
|
|
|
'border_width': 3,
|
|
|
|
|
|
'border_style': 'solid'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'frame',
|
|
|
|
|
|
'code': 'frame_silver',
|
|
|
|
|
|
'name': 'Серебряная рамка',
|
|
|
|
|
|
'description': 'Элегантная серебряная рамка',
|
|
|
|
|
|
'price': 100,
|
|
|
|
|
|
'rarity': 'uncommon',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'border_color': '#C0C0C0',
|
|
|
|
|
|
'border_width': 3,
|
|
|
|
|
|
'border_style': 'solid'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'frame',
|
|
|
|
|
|
'code': 'frame_gold',
|
|
|
|
|
|
'name': 'Золотая рамка',
|
|
|
|
|
|
'description': 'Престижная золотая рамка',
|
|
|
|
|
|
'price': 200,
|
|
|
|
|
|
'rarity': 'rare',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'border_color': '#FFD700',
|
|
|
|
|
|
'border_width': 4,
|
|
|
|
|
|
'border_style': 'solid'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'frame',
|
|
|
|
|
|
'code': 'frame_diamond',
|
|
|
|
|
|
'name': 'Бриллиантовая рамка',
|
|
|
|
|
|
'description': 'Сверкающая бриллиантовая рамка для истинных ценителей',
|
|
|
|
|
|
'price': 500,
|
|
|
|
|
|
'rarity': 'epic',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'border_color': '#B9F2FF',
|
|
|
|
|
|
'border_width': 4,
|
|
|
|
|
|
'border_style': 'double',
|
|
|
|
|
|
'glow': True,
|
|
|
|
|
|
'glow_color': '#B9F2FF'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'frame',
|
|
|
|
|
|
'code': 'frame_fire',
|
|
|
|
|
|
'name': 'Огненная рамка',
|
|
|
|
|
|
'description': 'Анимированная рамка с эффектом пламени',
|
|
|
|
|
|
'price': 1000,
|
|
|
|
|
|
'rarity': 'legendary',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'border_style': 'gradient',
|
|
|
|
|
|
'gradient': ['#FF4500', '#FF8C00', '#FFD700'],
|
|
|
|
|
|
'animated': True,
|
|
|
|
|
|
'animation': 'fire-pulse'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'frame',
|
|
|
|
|
|
'code': 'frame_neon',
|
|
|
|
|
|
'name': 'Неоновая рамка',
|
|
|
|
|
|
'description': 'Яркая неоновая рамка с свечением',
|
|
|
|
|
|
'price': 800,
|
|
|
|
|
|
'rarity': 'epic',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'border_color': '#00FF00',
|
|
|
|
|
|
'border_width': 3,
|
|
|
|
|
|
'glow': True,
|
|
|
|
|
|
'glow_color': '#00FF00',
|
|
|
|
|
|
'glow_intensity': 10
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'frame',
|
|
|
|
|
|
'code': 'frame_rainbow',
|
|
|
|
|
|
'name': 'Радужная рамка',
|
|
|
|
|
|
'description': 'Переливающаяся радужная рамка',
|
|
|
|
|
|
'price': 1500,
|
|
|
|
|
|
'rarity': 'legendary',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'border_style': 'gradient',
|
|
|
|
|
|
'gradient': ['#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#4B0082', '#9400D3'],
|
|
|
|
|
|
'animated': True,
|
|
|
|
|
|
'animation': 'rainbow-rotate'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# === Титулы ===
|
|
|
|
|
|
titles = [
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'title',
|
|
|
|
|
|
'code': 'title_newcomer',
|
|
|
|
|
|
'name': 'Новичок',
|
|
|
|
|
|
'description': 'Первый шаг в мир марафонов',
|
|
|
|
|
|
'price': 30,
|
|
|
|
|
|
'rarity': 'common',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'text': 'Новичок',
|
|
|
|
|
|
'color': '#808080'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'title',
|
|
|
|
|
|
'code': 'title_runner',
|
|
|
|
|
|
'name': 'Марафонец',
|
|
|
|
|
|
'description': 'Опытный участник марафонов',
|
|
|
|
|
|
'price': 100,
|
|
|
|
|
|
'rarity': 'uncommon',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'text': 'Марафонец',
|
|
|
|
|
|
'color': '#4169E1'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'title',
|
|
|
|
|
|
'code': 'title_hunter',
|
|
|
|
|
|
'name': 'Охотник за челленджами',
|
|
|
|
|
|
'description': 'Мастер выполнения сложных заданий',
|
|
|
|
|
|
'price': 200,
|
|
|
|
|
|
'rarity': 'rare',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'text': 'Охотник за челленджами',
|
|
|
|
|
|
'color': '#228B22'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'title',
|
|
|
|
|
|
'code': 'title_veteran',
|
|
|
|
|
|
'name': 'Ветеран',
|
|
|
|
|
|
'description': 'Закаленный в боях участник',
|
|
|
|
|
|
'price': 300,
|
|
|
|
|
|
'rarity': 'rare',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'text': 'Ветеран',
|
|
|
|
|
|
'color': '#8B4513'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'title',
|
|
|
|
|
|
'code': 'title_champion',
|
|
|
|
|
|
'name': 'Чемпион',
|
|
|
|
|
|
'description': 'Победитель марафонов',
|
|
|
|
|
|
'price': 500,
|
|
|
|
|
|
'rarity': 'epic',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'text': 'Чемпион',
|
|
|
|
|
|
'color': '#FFD700',
|
|
|
|
|
|
'icon': 'trophy'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'title',
|
|
|
|
|
|
'code': 'title_legend',
|
|
|
|
|
|
'name': 'Легенда',
|
|
|
|
|
|
'description': 'Легендарный участник марафонов',
|
|
|
|
|
|
'price': 1000,
|
|
|
|
|
|
'rarity': 'legendary',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'text': 'Легенда',
|
|
|
|
|
|
'color': '#FF4500',
|
|
|
|
|
|
'glow': True,
|
|
|
|
|
|
'icon': 'star'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# === Цвета никнейма ===
|
|
|
|
|
|
name_colors = [
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'name_color',
|
|
|
|
|
|
'code': 'color_red',
|
|
|
|
|
|
'name': 'Красный ник',
|
|
|
|
|
|
'description': 'Яркий красный цвет никнейма',
|
|
|
|
|
|
'price': 150,
|
|
|
|
|
|
'rarity': 'uncommon',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'style': 'solid',
|
|
|
|
|
|
'color': '#FF4444'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'name_color',
|
|
|
|
|
|
'code': 'color_blue',
|
|
|
|
|
|
'name': 'Синий ник',
|
|
|
|
|
|
'description': 'Глубокий синий цвет никнейма',
|
|
|
|
|
|
'price': 150,
|
|
|
|
|
|
'rarity': 'uncommon',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'style': 'solid',
|
|
|
|
|
|
'color': '#4444FF'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'name_color',
|
|
|
|
|
|
'code': 'color_green',
|
|
|
|
|
|
'name': 'Зеленый ник',
|
|
|
|
|
|
'description': 'Сочный зеленый цвет никнейма',
|
|
|
|
|
|
'price': 150,
|
|
|
|
|
|
'rarity': 'uncommon',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'style': 'solid',
|
|
|
|
|
|
'color': '#44FF44'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'name_color',
|
|
|
|
|
|
'code': 'color_purple',
|
|
|
|
|
|
'name': 'Фиолетовый ник',
|
|
|
|
|
|
'description': 'Королевский фиолетовый цвет',
|
|
|
|
|
|
'price': 200,
|
|
|
|
|
|
'rarity': 'rare',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'style': 'solid',
|
|
|
|
|
|
'color': '#9932CC'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'name_color',
|
|
|
|
|
|
'code': 'color_gold',
|
|
|
|
|
|
'name': 'Золотой ник',
|
|
|
|
|
|
'description': 'Престижный золотой цвет',
|
|
|
|
|
|
'price': 300,
|
|
|
|
|
|
'rarity': 'rare',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'style': 'solid',
|
|
|
|
|
|
'color': '#FFD700'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'name_color',
|
|
|
|
|
|
'code': 'color_gradient_sunset',
|
|
|
|
|
|
'name': 'Закат',
|
|
|
|
|
|
'description': 'Красивый градиент заката',
|
|
|
|
|
|
'price': 500,
|
|
|
|
|
|
'rarity': 'epic',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'style': 'gradient',
|
|
|
|
|
|
'gradient': ['#FF6B6B', '#FFE66D']
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'name_color',
|
|
|
|
|
|
'code': 'color_gradient_ocean',
|
|
|
|
|
|
'name': 'Океан',
|
|
|
|
|
|
'description': 'Градиент морских глубин',
|
|
|
|
|
|
'price': 500,
|
|
|
|
|
|
'rarity': 'epic',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'style': 'gradient',
|
|
|
|
|
|
'gradient': ['#4ECDC4', '#44A3FF']
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'name_color',
|
|
|
|
|
|
'code': 'color_rainbow',
|
|
|
|
|
|
'name': 'Радужный ник',
|
|
|
|
|
|
'description': 'Анимированный радужный цвет',
|
|
|
|
|
|
'price': 1000,
|
|
|
|
|
|
'rarity': 'legendary',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'style': 'animated',
|
|
|
|
|
|
'animation': 'rainbow-shift'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# === Фоны профиля ===
|
|
|
|
|
|
backgrounds = [
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'background',
|
|
|
|
|
|
'code': 'bg_dark',
|
|
|
|
|
|
'name': 'Тёмный фон',
|
|
|
|
|
|
'description': 'Элегантный тёмный фон',
|
|
|
|
|
|
'price': 100,
|
|
|
|
|
|
'rarity': 'common',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'type': 'solid',
|
|
|
|
|
|
'color': '#1a1a2e'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'background',
|
|
|
|
|
|
'code': 'bg_gradient_purple',
|
|
|
|
|
|
'name': 'Фиолетовый градиент',
|
|
|
|
|
|
'description': 'Красивый фиолетовый градиент',
|
|
|
|
|
|
'price': 200,
|
|
|
|
|
|
'rarity': 'uncommon',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'type': 'gradient',
|
|
|
|
|
|
'gradient': ['#1a1a2e', '#4a0080']
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'background',
|
|
|
|
|
|
'code': 'bg_stars',
|
|
|
|
|
|
'name': 'Звёздное небо',
|
|
|
|
|
|
'description': 'Фон с мерцающими звёздами',
|
|
|
|
|
|
'price': 400,
|
|
|
|
|
|
'rarity': 'rare',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'type': 'pattern',
|
|
|
|
|
|
'pattern': 'stars',
|
|
|
|
|
|
'animated': True
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'background',
|
|
|
|
|
|
'code': 'bg_gaming',
|
|
|
|
|
|
'name': 'Игровой фон',
|
|
|
|
|
|
'description': 'Фон с игровыми элементами',
|
|
|
|
|
|
'price': 500,
|
|
|
|
|
|
'rarity': 'epic',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'type': 'pattern',
|
|
|
|
|
|
'pattern': 'gaming-icons'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'background',
|
|
|
|
|
|
'code': 'bg_fire',
|
|
|
|
|
|
'name': 'Огненный фон',
|
|
|
|
|
|
'description': 'Анимированный огненный фон',
|
|
|
|
|
|
'price': 800,
|
|
|
|
|
|
'rarity': 'legendary',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'type': 'animated',
|
|
|
|
|
|
'animation': 'fire-particles'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# === Расходуемые предметы ===
|
|
|
|
|
|
consumables = [
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'consumable',
|
|
|
|
|
|
'code': 'skip',
|
|
|
|
|
|
'name': 'Пропуск',
|
|
|
|
|
|
'description': 'Пропустить текущее задание без штрафа и потери streak',
|
|
|
|
|
|
'price': 100,
|
|
|
|
|
|
'rarity': 'common',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'effect': 'skip',
|
|
|
|
|
|
'icon': 'skip-forward'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'consumable',
|
|
|
|
|
|
'code': 'shield',
|
|
|
|
|
|
'name': 'Щит',
|
|
|
|
|
|
'description': 'Защита от штрафа при следующем дропе. Streak сохраняется.',
|
|
|
|
|
|
'price': 150,
|
|
|
|
|
|
'rarity': 'uncommon',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'effect': 'shield',
|
|
|
|
|
|
'icon': 'shield'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'consumable',
|
|
|
|
|
|
'code': 'boost',
|
|
|
|
|
|
'name': 'Буст x1.5',
|
2026-01-08 08:49:51 +07:00
|
|
|
|
'description': 'Множитель очков x1.5 на текущее задание',
|
2026-01-05 07:15:50 +07:00
|
|
|
|
'price': 200,
|
|
|
|
|
|
'rarity': 'rare',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'effect': 'boost',
|
|
|
|
|
|
'multiplier': 1.5,
|
2026-01-08 08:49:51 +07:00
|
|
|
|
'one_time': True,
|
2026-01-05 07:15:50 +07:00
|
|
|
|
'icon': 'zap'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
'item_type': 'consumable',
|
|
|
|
|
|
'code': 'reroll',
|
|
|
|
|
|
'name': 'Перекрут',
|
|
|
|
|
|
'description': 'Перекрутить колесо и получить новое задание',
|
|
|
|
|
|
'price': 80,
|
|
|
|
|
|
'rarity': 'common',
|
|
|
|
|
|
'asset_data': {
|
|
|
|
|
|
'effect': 'reroll',
|
|
|
|
|
|
'icon': 'refresh-cw'
|
|
|
|
|
|
},
|
|
|
|
|
|
'is_active': True,
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# Вставляем все товары
|
|
|
|
|
|
all_items = frames + titles + name_colors + backgrounds + consumables
|
|
|
|
|
|
|
|
|
|
|
|
# Добавляем created_at ко всем товарам
|
|
|
|
|
|
for item in all_items:
|
|
|
|
|
|
item['created_at'] = now
|
|
|
|
|
|
|
|
|
|
|
|
op.bulk_insert(shop_items, all_items)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def downgrade() -> None:
|
|
|
|
|
|
# Удаляем все seed-товары по коду
|
|
|
|
|
|
op.execute("DELETE FROM shop_items WHERE code LIKE 'frame_%'")
|
|
|
|
|
|
op.execute("DELETE FROM shop_items WHERE code LIKE 'title_%'")
|
|
|
|
|
|
op.execute("DELETE FROM shop_items WHERE code LIKE 'color_%'")
|
|
|
|
|
|
op.execute("DELETE FROM shop_items WHERE code LIKE 'bg_%'")
|
|
|
|
|
|
op.execute("DELETE FROM shop_items WHERE code IN ('skip', 'shield', 'boost', 'reroll')")
|