Remove bloat

This commit is contained in:
Joakim Hellsén 2025-10-13 02:07:33 +02:00
commit 715cbf4bf0
51 changed files with 691 additions and 3032 deletions

View file

@ -1,179 +1,344 @@
# Generated by Django 5.2.4 on 2025-08-06 04:12
# Generated by Django 5.2.7 on 2025-10-13 00:00
from __future__ import annotations
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
"""Initial migration.
Args:
migrations (migrations.Migration): The base class for all migrations.
"""
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
dependencies = []
operations = [
migrations.CreateModel(
name='DropBenefit',
name="Game",
fields=[
('id', models.TextField(primary_key=True, serialize=False)),
('name', models.TextField(db_index=True)),
('image_asset_url', models.URLField(blank=True, default='', max_length=500)),
('created_at', models.DateTimeField(db_index=True)),
('entitlement_limit', models.PositiveIntegerField(default=1)),
('is_ios_available', models.BooleanField(default=False)),
('distribution_type', models.TextField(db_index=True)),
],
),
migrations.CreateModel(
name='DropBenefitEdge',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('entitlement_limit', models.PositiveIntegerField(default=1)),
('benefit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='twitch.dropbenefit')),
],
),
migrations.CreateModel(
name='Game',
fields=[
('id', models.TextField(primary_key=True, serialize=False)),
('slug', models.TextField(blank=True, db_index=True, default='')),
('display_name', models.TextField(db_index=True)),
('box_art', models.URLField(blank=True, default='', max_length=500)),
("id", models.TextField(primary_key=True, serialize=False, verbose_name="Game ID")),
(
"slug",
models.TextField(
blank=True, db_index=True, default="", help_text="Short unique identifier for the game.", max_length=200, verbose_name="Slug"
),
),
("name", models.TextField(blank=True, db_index=True, default="", verbose_name="Name")),
("display_name", models.TextField(blank=True, db_index=True, default="", verbose_name="Display name")),
("box_art", models.URLField(blank=True, default="", max_length=500, verbose_name="Box art URL")),
(
"box_art_file",
models.FileField(blank=True, help_text="Locally cached box art image served from this site.", null=True, upload_to="games/box_art/"),
),
("added_at", models.DateTimeField(auto_now_add=True, db_index=True, help_text="Timestamp when this game record was created.")),
("updated_at", models.DateTimeField(auto_now=True, help_text="Timestamp when this game record was last updated.")),
],
options={
'indexes': [models.Index(fields=['slug'], name='twitch_game_slug_a02d3c_idx'), models.Index(fields=['display_name'], name='twitch_game_display_a35ba3_idx')],
},
),
migrations.AddField(
model_name='dropbenefit',
name='game',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='drop_benefits', to='twitch.game'),
),
migrations.CreateModel(
name='Organization',
fields=[
('id', models.TextField(primary_key=True, serialize=False)),
('name', models.TextField(db_index=True)),
],
options={
'indexes': [models.Index(fields=['name'], name='twitch_orga_name_febe72_idx')],
"ordering": ["display_name"],
},
),
migrations.CreateModel(
name='DropCampaign',
name="Channel",
fields=[
('id', models.TextField(primary_key=True, serialize=False)),
('name', models.TextField(db_index=True)),
('description', models.TextField(blank=True)),
('details_url', models.URLField(blank=True, default='', max_length=500)),
('account_link_url', models.URLField(blank=True, default='', max_length=500)),
('image_url', models.URLField(blank=True, default='', max_length=500)),
('start_at', models.DateTimeField(db_index=True)),
('end_at', models.DateTimeField(db_index=True)),
('is_account_connected', models.BooleanField(default=False)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('game', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='drop_campaigns', to='twitch.game')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='drop_campaigns', to='twitch.organization')),
],
),
migrations.AddField(
model_name='dropbenefit',
name='owner_organization',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='drop_benefits', to='twitch.organization'),
),
migrations.CreateModel(
name='TimeBasedDrop',
fields=[
('id', models.TextField(primary_key=True, serialize=False)),
('name', models.TextField(db_index=True)),
('required_minutes_watched', models.PositiveIntegerField(db_index=True)),
('required_subs', models.PositiveIntegerField(default=0)),
('start_at', models.DateTimeField(db_index=True)),
('end_at', models.DateTimeField(db_index=True)),
('benefits', models.ManyToManyField(related_name='drops', through='twitch.DropBenefitEdge', to='twitch.dropbenefit')),
('campaign', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='time_based_drops', to='twitch.dropcampaign')),
],
),
migrations.AddField(
model_name='dropbenefitedge',
name='drop',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='twitch.timebaseddrop'),
),
migrations.CreateModel(
name='NotificationSubscription',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('notify_found', models.BooleanField(default=False)),
('notify_live', models.BooleanField(default=False)),
('game', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='twitch.game')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('organization', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='twitch.organization')),
(
"id",
models.TextField(help_text="The unique Twitch identifier for the channel.", primary_key=True, serialize=False, verbose_name="Channel ID"),
),
("name", models.TextField(db_index=True, help_text="The lowercase username of the channel.", verbose_name="Username")),
(
"display_name",
models.TextField(db_index=True, help_text="The display name of the channel (with proper capitalization).", verbose_name="Display Name"),
),
("added_at", models.DateTimeField(auto_now_add=True, db_index=True, help_text="Timestamp when this channel record was created.")),
("updated_at", models.DateTimeField(auto_now=True, help_text="Timestamp when this channel record was last updated.")),
],
options={
'unique_together': {('user', 'game'), ('user', 'organization')},
"ordering": ["display_name"],
"indexes": [
models.Index(fields=["name"], name="twitch_chan_name_15d566_idx"),
models.Index(fields=["display_name"], name="twitch_chan_display_2bf213_idx"),
],
},
),
migrations.CreateModel(
name="DropBenefit",
fields=[
("id", models.TextField(help_text="Unique Twitch identifier for the benefit.", primary_key=True, serialize=False)),
("name", models.TextField(blank=True, db_index=True, default="N/A", help_text="Name of the drop benefit.")),
("image_asset_url", models.URLField(blank=True, default="", help_text="URL to the benefit's image asset.", max_length=500)),
(
"image_file",
models.FileField(blank=True, help_text="Locally cached benefit image served from this site.", null=True, upload_to="benefits/images/"),
),
(
"created_at",
models.DateTimeField(
db_index=True, help_text="Timestamp when the benefit was created. This is from Twitch API and not auto-generated.", null=True
),
),
("entitlement_limit", models.PositiveIntegerField(default=1, help_text="Maximum number of times this benefit can be earned.")),
("is_ios_available", models.BooleanField(default=False, help_text="Whether the benefit is available on iOS.")),
(
"distribution_type",
models.TextField(blank=True, db_index=True, default="", help_text="Type of distribution for this benefit.", max_length=50),
),
("added_at", models.DateTimeField(auto_now_add=True, db_index=True, help_text="Timestamp when this benefit record was created.")),
("updated_at", models.DateTimeField(auto_now=True, help_text="Timestamp when this benefit record was last updated.")),
],
options={
"ordering": ["-created_at"],
"indexes": [
models.Index(fields=["name"], name="twitch_drop_name_7125ff_idx"),
models.Index(fields=["created_at"], name="twitch_drop_created_a3563e_idx"),
models.Index(fields=["distribution_type"], name="twitch_drop_distrib_08b224_idx"),
models.Index(condition=models.Q(("is_ios_available", True)), fields=["is_ios_available"], name="benefit_ios_available_idx"),
],
},
),
migrations.CreateModel(
name="DropBenefitEdge",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("entitlement_limit", models.PositiveIntegerField(default=1, help_text="Max times this benefit can be claimed for this drop.")),
("added_at", models.DateTimeField(auto_now_add=True, db_index=True, help_text="Timestamp when this drop-benefit edge was created.")),
("updated_at", models.DateTimeField(auto_now=True, help_text="Timestamp when this drop-benefit edge was last updated.")),
(
"benefit",
models.ForeignKey(help_text="The benefit in this relationship.", on_delete=django.db.models.deletion.CASCADE, to="twitch.dropbenefit"),
),
],
),
migrations.CreateModel(
name="DropCampaign",
fields=[
("id", models.TextField(help_text="Unique Twitch identifier for the campaign.", primary_key=True, serialize=False)),
("name", models.TextField(db_index=True, help_text="Name of the drop campaign.")),
("description", models.TextField(blank=True, help_text="Detailed description of the campaign.")),
("details_url", models.URLField(blank=True, default="", help_text="URL with campaign details.", max_length=500)),
("account_link_url", models.URLField(blank=True, default="", help_text="URL to link a Twitch account for the campaign.", max_length=500)),
("image_url", models.URLField(blank=True, default="", help_text="URL to an image representing the campaign.", max_length=500)),
(
"image_file",
models.FileField(blank=True, help_text="Locally cached campaign image served from this site.", null=True, upload_to="campaigns/images/"),
),
("start_at", models.DateTimeField(blank=True, db_index=True, help_text="Datetime when the campaign starts.", null=True)),
("end_at", models.DateTimeField(blank=True, db_index=True, help_text="Datetime when the campaign ends.", null=True)),
("is_account_connected", models.BooleanField(default=False, help_text="Indicates if the user account is linked.")),
("allow_is_enabled", models.BooleanField(default=True, help_text="Whether the campaign allows participation.")),
("added_at", models.DateTimeField(auto_now_add=True, db_index=True, help_text="Timestamp when this campaign record was created.")),
("updated_at", models.DateTimeField(auto_now=True, help_text="Timestamp when this campaign record was last updated.")),
(
"allow_channels",
models.ManyToManyField(
blank=True,
help_text="Channels that are allowed to participate in this campaign.",
related_name="allowed_campaigns",
to="twitch.channel",
),
),
(
"game",
models.ForeignKey(
help_text="Game associated with this campaign.",
on_delete=django.db.models.deletion.CASCADE,
related_name="drop_campaigns",
to="twitch.game",
verbose_name="Game",
),
),
],
options={
"ordering": ["-start_at"],
},
),
migrations.CreateModel(
name="Organization",
fields=[
(
"id",
models.TextField(
help_text="The unique Twitch identifier for the organization.", primary_key=True, serialize=False, verbose_name="Organization ID"
),
),
("name", models.TextField(db_index=True, help_text="Display name of the organization.", unique=True, verbose_name="Name")),
("added_at", models.DateTimeField(auto_now_add=True, db_index=True, help_text="Timestamp when this organization record was created.")),
("updated_at", models.DateTimeField(auto_now=True, help_text="Timestamp when this organization record was last updated.")),
],
options={
"ordering": ["name"],
"indexes": [models.Index(fields=["name"], name="twitch_orga_name_febe72_idx")],
},
),
migrations.AddField(
model_name="game",
name="owner",
field=models.ForeignKey(
blank=True,
help_text="The organization that owns this game.",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="games",
to="twitch.organization",
verbose_name="Organization",
),
),
migrations.CreateModel(
name="TimeBasedDrop",
fields=[
("id", models.TextField(help_text="Unique Twitch identifier for the time-based drop.", primary_key=True, serialize=False)),
("name", models.TextField(db_index=True, help_text="Name of the time-based drop.")),
(
"required_minutes_watched",
models.PositiveIntegerField(blank=True, db_index=True, help_text="Minutes required to watch before earning this drop.", null=True),
),
("required_subs", models.PositiveIntegerField(default=0, help_text="Number of subscriptions required to unlock this drop.")),
("start_at", models.DateTimeField(blank=True, db_index=True, help_text="Datetime when this drop becomes available.", null=True)),
("end_at", models.DateTimeField(blank=True, db_index=True, help_text="Datetime when this drop expires.", null=True)),
("added_at", models.DateTimeField(auto_now_add=True, db_index=True, help_text="Timestamp when this time-based drop record was created.")),
("updated_at", models.DateTimeField(auto_now=True, help_text="Timestamp when this time-based drop record was last updated.")),
(
"benefits",
models.ManyToManyField(
help_text="Benefits unlocked by this drop.", related_name="drops", through="twitch.DropBenefitEdge", to="twitch.dropbenefit"
),
),
(
"campaign",
models.ForeignKey(
help_text="The campaign this drop belongs to.",
on_delete=django.db.models.deletion.CASCADE,
related_name="time_based_drops",
to="twitch.dropcampaign",
),
),
],
options={
"ordering": ["start_at"],
},
),
migrations.AddField(
model_name="dropbenefitedge",
name="drop",
field=models.ForeignKey(
help_text="The time-based drop in this relationship.", on_delete=django.db.models.deletion.CASCADE, to="twitch.timebaseddrop"
),
),
migrations.CreateModel(
name="TwitchGameData",
fields=[
("id", models.TextField(primary_key=True, serialize=False, verbose_name="Twitch Game ID")),
("name", models.TextField(blank=True, db_index=True, default="", verbose_name="Name")),
(
"box_art_url",
models.URLField(
blank=True,
default="",
help_text="URL template with {width}x{height} placeholders for the box art image.",
max_length=500,
verbose_name="Box art URL",
),
),
("igdb_id", models.TextField(blank=True, default="", verbose_name="IGDB ID")),
("added_at", models.DateTimeField(auto_now_add=True, db_index=True, help_text="Record creation time.")),
("updated_at", models.DateTimeField(auto_now=True, help_text="Record last update time.")),
(
"game",
models.ForeignKey(
blank=True,
help_text="Optional link to the local Game record for this Twitch game.",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="twitch_game_data",
to="twitch.game",
verbose_name="Game",
),
),
],
options={
"ordering": ["name"],
},
),
migrations.AddIndex(
model_name='dropcampaign',
index=models.Index(fields=['name'], name='twitch_drop_name_3b70b3_idx'),
model_name="dropcampaign",
index=models.Index(fields=["name"], name="twitch_drop_name_3b70b3_idx"),
),
migrations.AddIndex(
model_name='dropcampaign',
index=models.Index(fields=['start_at', 'end_at'], name='twitch_drop_start_a_6e5fb6_idx'),
model_name="dropcampaign",
index=models.Index(fields=["start_at", "end_at"], name="twitch_drop_start_a_6e5fb6_idx"),
),
migrations.AddIndex(
model_name='dropcampaign',
index=models.Index(fields=['game'], name='twitch_drop_game_id_868e70_idx'),
model_name="dropcampaign",
index=models.Index(
condition=models.Q(("end_at__isnull", False), ("start_at__isnull", False)), fields=["start_at", "end_at"], name="campaign_active_partial_idx"
),
),
migrations.AddConstraint(
model_name="dropcampaign",
constraint=models.CheckConstraint(
condition=models.Q(("start_at__isnull", True), ("end_at__isnull", True), ("end_at__gt", models.F("start_at")), _connector="OR"),
name="campaign_valid_date_range",
),
),
migrations.AddIndex(
model_name='dropcampaign',
index=models.Index(fields=['owner'], name='twitch_drop_owner_i_37241d_idx'),
model_name="game",
index=models.Index(fields=["display_name"], name="twitch_game_display_a35ba3_idx"),
),
migrations.AddIndex(
model_name='dropbenefit',
index=models.Index(fields=['name'], name='twitch_drop_name_7125ff_idx'),
model_name="game",
index=models.Index(fields=["name"], name="twitch_game_name_c92c15_idx"),
),
migrations.AddIndex(
model_name='dropbenefit',
index=models.Index(fields=['created_at'], name='twitch_drop_created_a3563e_idx'),
model_name="game",
index=models.Index(fields=["slug"], name="twitch_game_slug_a02d3c_idx"),
),
migrations.AddIndex(
model_name='dropbenefit',
index=models.Index(fields=['distribution_type'], name='twitch_drop_distrib_08b224_idx'),
model_name="game",
index=models.Index(condition=models.Q(("owner__isnull", False)), fields=["owner"], name="game_owner_partial_idx"),
),
migrations.AddIndex(
model_name='dropbenefit',
index=models.Index(fields=['game'], name='twitch_drop_game_id_a9209e_idx'),
model_name="timebaseddrop",
index=models.Index(fields=["name"], name="twitch_time_name_47c0f4_idx"),
),
migrations.AddIndex(
model_name='dropbenefit',
index=models.Index(fields=['owner_organization'], name='twitch_drop_owner_o_45b4cc_idx'),
model_name="timebaseddrop",
index=models.Index(fields=["start_at", "end_at"], name="twitch_time_start_a_c481f1_idx"),
),
migrations.AddIndex(
model_name='timebaseddrop',
index=models.Index(fields=['name'], name='twitch_time_name_47c0f4_idx'),
model_name="timebaseddrop",
index=models.Index(fields=["required_minutes_watched"], name="twitch_time_require_82c30c_idx"),
),
migrations.AddIndex(
model_name='timebaseddrop',
index=models.Index(fields=['start_at', 'end_at'], name='twitch_time_start_a_c481f1_idx'),
model_name="timebaseddrop",
index=models.Index(fields=["campaign", "start_at", "required_minutes_watched"], name="twitch_time_campaig_4cc3b7_idx"),
),
migrations.AddConstraint(
model_name="timebaseddrop",
constraint=models.CheckConstraint(
condition=models.Q(("start_at__isnull", True), ("end_at__isnull", True), ("end_at__gt", models.F("start_at")), _connector="OR"),
name="drop_valid_date_range",
),
),
migrations.AddConstraint(
model_name="timebaseddrop",
constraint=models.CheckConstraint(
condition=models.Q(("required_minutes_watched__isnull", True), ("required_minutes_watched__gte", 0), _connector="OR"),
name="drop_positive_minutes",
),
),
migrations.AddIndex(
model_name='timebaseddrop',
index=models.Index(fields=['campaign'], name='twitch_time_campaig_bbe349_idx'),
model_name="dropbenefitedge",
index=models.Index(fields=["drop", "benefit"], name="twitch_drop_drop_id_5a574c_idx"),
),
migrations.AddConstraint(
model_name="dropbenefitedge",
constraint=models.UniqueConstraint(fields=("drop", "benefit"), name="unique_drop_benefit"),
),
migrations.AddIndex(
model_name='timebaseddrop',
index=models.Index(fields=['required_minutes_watched'], name='twitch_time_require_82c30c_idx'),
),
migrations.AddIndex(
model_name='dropbenefitedge',
index=models.Index(fields=['drop', 'benefit'], name='twitch_drop_drop_id_5a574c_idx'),
),
migrations.AlterUniqueTogether(
name='dropbenefitedge',
unique_together={('drop', 'benefit')},
model_name="twitchgamedata",
index=models.Index(fields=["name"], name="twitch_twit_name_5dda5f_idx"),
),
]

