# Generated by Django 6.1 on 2026-08-22 11:14 import django.db.models.deletion import django.utils.timezone from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='TbBlogPost', fields=[ ('id', models.SmallAutoField(primary_key=True, serialize=False, verbose_name='ID')), ('s_title', models.CharField(help_text='HTML-заголовок (с HTML-тегами, типографированный etpgrf)', max_length=255, verbose_name='Заголовок')), ('slug', models.SlugField(max_length=200, unique=True, verbose_name='URL-слаг')), ('s_teaser', models.TextField(blank=True, help_text='HTML-контент тизера, очищенный и типографированный etpgrf', max_length=1024, verbose_name='Краткое описание / Лид')), ('s_content', models.TextField(help_text='HTML-контент статьи, очищенный и типографированный etpgrf', verbose_name='Основной HTML-контент')), ('f_cover_img', models.ImageField(blank=True, null=True, upload_to='blog/covers/%Y/', verbose_name='Обложка')), ('is_published', models.BooleanField(default=False, verbose_name='Опубликовано')), ('d_published_at', models.DateTimeField(db_index=True, default=django.utils.timezone.now, verbose_name='Дата публикации')), ('d_created_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), ('d_updated_at', models.DateTimeField(auto_now=True, verbose_name='Дата обновления')), ], options={ 'verbose_name': 'Статья блога / Страница', 'verbose_name_plural': 'Статьи блога / Страницы', 'ordering': ['-d_published_at', '-d_created_at'], }, ), migrations.CreateModel( name='TbHypn0Item', fields=[ ('id', models.AutoField(primary_key=True, serialize=False, verbose_name='ID')), ('s_hash_id', models.CharField(max_length=16, unique=True, verbose_name='ID-Хэш')), ('s_title', models.CharField(help_text='Заголовок для генерации. Включена HTML-типографика. 255 символов максимум.', max_length=255, verbose_name='Название генерации')), ('file_svg', models.FileField(help_text='Результирующий SVG-файл генерации', upload_to='svg/%Y/%m/', verbose_name='SVG-файл')), ('i_file_size', models.PositiveIntegerField(default=0, help_text='Размер файла в байтах', verbose_name='Размер файла')), ('j_metadata', models.JSONField(blank=True, default=dict, help_text='Метаданные и параметры для возможного клонирования настроек', verbose_name='Параметры генерации')), ('i_likes_count', models.PositiveIntegerField(db_index=True, default=0, verbose_name='Число лайков')), ('i_views_count', models.PositiveIntegerField(default=0, verbose_name='Число просмотров')), ('i_claims_count', models.PositiveIntegerField(default=0, verbose_name='Число жалоб')), ('f_score', models.FloatField(db_index=True, default=0.0, help_text='Рейтинг для Smart Retention и определения, что удалять при чистке по лимитам, а что оставлять', verbose_name='Рейтинг популярности')), ('i_level', models.IntegerField(choices=[(0, 'Candidate: Шум сознания'), (10, 'Voted: Плеск бессознательного'), (30, 'Moderated: Одобрено Мозговым Слизнем'), (1000, 'Locked: Глубокий транс')], default=0, help_text='Уровень', verbose_name='В какой группе находится SVG-файл генерации')), ('is_public', models.BooleanField(default=True, help_text='Доступность по прямой ссылке', verbose_name='Публичный доступ')), ('s_promo_url', models.URLField(blank=True, default='', verbose_name='Промо-ссылка')), ('s_promo_title', models.CharField(blank=True, default='', max_length=100, verbose_name='Бейдж/автор промо')), ('i_promo_clicks', models.PositiveIntegerField(default=0, verbose_name='Клики по промо')), ('d_created_at', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='Дата создания')), ('d_updated_at', models.DateTimeField(auto_now=True, db_index=True, verbose_name='Дата обновления')), ], options={ 'verbose_name': 'Гипно-картина', 'verbose_name_plural': 'Гипно-картины', 'ordering': ['-d_created_at'], }, ), migrations.CreateModel( name='TbVote', fields=[ ('id', models.BigAutoField(primary_key=True, serialize=False, verbose_name='ID')), ('i_direction', models.IntegerField(choices=[(1, 'Like (+1)'), (-2, 'Clime (-2)'), (2, 'Author Like (+2)')], default=1, help_text='Направление голоса', verbose_name='Направление')), ('s_fingerprint', models.CharField(db_index=True, help_text='SHA256(visitor_uuid + SECRET_KEY) для защиты от накрутки и разделения устройств', max_length=64, verbose_name='Хэш устройства/отпечаток')), ('d_created_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата голосования')), ('k_item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='votes', to='hypn0_site.tbhypn0item', verbose_name='Картина')), ], options={ 'verbose_name': 'Голос / Лайк', 'verbose_name_plural': 'Голоса / Лайки', 'ordering': ['-d_created_at'], 'constraints': [models.UniqueConstraint(fields=('k_item', 's_fingerprint'), name='unique_item_fingerprint_vote')], }, ), ]