View file

@ -1,31 +0,0 @@
# Generated by Django 5.2.5 on 2025-08-07 02:35
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='game',
name='name',
field=models.TextField(blank=True, db_index=True, default=''),
),
migrations.AlterField(
model_name='game',
name='display_name',
field=models.TextField(blank=True, db_index=True, default=''),
),
migrations.AddIndex(
model_name='game',
index=models.Index(fields=['name'], name='twitch_game_name_c92c15_idx'),
),
migrations.AddIndex(
model_name='game',
index=models.Index(fields=['box_art'], name='twitch_game_box_art_498a89_idx'),
),
]

View file

@ -1,28 +0,0 @@
# Generated by Django 5.2.5 on 2025-08-10 20:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0002_game_name_alter_game_display_name_and_more'),
]
operations = [
migrations.AlterField(
model_name='dropbenefit',
name='created_at',
field=models.DateTimeField(db_index=True, null=True),
),
migrations.AlterField(
model_name='dropbenefit',
name='distribution_type',
field=models.TextField(blank=True, db_index=True, default=''),
),
migrations.AlterField(
model_name='dropbenefit',
name='name',
field=models.TextField(blank=True, db_index=True, default='N/A'),
),
]

View file

@ -1,23 +0,0 @@
# Generated by Django 5.2.5 on 2025-08-10 20:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0003_alter_dropbenefit_created_at_and_more'),
]
operations = [
migrations.AlterField(
model_name='dropcampaign',
name='end_at',
field=models.DateTimeField(db_index=True, null=True),
),
migrations.AlterField(
model_name='dropcampaign',
name='start_at',
field=models.DateTimeField(db_index=True, null=True),
),
]

View file

@ -1,28 +0,0 @@
# Generated by Django 5.2.5 on 2025-08-10 20:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0004_alter_dropcampaign_end_at_and_more'),
]
operations = [
migrations.AlterField(
model_name='timebaseddrop',
name='end_at',
field=models.DateTimeField(db_index=True, null=True),
),
migrations.AlterField(
model_name='timebaseddrop',
name='required_minutes_watched',
field=models.PositiveIntegerField(db_index=True, null=True),
),
migrations.AlterField(
model_name='timebaseddrop',
name='start_at',
field=models.DateTimeField(db_index=True, null=True),
),
]

View file

@ -1,272 +0,0 @@
# Generated by Django 5.2.5 on 2025-09-01 17:01
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0005_alter_timebaseddrop_end_at_and_more'),
]
operations = [
migrations.AlterModelOptions(
name='dropbenefit',
options={'ordering': ['-created_at']},
),
migrations.AlterModelOptions(
name='dropcampaign',
options={'ordering': ['-start_at']},
),
migrations.AlterModelOptions(
name='game',
options={'ordering': ['display_name']},
),
migrations.AlterModelOptions(
name='organization',
options={'ordering': ['name']},
),
migrations.AlterModelOptions(
name='timebaseddrop',
options={'ordering': ['start_at']},
),
migrations.RemoveIndex(
model_name='dropbenefit',
name='twitch_drop_game_id_a9209e_idx',
),
migrations.RemoveIndex(
model_name='dropbenefit',
name='twitch_drop_owner_o_45b4cc_idx',
),
migrations.RemoveIndex(
model_name='dropcampaign',
name='twitch_drop_game_id_868e70_idx',
),
migrations.RemoveIndex(
model_name='dropcampaign',
name='twitch_drop_owner_i_37241d_idx',
),
migrations.RemoveIndex(
model_name='game',
name='twitch_game_box_art_498a89_idx',
),
migrations.RemoveIndex(
model_name='timebaseddrop',
name='twitch_time_campaig_bbe349_idx',
),
migrations.AlterUniqueTogether(
name='dropbenefitedge',
unique_together=set(),
),
migrations.RemoveField(
model_name='dropbenefit',
name='game',
),
migrations.RemoveField(
model_name='dropbenefit',
name='owner_organization',
),
migrations.RemoveField(
model_name='dropcampaign',
name='owner',
),
migrations.AddField(
model_name='game',
name='owner',
field=models.ForeignKey(blank=True, help_text='The organization that owns this game.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='games', to='twitch.organization', verbose_name='Organization'),
),
migrations.AlterField(
model_name='dropbenefit',
name='created_at',
field=models.DateTimeField(db_index=True, help_text='Timestamp when the benefit was created. This is from Twitch API and not auto-generated.', null=True),
),
migrations.AlterField(
model_name='dropbenefit',
name='distribution_type',
field=models.CharField(blank=True, db_index=True, default='', help_text='Type of distribution for this benefit.', max_length=50),
),
migrations.AlterField(
model_name='dropbenefit',
name='entitlement_limit',
field=models.PositiveIntegerField(default=1, help_text='Maximum number of times this benefit can be earned.'),
),
migrations.AlterField(
model_name='dropbenefit',
name='id',
field=models.CharField(help_text='Unique Twitch identifier for the benefit.', max_length=64, primary_key=True, serialize=False),
),
migrations.AlterField(
model_name='dropbenefit',
name='image_asset_url',
field=models.URLField(blank=True, default='', help_text="URL to the benefit's image asset.", max_length=500),
),
migrations.AlterField(
model_name='dropbenefit',
name='is_ios_available',
field=models.BooleanField(default=False, help_text='Whether the benefit is available on iOS.'),
),
migrations.AlterField(
model_name='dropbenefit',
name='name',
field=models.CharField(blank=True, db_index=True, default='N/A', help_text='Name of the drop benefit.', max_length=255),
),
migrations.AlterField(
model_name='dropbenefitedge',
name='benefit',
field=models.ForeignKey(help_text='The benefit in this relationship.', on_delete=django.db.models.deletion.CASCADE, to='twitch.dropbenefit'),
),
migrations.AlterField(
model_name='dropbenefitedge',
name='drop',
field=models.ForeignKey(help_text='The time-based drop in this relationship.', on_delete=django.db.models.deletion.CASCADE, to='twitch.timebaseddrop'),
),
migrations.AlterField(
model_name='dropbenefitedge',
name='entitlement_limit',
field=models.PositiveIntegerField(default=1, help_text='Max times this benefit can be claimed for this drop.'),
),
migrations.AlterField(
model_name='dropcampaign',
name='account_link_url',
field=models.URLField(blank=True, default='', help_text='URL to link a Twitch account for the campaign.', max_length=500),
),
migrations.AlterField(
model_name='dropcampaign',
name='created_at',
field=models.DateTimeField(auto_now_add=True, db_index=True, help_text='Timestamp when this campaign record was created.'),
),
migrations.AlterField(
model_name='dropcampaign',
name='description',
field=models.TextField(blank=True, help_text='Detailed description of the campaign.'),
),
migrations.AlterField(
model_name='dropcampaign',
name='details_url',
field=models.URLField(blank=True, default='', help_text='URL with campaign details.', max_length=500),
),
migrations.AlterField(
model_name='dropcampaign',
name='end_at',
field=models.DateTimeField(blank=True, db_index=True, help_text='Datetime when the campaign ends.', null=True),
),
migrations.AlterField(
model_name='dropcampaign',
name='game',
field=models.ForeignKey(help_text='Game associated with this campaign.', on_delete=django.db.models.deletion.CASCADE, related_name='drop_campaigns', to='twitch.game', verbose_name='Game'),
),
migrations.AlterField(
model_name='dropcampaign',
name='id',
field=models.CharField(help_text='Unique Twitch identifier for the campaign.', max_length=255, primary_key=True, serialize=False),
),
migrations.AlterField(
model_name='dropcampaign',
name='image_url',
field=models.URLField(blank=True, default='', help_text='URL to an image representing the campaign.', max_length=500),
),
migrations.AlterField(
model_name='dropcampaign',
name='is_account_connected',
field=models.BooleanField(default=False, help_text='Indicates if the user account is linked.'),
),
migrations.AlterField(
model_name='dropcampaign',
name='name',
field=models.CharField(db_index=True, help_text='Name of the drop campaign.', max_length=255),
),
migrations.AlterField(
model_name='dropcampaign',
name='start_at',
field=models.DateTimeField(blank=True, db_index=True, help_text='Datetime when the campaign starts.', null=True),
),
migrations.AlterField(
model_name='dropcampaign',
name='updated_at',
field=models.DateTimeField(auto_now=True, help_text='Timestamp when this campaign record was last updated.'),
),
migrations.AlterField(
model_name='game',
name='box_art',
field=models.URLField(blank=True, default='', max_length=500, verbose_name='Box art URL'),
),
migrations.AlterField(
model_name='game',
name='display_name',
field=models.CharField(blank=True, db_index=True, default='', max_length=255, verbose_name='Display name'),
),
migrations.AlterField(
model_name='game',
name='id',
field=models.CharField(max_length=64, primary_key=True, serialize=False, verbose_name='Game ID'),
),
migrations.AlterField(
model_name='game',
name='name',
field=models.CharField(blank=True, db_index=True, default='', max_length=255, verbose_name='Name'),
),
migrations.AlterField(
model_name='game',
name='slug',
field=models.CharField(blank=True, db_index=True, default='', help_text='Short unique identifier for the game.', max_length=200, verbose_name='Slug'),
),
migrations.AlterField(
model_name='organization',
name='id',
field=models.CharField(help_text='The unique Twitch identifier for the organization.', max_length=255, primary_key=True, serialize=False, verbose_name='Organization ID'),
),
migrations.AlterField(
model_name='organization',
name='name',
field=models.CharField(db_index=True, help_text='Display name of the organization.', max_length=255, unique=True, verbose_name='Name'),
),
migrations.AlterField(
model_name='timebaseddrop',
name='benefits',
field=models.ManyToManyField(help_text='Benefits unlocked by this drop.', related_name='drops', through='twitch.DropBenefitEdge', to='twitch.dropbenefit'),
),
migrations.AlterField(
model_name='timebaseddrop',
name='campaign',
field=models.ForeignKey(help_text='The campaign this drop belongs to.', on_delete=django.db.models.deletion.CASCADE, related_name='time_based_drops', to='twitch.dropcampaign'),
),
migrations.AlterField(
model_name='timebaseddrop',
name='end_at',
field=models.DateTimeField(blank=True, db_index=True, help_text='Datetime when this drop expires.', null=True),
),
migrations.AlterField(
model_name='timebaseddrop',
name='id',
field=models.CharField(help_text='Unique Twitch identifier for the time-based drop.', max_length=64, primary_key=True, serialize=False),
),
migrations.AlterField(
model_name='timebaseddrop',
name='name',
field=models.CharField(db_index=True, help_text='Name of the time-based drop.', max_length=255),
),
migrations.AlterField(
model_name='timebaseddrop',
name='required_minutes_watched',
field=models.PositiveIntegerField(blank=True, db_index=True, help_text='Minutes required to watch before earning this drop.', null=True),
),
migrations.AlterField(
model_name='timebaseddrop',
name='required_subs',
field=models.PositiveIntegerField(default=0, help_text='Number of subscriptions required to unlock this drop.'),
),
migrations.AlterField(
model_name='timebaseddrop',
name='start_at',
field=models.DateTimeField(blank=True, db_index=True, help_text='Datetime when this drop becomes available.', null=True),
),
migrations.AddConstraint(
model_name='dropbenefitedge',
constraint=models.UniqueConstraint(fields=('drop', 'benefit'), name='unique_drop_benefit'),
),
migrations.AddConstraint(
model_name='game',
constraint=models.UniqueConstraint(fields=('slug',), name='unique_game_slug'),
),
]

View file

@ -1,17 +0,0 @@
# Generated by Django 5.2.5 on 2025-09-01 17:06
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('twitch', '0006_alter_dropbenefit_options_alter_dropcampaign_options_and_more'),
]
operations = [
migrations.RemoveConstraint(
model_name='game',
name='unique_game_slug',
),
]

View file

@ -1,85 +0,0 @@
# Generated by Django 5.2.5 on 2025-09-04 21:00
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0007_remove_game_unique_game_slug'),
]
operations = [
migrations.RenameField(
model_name='dropcampaign',
old_name='created_at',
new_name='added_at',
),
migrations.AddField(
model_name='dropbenefit',
name='added_at',
field=models.DateTimeField(auto_now_add=True, db_index=True, default=django.utils.timezone.now, help_text='Timestamp when this benefit record was created.'),
preserve_default=False,
),
migrations.AddField(
model_name='dropbenefit',
name='updated_at',
field=models.DateTimeField(auto_now=True, help_text='Timestamp when this benefit record was last updated.'),
),
migrations.AddField(
model_name='dropbenefitedge',
name='added_at',
field=models.DateTimeField(auto_now_add=True, db_index=True, default=django.utils.timezone.now, help_text='Timestamp when this drop-benefit edge was created.'),
preserve_default=False,
),
migrations.AddField(
model_name='dropbenefitedge',
name='updated_at',
field=models.DateTimeField(auto_now=True, help_text='Timestamp when this drop-benefit edge was last updated.'),
),
migrations.AddField(
model_name='game',
name='added_at',
field=models.DateTimeField(auto_now_add=True, db_index=True, default=django.utils.timezone.now, help_text='Timestamp when this game record was created.'),
preserve_default=False,
),
migrations.AddField(
model_name='game',
name='updated_at',
field=models.DateTimeField(auto_now=True, help_text='Timestamp when this game record was last updated.'),
),
migrations.AddField(
model_name='notificationsubscription',
name='added_at',
field=models.DateTimeField(auto_now_add=True, db_index=True, default=django.utils.timezone.now),
preserve_default=False,
),
migrations.AddField(
model_name='notificationsubscription',
name='updated_at',
field=models.DateTimeField(auto_now=True),
),
migrations.AddField(
model_name='organization',
name='added_at',
field=models.DateTimeField(auto_now_add=True, db_index=True, default=django.utils.timezone.now, help_text='Timestamp when this organization record was created.'),
preserve_default=False,
),
migrations.AddField(
model_name='organization',
name='updated_at',
field=models.DateTimeField(auto_now=True, help_text='Timestamp when this organization record was last updated.'),
),
migrations.AddField(
model_name='timebaseddrop',
name='added_at',
field=models.DateTimeField(auto_now_add=True, db_index=True, default=django.utils.timezone.now, help_text='Timestamp when this time-based drop record was created.'),
preserve_default=False,
),
migrations.AddField(
model_name='timebaseddrop',
name='updated_at',
field=models.DateTimeField(auto_now=True, help_text='Timestamp when this time-based drop record was last updated.'),
),
]

View file

@ -1,52 +0,0 @@
# Generated by Django 5.2.5 on 2025-09-04 22:22
import django.contrib.postgres.indexes
import django.contrib.postgres.search
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0008_rename_created_at_dropcampaign_added_at_and_more'),
]
operations = [
migrations.AddField(
model_name='dropcampaign',
name='search_vector',
field=django.contrib.postgres.search.SearchVectorField(blank=True, null=True),
),
migrations.AddIndex(
model_name='dropbenefit',
index=models.Index(condition=models.Q(('is_ios_available', True)), fields=['is_ios_available'], name='benefit_ios_available_idx'),
),
migrations.AddIndex(
model_name='dropcampaign',
index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='campaign_search_vector_idx'),
),
migrations.AddIndex(
model_name='dropcampaign',
index=models.Index(condition=models.Q(('end_at__isnull', False), ('start_at__isnull', False)), fields=['start_at', 'end_at'], name='campaign_active_partial_idx'),
),
migrations.AddIndex(
model_name='game',
index=models.Index(condition=models.Q(('owner__isnull', False)), fields=['owner'], name='game_owner_partial_idx'),
),
migrations.AddIndex(
model_name='timebaseddrop',
index=models.Index(fields=['campaign', 'start_at', 'required_minutes_watched'], name='twitch_time_campaig_4cc3b7_idx'),
),
migrations.AddConstraint(
model_name='dropcampaign',
constraint=models.CheckConstraint(condition=models.Q(('start_at__isnull', True), ('end_at__isnull', True), ('end_at__gt', models.F('start_at')), _connector='OR'), name='campaign_valid_date_range'),
),
migrations.AddConstraint(
model_name='timebaseddrop',
constraint=models.CheckConstraint(condition=models.Q(('start_at__isnull', True), ('end_at__isnull', True), ('end_at__gt', models.F('start_at')), _connector='OR'), name='drop_valid_date_range'),
),
migrations.AddConstraint(
model_name='timebaseddrop',
constraint=models.CheckConstraint(condition=models.Q(('required_minutes_watched__isnull', True), ('required_minutes_watched__gt', 0), _connector='OR'), name='drop_positive_minutes'),
),
]

View file

@ -1,28 +0,0 @@
# Generated by Django 5.2.5 on 2025-09-04 22:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0009_postgresql_optimizations_fixed'),
]
operations = [
migrations.AlterField(
model_name='dropbenefit',
name='id',
field=models.CharField(help_text='Unique Twitch identifier for the benefit.', max_length=255, primary_key=True, serialize=False),
),
migrations.AlterField(
model_name='game',
name='id',
field=models.CharField(max_length=255, primary_key=True, serialize=False, verbose_name='Game ID'),
),
migrations.AlterField(
model_name='timebaseddrop',
name='id',
field=models.CharField(help_text='Unique Twitch identifier for the time-based drop.', max_length=255, primary_key=True, serialize=False),
),
]

View file

@ -1,21 +0,0 @@
# Generated by Django 5.2.5 on 2025-09-04 23:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0010_alter_dropbenefit_id_alter_game_id_and_more'),
]
operations = [
migrations.RemoveConstraint(
model_name='timebaseddrop',
name='drop_positive_minutes',
),
migrations.AddConstraint(
model_name='timebaseddrop',
constraint=models.CheckConstraint(condition=models.Q(('required_minutes_watched__isnull', True), ('required_minutes_watched__gte', 0), _connector='OR'), name='drop_positive_minutes'),
),
]

View file

@ -1,51 +0,0 @@
# Generated by Django 5.2.5 on 2025-09-05 11:36
import django.contrib.postgres.indexes
import django.contrib.postgres.search
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('twitch', '0011_remove_timebaseddrop_drop_positive_minutes_and_more'),
]
operations = [
migrations.AddField(
model_name='dropbenefit',
name='search_vector',
field=django.contrib.postgres.search.SearchVectorField(blank=True, null=True),
),
migrations.AddField(
model_name='game',
name='search_vector',
field=django.contrib.postgres.search.SearchVectorField(blank=True, null=True),
),
migrations.AddField(
model_name='organization',
name='search_vector',
field=django.contrib.postgres.search.SearchVectorField(blank=True, null=True),
),
migrations.AddField(
model_name='timebaseddrop',
name='search_vector',
field=django.contrib.postgres.search.SearchVectorField(blank=True, null=True),
),
migrations.AddIndex(
model_name='dropbenefit',
index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='benefit_search_vector_idx'),
),
migrations.AddIndex(
model_name='game',
index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='game_search_vector_idx'),
),
migrations.AddIndex(
model_name='organization',
index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='org_search_vector_idx'),
),
migrations.AddIndex(
model_name='timebaseddrop',
index=django.contrib.postgres.indexes.GinIndex(fields=['search_vector'], name='drop_search_vector_idx'),
),
]

View file

@ -1,37 +0,0 @@
# Generated by Django 5.2.5 on 2025-09-08 17:08
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0012_dropbenefit_search_vector_game_search_vector_and_more'),
]
operations = [
migrations.AddField(
model_name='dropcampaign',
name='allow_is_enabled',
field=models.BooleanField(default=True, help_text='Whether the campaign allows participation.'),
),
migrations.CreateModel(
name='Channel',
fields=[
('id', models.CharField(help_text='The unique Twitch identifier for the channel.', max_length=255, primary_key=True, serialize=False, verbose_name='Channel ID')),
('name', models.CharField(db_index=True, help_text='The lowercase username of the channel.', max_length=255, verbose_name='Username')),
('display_name', models.CharField(db_index=True, help_text='The display name of the channel (with proper capitalization).', max_length=255, verbose_name='Display Name')),
('added_at', models.DateTimeField(auto_now_add=True, db_index=True, help_text='Timestamp when this channel record was created.')),
('updated_at', models.DateTimeField(auto_now=True, help_text='Timestamp when this channel record was last updated.')),
],
options={
'ordering': ['display_name'],
'indexes': [models.Index(fields=['name'], name='twitch_chan_name_15d566_idx'), models.Index(fields=['display_name'], name='twitch_chan_display_2bf213_idx')],
},
),
migrations.AddField(
model_name='dropcampaign',
name='allow_channels',
field=models.ManyToManyField(blank=True, help_text='Channels that are allowed to participate in this campaign.', related_name='allowed_campaigns', to='twitch.channel'),
),
]

View file

@ -1,102 +0,0 @@
# Generated by Django 5.2.6 on 2025-09-12 22:03
import django.db.models.manager
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('twitch', '0013_dropcampaign_allow_is_enabled_channel_and_more'),
]
operations = [
migrations.AlterModelOptions(
name='channel',
options={'base_manager_name': 'prefetch_manager', 'ordering': ['display_name']},
),
migrations.AlterModelOptions(
name='dropbenefit',
options={'base_manager_name': 'prefetch_manager', 'ordering': ['-created_at']},
),
migrations.AlterModelOptions(
name='dropbenefitedge',
options={'base_manager_name': 'prefetch_manager'},
),
migrations.AlterModelOptions(
name='dropcampaign',
options={'base_manager_name': 'prefetch_manager', 'ordering': ['-start_at']},
),
migrations.AlterModelOptions(
name='game',
options={'base_manager_name': 'prefetch_manager', 'ordering': ['display_name']},
),
migrations.AlterModelOptions(
name='notificationsubscription',
options={'base_manager_name': 'prefetch_manager'},
),
migrations.AlterModelOptions(
name='organization',
options={'base_manager_name': 'prefetch_manager', 'ordering': ['name']},
),
migrations.AlterModelOptions(
name='timebaseddrop',
options={'base_manager_name': 'prefetch_manager', 'ordering': ['start_at']},
),
migrations.AlterModelManagers(
name='channel',
managers=[
('objects', django.db.models.manager.Manager()),
('prefetch_manager', django.db.models.manager.Manager()),
],
),
migrations.AlterModelManagers(
name='dropbenefit',
managers=[
('objects', django.db.models.manager.Manager()),
('prefetch_manager', django.db.models.manager.Manager()),
],
),
migrations.AlterModelManagers(
name='dropbenefitedge',
managers=[
('objects', django.db.models.manager.Manager()),
('prefetch_manager', django.db.models.manager.Manager()),
],
),
migrations.AlterModelManagers(
name='dropcampaign',
managers=[
('objects', django.db.models.manager.Manager()),
('prefetch_manager', django.db.models.manager.Manager()),
],
),
migrations.AlterModelManagers(
name='game',
managers=[
('objects', django.db.models.manager.Manager()),
('prefetch_manager', django.db.models.manager.Manager()),
],
),
migrations.AlterModelManagers(
name='notificationsubscription',
managers=[
('objects', django.db.models.manager.Manager()),
('prefetch_manager', django.db.models.manager.Manager()),
],
),
migrations.AlterModelManagers(
name='organization',
managers=[
('objects', django.db.models.manager.Manager()),
('prefetch_manager', django.db.models.manager.Manager()),
],
),
migrations.AlterModelManagers(
name='timebaseddrop',
managers=[
('objects', django.db.models.manager.Manager()),
('prefetch_manager', django.db.models.manager.Manager()),
],
),
]

View file

@ -1,57 +0,0 @@
# Generated by Django 5.2.6 on 2025-09-12 22:18
import auto_prefetch
import django.db.models.deletion
from django.conf import settings
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('twitch', '0014_alter_channel_options_alter_dropbenefit_options_and_more'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AlterField(
model_name='dropbenefitedge',
name='benefit',
field=auto_prefetch.ForeignKey(help_text='The benefit in this relationship.', on_delete=django.db.models.deletion.CASCADE, to='twitch.dropbenefit'),
),
migrations.AlterField(
model_name='dropbenefitedge',
name='drop',
field=auto_prefetch.ForeignKey(help_text='The time-based drop in this relationship.', on_delete=django.db.models.deletion.CASCADE, to='twitch.timebaseddrop'),
),
migrations.AlterField(
model_name='dropcampaign',
name='game',
field=auto_prefetch.ForeignKey(help_text='Game associated with this campaign.', on_delete=django.db.models.deletion.CASCADE, related_name='drop_campaigns', to='twitch.game', verbose_name='Game'),
),
migrations.AlterField(
model_name='game',
name='owner',
field=auto_prefetch.ForeignKey(blank=True, help_text='The organization that owns this game.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='games', to='twitch.organization', verbose_name='Organization'),
),
migrations.AlterField(
model_name='notificationsubscription',
name='game',
field=auto_prefetch.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='twitch.game'),
),
migrations.AlterField(
model_name='notificationsubscription',
name='organization',
field=auto_prefetch.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='twitch.organization'),
),
migrations.AlterField(
model_name='notificationsubscription',
name='user',
field=auto_prefetch.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='timebaseddrop',
name='campaign',
field=auto_prefetch.ForeignKey(help_text='The campaign this drop belongs to.', on_delete=django.db.models.deletion.CASCADE, related_name='time_based_drops', to='twitch.dropcampaign'),
),
]

View file

@ -1,29 +0,0 @@
from __future__ import annotations
from django.db import migrations, models
class Migration(migrations.Migration):
"""Add local image FileFields to models for caching Twitch images."""
dependencies = [
("twitch", "0015_alter_dropbenefitedge_benefit_and_more"),
]
operations = [
migrations.AddField(
model_name="game",
name="box_art_file",
field=models.FileField(blank=True, null=True, upload_to="games/box_art/"),
),
migrations.AddField(
model_name="dropcampaign",
name="image_file",
field=models.FileField(blank=True, null=True, upload_to="campaigns/images/"),
),
migrations.AddField(
model_name="dropbenefit",
name="image_file",
field=models.FileField(blank=True, null=True, upload_to="benefits/images/"),
),
]

View file

@ -1,28 +0,0 @@
# Generated by Django 5.2.6 on 2025-09-13 00:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('twitch', '0016_add_local_image_fields'),
]
operations = [
migrations.AlterField(
model_name='dropbenefit',
name='image_file',
field=models.FileField(blank=True, help_text='Locally cached benefit image served from this site.', null=True, upload_to='benefits/images/'),
),
migrations.AlterField(
model_name='dropcampaign',
name='image_file',
field=models.FileField(blank=True, help_text='Locally cached campaign image served from this site.', null=True, upload_to='campaigns/images/'),
),
migrations.AlterField(
model_name='game',
name='box_art_file',
field=models.FileField(blank=True, help_text='Locally cached box art image served from this site.', null=True, upload_to='games/box_art/'),
),
]