From da12b0bbcf3b158179d7d2833dbe0f04d03301d3 Mon Sep 17 00:00:00 2001 From: Job Doesburg Date: Mon, 8 Apr 2024 15:06:00 +0200 Subject: [PATCH] Oeps --- website/age/migrations/0001_initial.py | 28 +++ website/age/migrations/0002_initial.py | 33 +++ .../announcements/migrations/0001_initial.py | 42 ++++ .../associations/migrations/0001_initial.py | 19 ++ website/borrel/migrations/0001_initial.py | 115 ++++++++++ website/borrel/migrations/0002_initial.py | 82 +++++++ website/fridges/migrations/0001_initial.py | 123 +++++++++++ website/fridges/migrations/0002_initial.py | 49 +++++ website/orders/migrations/0001_initial.py | 44 ++++ website/orders/migrations/0002_initial.py | 208 ++++++++++++++++++ website/silvasoft/migrations/0001_initial.py | 105 +++++++++ website/silvasoft/migrations/0002_initial.py | 72 ++++++ website/thaliedje/migrations/0001_initial.py | 167 ++++++++++++++ website/thaliedje/migrations/0002_initial.py | 90 ++++++++ .../transactions/migrations/0001_initial.py | 75 +++++++ .../transactions/migrations/0002_initial.py | 32 +++ website/users/migrations/0001_initial.py | 126 +++++++++++ website/venues/migrations/0001_initial.py | 118 ++++++++++ website/yivi/migrations/0001_initial.py | 34 +++ 19 files changed, 1562 insertions(+) create mode 100644 website/age/migrations/0001_initial.py create mode 100644 website/age/migrations/0002_initial.py create mode 100644 website/announcements/migrations/0001_initial.py create mode 100644 website/associations/migrations/0001_initial.py create mode 100644 website/borrel/migrations/0001_initial.py create mode 100644 website/borrel/migrations/0002_initial.py create mode 100644 website/fridges/migrations/0001_initial.py create mode 100644 website/fridges/migrations/0002_initial.py create mode 100644 website/orders/migrations/0001_initial.py create mode 100644 website/orders/migrations/0002_initial.py create mode 100644 website/silvasoft/migrations/0001_initial.py create mode 100644 website/silvasoft/migrations/0002_initial.py create mode 100644 website/thaliedje/migrations/0001_initial.py create mode 100644 website/thaliedje/migrations/0002_initial.py create mode 100644 website/transactions/migrations/0001_initial.py create mode 100644 website/transactions/migrations/0002_initial.py create mode 100644 website/users/migrations/0001_initial.py create mode 100644 website/venues/migrations/0001_initial.py create mode 100644 website/yivi/migrations/0001_initial.py diff --git a/website/age/migrations/0001_initial.py b/website/age/migrations/0001_initial.py new file mode 100644 index 00000000..74fc07bc --- /dev/null +++ b/website/age/migrations/0001_initial.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="AgeRegistration", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("minimum_age", models.PositiveIntegerField()), + ( + "verified_by", + models.CharField( + blank=True, choices=[("yivi", "Yivi"), ("manual", "Manually")], max_length=100, null=True + ), + ), + ("attributes", models.JSONField(blank=True, max_length=1000, null=True)), + ], + ), + ] diff --git a/website/age/migrations/0002_initial.py b/website/age/migrations/0002_initial.py new file mode 100644 index 00000000..c43740cc --- /dev/null +++ b/website/age/migrations/0002_initial.py @@ -0,0 +1,33 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("age", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="ageregistration", + name="user", + field=models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name="is_18_years_old", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="ageregistration", + name="verified_by_user", + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL + ), + ), + ] diff --git a/website/announcements/migrations/0001_initial.py b/website/announcements/migrations/0001_initial.py new file mode 100644 index 00000000..37d9cb02 --- /dev/null +++ b/website/announcements/migrations/0001_initial.py @@ -0,0 +1,42 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.db import migrations, models +import django.utils.timezone +import tinymce.models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Announcement", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ( + "title", + models.CharField( + help_text="This is not shown on the announcement but can be used as an identifier in the admin area.", + max_length=100, + ), + ), + ("content", tinymce.models.HTMLField(max_length=500)), + ("since", models.DateTimeField(default=django.utils.timezone.now)), + ("until", models.DateTimeField(blank=True, null=True)), + ( + "icon", + models.CharField( + default="bullhorn", + help_text="Font Awesome 6 abbreviation for icon to use.", + max_length=150, + verbose_name="Font Awesome 6 icon", + ), + ), + ], + options={ + "ordering": ("-since",), + }, + ), + ] diff --git a/website/associations/migrations/0001_initial.py b/website/associations/migrations/0001_initial.py new file mode 100644 index 00000000..38283f0d --- /dev/null +++ b/website/associations/migrations/0001_initial.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Association", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("name", models.CharField(max_length=150)), + ], + ), + ] diff --git a/website/borrel/migrations/0001_initial.py b/website/borrel/migrations/0001_initial.py new file mode 100644 index 00000000..32dc0073 --- /dev/null +++ b/website/borrel/migrations/0001_initial.py @@ -0,0 +1,115 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("associations", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="BasicBorrelBrevet", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("registered_on", models.DateField(auto_now_add=True)), + ], + ), + migrations.CreateModel( + name="BorrelReservation", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("submitted_at", models.DateTimeField(blank=True, null=True)), + ("title", models.CharField(max_length=100)), + ("start", models.DateTimeField()), + ("end", models.DateTimeField(blank=True, null=True)), + ("comments", models.TextField(blank=True, null=True)), + ("accepted", models.BooleanField(blank=True, default=None, null=True)), + ( + "join_code", + models.CharField( + blank=True, max_length=255, validators=[django.core.validators.MinLengthValidator(20)] + ), + ), + ( + "association", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="borrel_reservations", + to="associations.association", + ), + ), + ], + options={ + "ordering": ["-start", "-end", "title"], + }, + ), + migrations.CreateModel( + name="Product", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("name", models.CharField(max_length=100, unique=True)), + ("active", models.BooleanField(default=True)), + ("description", models.TextField(blank=True, null=True)), + ("price", models.DecimalField(decimal_places=2, max_digits=6)), + ("can_be_reserved", models.BooleanField(default=True)), + ("can_be_submitted", models.BooleanField(default=True)), + ], + ), + migrations.CreateModel( + name="ProductCategory", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("name", models.CharField(max_length=100)), + ], + options={ + "verbose_name": "product category", + "verbose_name_plural": "product categories", + }, + ), + migrations.CreateModel( + name="ReservationItem", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("product_name", models.CharField(max_length=100)), + ("product_description", models.TextField(blank=True, null=True)), + ("product_price_per_unit", models.DecimalField(decimal_places=2, max_digits=6)), + ("amount_reserved", models.PositiveIntegerField()), + ("amount_used", models.PositiveIntegerField(blank=True, null=True)), + ( + "product", + models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to="borrel.product" + ), + ), + ( + "reservation", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="items", + to="borrel.borrelreservation", + ), + ), + ], + ), + migrations.AddField( + model_name="product", + name="category", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="products", + to="borrel.productcategory", + ), + ), + ] diff --git a/website/borrel/migrations/0002_initial.py b/website/borrel/migrations/0002_initial.py new file mode 100644 index 00000000..40c63fc1 --- /dev/null +++ b/website/borrel/migrations/0002_initial.py @@ -0,0 +1,82 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("venues", "0001_initial"), + ("borrel", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="borrelreservation", + name="user_created", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="borrel_reservations_created", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="borrelreservation", + name="user_submitted", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="borrel_reservations_submitted", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="borrelreservation", + name="user_updated", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="borrel_reservations_updated", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="borrelreservation", + name="users_access", + field=models.ManyToManyField( + blank=True, related_name="borrel_reservations_access", to=settings.AUTH_USER_MODEL + ), + ), + migrations.AddField( + model_name="borrelreservation", + name="venue_reservation", + field=models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="borrel_reservations", + to="venues.reservation", + ), + ), + migrations.AddField( + model_name="basicborrelbrevet", + name="user", + field=models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name="basic_borrel_brevet", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AlterUniqueTogether( + name="reservationitem", + unique_together={("reservation", "product_name")}, + ), + ] diff --git a/website/fridges/migrations/0001_initial.py b/website/fridges/migrations/0001_initial.py new file mode 100644 index 00000000..04d379cd --- /dev/null +++ b/website/fridges/migrations/0001_initial.py @@ -0,0 +1,123 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +import datetime +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.OAUTH2_PROVIDER_APPLICATION_MODEL), + ("auth", "0012_alter_user_first_name_max_length"), + ] + + operations = [ + migrations.CreateModel( + name="AccessLog", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("timestamp", models.DateTimeField(auto_now_add=True)), + ], + options={ + "verbose_name": "access log", + "verbose_name_plural": "access logs", + "ordering": ["-timestamp"], + "get_latest_by": "timestamp", + }, + ), + migrations.CreateModel( + name="BlacklistEntry", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ], + options={ + "verbose_name": "blacklist entry", + "verbose_name_plural": "blacklist entries", + }, + ), + migrations.CreateModel( + name="Fridge", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("name", models.CharField(max_length=255)), + ("slug", models.SlugField(max_length=255, unique=True)), + ( + "is_active", + models.BooleanField( + default=True, + help_text="If the fridge is active, it will be shown on the website and can be opened by users within the set opening hours. People with 'open always' permissions can always open the fridge, regardless of whether it is active.", + ), + ), + ( + "unlock_for_how_long", + models.DurationField( + default=datetime.timedelta(seconds=60), + help_text="How long to unlock the fridge for by default (HH:MM:SS).", + ), + ), + ( + "minimum_age", + models.PositiveIntegerField( + blank=True, + default=18, + help_text="Minimum age required for a user to open the fridge. People with 'open always' permissions can always open the fridge, regardless of what their age is.", + null=True, + ), + ), + ( + "oauth_client", + models.ForeignKey( + help_text="The OAuth2 client that may request opening the fridge.", + on_delete=django.db.models.deletion.PROTECT, + related_name="fridges", + to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL, + ), + ), + ], + options={ + "verbose_name": "fridge", + "verbose_name_plural": "fridges", + "ordering": ["name"], + "permissions": [("open_always", "Can always open fridges")], + }, + ), + migrations.CreateModel( + name="GeneralOpeningHours", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ( + "weekday", + models.IntegerField( + choices=[ + (0, "Monday"), + (1, "Tuesday"), + (2, "Wednesday"), + (3, "Thursday"), + (4, "Friday"), + (5, "Saturday"), + (6, "Sunday"), + ] + ), + ), + ("start_time", models.TimeField()), + ("end_time", models.TimeField()), + ("fridge", models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="fridges.fridge")), + ( + "restrict_to_groups", + models.ManyToManyField( + blank=True, + help_text="Only allow members of these groups to open the fridge during these opening hours.", + to="auth.group", + ), + ), + ], + options={ + "verbose_name": "general opening hours", + "verbose_name_plural": "general opening hours", + "ordering": ["weekday", "start_time"], + }, + ), + ] diff --git a/website/fridges/migrations/0002_initial.py b/website/fridges/migrations/0002_initial.py new file mode 100644 index 00000000..22d9ceae --- /dev/null +++ b/website/fridges/migrations/0002_initial.py @@ -0,0 +1,49 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("venues", "0001_initial"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("fridges", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="fridge", + name="venue", + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to="venues.venue" + ), + ), + migrations.AddField( + model_name="blacklistentry", + name="fridge", + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="fridges.fridge"), + ), + migrations.AddField( + model_name="blacklistentry", + name="user", + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name="accesslog", + name="fridge", + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="fridges.fridge"), + ), + migrations.AddField( + model_name="accesslog", + name="user", + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AlterUniqueTogether( + name="generalopeninghours", + unique_together={("weekday", "start_time", "end_time", "fridge")}, + ), + ] diff --git a/website/orders/migrations/0001_initial.py b/website/orders/migrations/0001_initial.py new file mode 100644 index 00000000..61287d27 --- /dev/null +++ b/website/orders/migrations/0001_initial.py @@ -0,0 +1,44 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Order", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("created", models.DateTimeField(auto_now_add=True)), + ("order_price", models.DecimalField(decimal_places=2, max_digits=6)), + ("ready", models.BooleanField(default=False)), + ("ready_at", models.DateTimeField(blank=True, null=True)), + ("paid", models.BooleanField(default=False)), + ("paid_at", models.DateTimeField(blank=True, null=True)), + ("type", models.PositiveIntegerField(choices=[(0, "Ordered"), (1, "Scanned")], default=0)), + ( + "priority", + models.PositiveIntegerField( + choices=[(0, "Deprioritized"), (1, "Normal"), (2, "Prioritized")], default=1 + ), + ), + ], + options={ + "ordering": ["-created"], + }, + ), + migrations.CreateModel( + name="OrderBlacklistedUser", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("explanation", models.TextField(blank=True, null=True)), + ], + options={ + "verbose_name": "blacklisted user", + }, + ), + ] diff --git a/website/orders/migrations/0002_initial.py b/website/orders/migrations/0002_initial.py new file mode 100644 index 00000000..53c4f8b0 --- /dev/null +++ b/website/orders/migrations/0002_initial.py @@ -0,0 +1,208 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from decimal import Decimal +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import orders.models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("orders", "0001_initial"), + ("venues", "0001_initial"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("associations", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="OrderVenue", + fields=[ + ( + "venue", + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + primary_key=True, + serialize=False, + to="venues.venue", + ), + ), + ], + options={ + "ordering": ["venue__name"], + "permissions": [ + ("can_manage_shift_in_venue", "Can manage shifts in this venue"), + ("gets_prioritized_orders_in_venue", "Gets prioritized orders in this venue"), + ], + }, + ), + migrations.CreateModel( + name="Shift", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("start", models.DateTimeField(default=orders.models.get_default_start_time_shift)), + ("end", models.DateTimeField(default=orders.models.get_default_end_time_shift)), + ( + "can_order", + models.BooleanField( + default=False, + help_text="If checked, people can order within the given time frame. If not checked, ordering will not be possible, even in the given time frame.", + verbose_name="Orders allowed", + ), + ), + ( + "finalized", + models.BooleanField( + default=False, + help_text="If checked, shift is finalized and no alterations on the shift can be made anymore.", + verbose_name="Shift finalized", + ), + ), + ( + "max_orders_per_user", + models.PositiveSmallIntegerField( + blank=True, + default=2, + help_text="The maximum amount of products a single user can order in this shift. Empty means no limit.", + null=True, + verbose_name="Max. number of orders per user", + ), + ), + ( + "max_orders_total", + models.PositiveSmallIntegerField( + blank=True, + default=orders.models.get_default_max_orders_total, + help_text="The maximum amount of products that can be ordered during this shift in total. Empty means no limit.", + null=True, + verbose_name="Max. total number of orders", + ), + ), + ("assignees", models.ManyToManyField(to=settings.AUTH_USER_MODEL)), + ( + "venue", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="shifts", + to="orders.ordervenue", + validators=[orders.models.active_venue_validator], + ), + ), + ], + options={ + "ordering": ["-start", "-end"], + }, + ), + migrations.CreateModel( + name="Product", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("name", models.CharField(max_length=50, unique=True)), + ( + "icon", + models.CharField( + blank=True, + default="", + help_text="Font-awesome icon name that is used for quick display of the product type.", + max_length=20, + ), + ), + ("available", models.BooleanField(default=True)), + ( + "current_price", + models.DecimalField( + decimal_places=2, + max_digits=6, + validators=[django.core.validators.MinValueValidator(Decimal("0.00"))], + ), + ), + ( + "orderable", + models.BooleanField( + default=True, help_text="Whether or not this product should appear on the order page." + ), + ), + ( + "ignore_shift_restrictions", + models.BooleanField( + default=False, + help_text="Whether or not this product should ignore the maximum orders per shift restriction.", + ), + ), + ( + "max_allowed_per_shift", + models.PositiveSmallIntegerField( + blank=True, + default=2, + help_text="The maximum amount a single user can order this product in a single shift. Note that shifts are bound to the venue. Empty means no limit.", + null=True, + verbose_name="Max. allowed orders per shift", + ), + ), + ( + "barcode", + models.CharField( + blank=True, + default=None, + help_text="Either an EAN-8 or EAN-13 barcode.", + max_length=13, + null=True, + unique=True, + validators=[orders.models.validate_barcode], + ), + ), + ("available_at", models.ManyToManyField(to="orders.ordervenue")), + ], + options={ + "ordering": ["-available", "name"], + }, + ), + migrations.AddField( + model_name="orderblacklisteduser", + name="user", + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name="order", + name="product", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="orders", + to="orders.product", + validators=[orders.models.available_product_filter], + ), + ), + migrations.AddField( + model_name="order", + name="shift", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, related_name="orders", to="orders.shift" + ), + ), + migrations.AddField( + model_name="order", + name="user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="orders", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="order", + name="user_association", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="orders", + to="associations.association", + ), + ), + ] diff --git a/website/silvasoft/migrations/0001_initial.py b/website/silvasoft/migrations/0001_initial.py new file mode 100644 index 00000000..a9aedf6a --- /dev/null +++ b/website/silvasoft/migrations/0001_initial.py @@ -0,0 +1,105 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="CachedProduct", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("product_number", models.CharField(max_length=100)), + ("name", models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name="CachedRelation", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("customer_number", models.IntegerField()), + ("name", models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name="SilvasoftAssociation", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("silvasoft_customer_number", models.IntegerField(unique=True)), + ], + ), + migrations.CreateModel( + name="SilvasoftBorrelProduct", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("silvasoft_product_number", models.CharField(max_length=100, unique=True)), + ("cost_center", models.CharField(blank=True, max_length=100, null=True)), + ], + ), + migrations.CreateModel( + name="SilvasoftBorrelReservationInvoice", + fields=[ + ( + "silvasoft_identifier", + models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="SilvasoftBorrelReservationSynchronization", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("created", models.DateTimeField(auto_now_add=True)), + ("succeeded", models.BooleanField()), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="SilvasoftOrderProduct", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("silvasoft_product_number", models.CharField(max_length=100, unique=True)), + ("cost_center", models.CharField(blank=True, max_length=100, null=True)), + ], + ), + migrations.CreateModel( + name="SilvasoftOrderVenue", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("silvasoft_customer_number", models.IntegerField(unique=True)), + ], + ), + migrations.CreateModel( + name="SilvasoftShiftInvoice", + fields=[ + ( + "silvasoft_identifier", + models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="SilvasoftShiftSynchronization", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("created", models.DateTimeField(auto_now_add=True)), + ("succeeded", models.BooleanField()), + ], + options={ + "abstract": False, + }, + ), + ] diff --git a/website/silvasoft/migrations/0002_initial.py b/website/silvasoft/migrations/0002_initial.py new file mode 100644 index 00000000..40aa3184 --- /dev/null +++ b/website/silvasoft/migrations/0002_initial.py @@ -0,0 +1,72 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("orders", "0002_initial"), + ("silvasoft", "0001_initial"), + ("borrel", "0002_initial"), + ("associations", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="silvasoftshiftsynchronization", + name="shift", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="silvasoft_synchronization", + to="orders.shift", + ), + ), + migrations.AddField( + model_name="silvasoftshiftinvoice", + name="shift", + field=models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, related_name="silvasoft_invoice", to="orders.shift" + ), + ), + migrations.AddField( + model_name="silvasoftordervenue", + name="order_venue", + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to="orders.ordervenue"), + ), + migrations.AddField( + model_name="silvasoftorderproduct", + name="product", + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to="orders.product"), + ), + migrations.AddField( + model_name="silvasoftborrelreservationsynchronization", + name="borrel_reservation", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="silvasoft_synchronization", + to="borrel.borrelreservation", + ), + ), + migrations.AddField( + model_name="silvasoftborrelreservationinvoice", + name="borrel_reservation", + field=models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name="silvasoft_invoice", + to="borrel.borrelreservation", + ), + ), + migrations.AddField( + model_name="silvasoftborrelproduct", + name="product", + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to="borrel.product"), + ), + migrations.AddField( + model_name="silvasoftassociation", + name="association", + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to="associations.association"), + ), + ] diff --git a/website/thaliedje/migrations/0001_initial.py b/website/thaliedje/migrations/0001_initial.py new file mode 100644 index 00000000..3127a9e3 --- /dev/null +++ b/website/thaliedje/migrations/0001_initial.py @@ -0,0 +1,167 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Player", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("display_name", models.CharField(blank=True, default="", max_length=255)), + ("slug", models.SlugField(max_length=100, unique=True)), + ], + options={ + "verbose_name": "Player", + "verbose_name_plural": "Players", + "permissions": [ + ("can_control", "Can control music players"), + ("can_request_playlists_and_albums", "Can request playlists and albums"), + ], + }, + ), + migrations.CreateModel( + name="PlayerLogEntry", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("action", models.CharField(max_length=255)), + ("timestamp", models.DateTimeField(auto_now_add=True)), + ("description", models.CharField(max_length=255)), + ], + options={ + "verbose_name": "player log entry", + "verbose_name_plural": "player log entries", + }, + ), + migrations.CreateModel( + name="SpotifyArtist", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("artist_name", models.CharField(max_length=255)), + ("artist_id", models.CharField(max_length=255, unique=True)), + ], + ), + migrations.CreateModel( + name="SpotifyQueueItem", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("added", models.DateTimeField(auto_now_add=True)), + ], + options={ + "ordering": ["-added"], + }, + ), + migrations.CreateModel( + name="SpotifyTrack", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("track_id", models.CharField(max_length=255, unique=True)), + ("track_name", models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name="ThaliedjeBlacklistedUser", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("explanation", models.TextField(blank=True, null=True)), + ], + options={ + "verbose_name": "blacklisted user", + }, + ), + migrations.CreateModel( + name="ThaliedjeControlEvent", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("association_can_request", models.BooleanField(default=False)), + ("association_can_control", models.BooleanField(default=False)), + ("association_can_request_playlist", models.BooleanField(default=False)), + ( + "join_code", + models.CharField( + blank=True, + max_length=255, + null=True, + validators=[django.core.validators.MinLengthValidator(20)], + ), + ), + ("selected_users_can_request", models.BooleanField(default=False)), + ("selected_users_can_control", models.BooleanField(default=False)), + ("selected_users_can_request_playlist", models.BooleanField(default=False)), + ("everyone_can_request", models.BooleanField(default=False)), + ("everyone_can_control", models.BooleanField(default=False)), + ("everyone_can_request_playlist", models.BooleanField(default=False)), + ("respect_blacklist", models.BooleanField(default=True)), + ("check_throttling", models.BooleanField(default=True)), + ], + options={ + "verbose_name": "control event", + "verbose_name_plural": "control events", + }, + ), + migrations.CreateModel( + name="MarietjePlayer", + fields=[ + ( + "player_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="thaliedje.player", + ), + ), + ("url", models.URLField(default="", max_length=255)), + ("client_id", models.CharField(max_length=100)), + ("client_secret", models.CharField(max_length=255)), + ], + bases=("thaliedje.player",), + ), + migrations.CreateModel( + name="SpotifyPlayer", + fields=[ + ( + "player_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="thaliedje.player", + ), + ), + ("playback_device_id", models.CharField(blank=True, default="", max_length=255)), + ( + "playback_device_name", + models.CharField( + blank=True, + default="", + help_text="When configuring this Spotify account for the first time, make sure to have the Spotify account active on at least one playback device to complete configuration.", + max_length=255, + ), + ), + ("client_id", models.CharField(max_length=255, unique=True)), + ("client_secret", models.CharField(max_length=255)), + ("redirect_uri", models.CharField(max_length=255)), + ], + options={ + "verbose_name": "Spotify player", + "verbose_name_plural": "Spotify players", + "permissions": [ + ("can_control", "Can control music players"), + ("can_request_playlists_and_albums", "Can request playlists and albums"), + ], + }, + bases=("thaliedje.player",), + ), + ] diff --git a/website/thaliedje/migrations/0002_initial.py b/website/thaliedje/migrations/0002_initial.py new file mode 100644 index 00000000..87c4971e --- /dev/null +++ b/website/thaliedje/migrations/0002_initial.py @@ -0,0 +1,90 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("venues", "0001_initial"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("thaliedje", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="thaliedjecontrolevent", + name="event", + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to="venues.reservation"), + ), + migrations.AddField( + model_name="thaliedjecontrolevent", + name="selected_users", + field=models.ManyToManyField( + blank=True, related_name="thaliedje_control_events", to=settings.AUTH_USER_MODEL + ), + ), + migrations.AddField( + model_name="thaliedjeblacklisteduser", + name="user", + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name="spotifytrack", + name="track_artists", + field=models.ManyToManyField(to="thaliedje.spotifyartist"), + ), + migrations.AddField( + model_name="spotifyqueueitem", + name="player", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name="requests", to="thaliedje.player" + ), + ), + migrations.AddField( + model_name="spotifyqueueitem", + name="requested_by", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="requests", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="spotifyqueueitem", + name="track", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="requests", + to="thaliedje.spotifytrack", + ), + ), + migrations.AddField( + model_name="playerlogentry", + name="player", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name="logs", to="thaliedje.player" + ), + ), + migrations.AddField( + model_name="playerlogentry", + name="user", + field=models.ForeignKey( + blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL + ), + ), + migrations.AddField( + model_name="player", + name="venue", + field=models.OneToOneField( + blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to="venues.venue" + ), + ), + ] diff --git a/website/transactions/migrations/0001_initial.py b/website/transactions/migrations/0001_initial.py new file mode 100644 index 00000000..9b64d75c --- /dev/null +++ b/website/transactions/migrations/0001_initial.py @@ -0,0 +1,75 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("contenttypes", "0002_remove_content_type_name"), + ] + + operations = [ + migrations.CreateModel( + name="Account", + fields=[ + ("id", models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ("created_at", models.DateTimeField(auto_now_add=True)), + ], + options={ + "verbose_name": "account", + "verbose_name_plural": "accounts", + "ordering": ["created_at"], + "get_latest_by": "created_at", + }, + ), + migrations.CreateModel( + name="Transaction", + fields=[ + ("id", models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ("amount", models.DecimalField(decimal_places=2, max_digits=10)), + ("timestamp", models.DateTimeField(auto_now_add=True)), + ("description", models.CharField(max_length=255)), + ("payable_object_id", models.CharField(blank=True, max_length=255, null=True)), + ("_balance_after", models.DecimalField(decimal_places=2, editable=False, max_digits=10)), + ( + "_previous_transaction", + models.OneToOneField( + blank=True, + editable=False, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="_next_transaction", + to="transactions.transaction", + ), + ), + ( + "account", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="transactions", + to="transactions.account", + ), + ), + ( + "payable_content_type", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="contenttypes.contenttype", + ), + ), + ], + options={ + "verbose_name": "transaction", + "verbose_name_plural": "transactions", + "ordering": ["timestamp"], + "get_latest_by": "timestamp", + }, + ), + ] diff --git a/website/transactions/migrations/0002_initial.py b/website/transactions/migrations/0002_initial.py new file mode 100644 index 00000000..e15bf518 --- /dev/null +++ b/website/transactions/migrations/0002_initial.py @@ -0,0 +1,32 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("transactions", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="transaction", + name="processor", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="transactions_processed", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="account", + name="user", + field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/website/users/migrations/0001_initial.py b/website/users/migrations/0001_initial.py new file mode 100644 index 00000000..5c46ac02 --- /dev/null +++ b/website/users/migrations/0001_initial.py @@ -0,0 +1,126 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("auth", "0012_alter_user_first_name_max_length"), + ("associations", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="GroupSettings", + fields=[ + ( + "group", + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + primary_key=True, + related_name="settings", + serialize=False, + to="auth.group", + ), + ), + ( + "gets_staff_permissions", + models.BooleanField( + default=False, + help_text="If enabled, all members added to this group will automatically get staff status after their next login. This staff status will not be automatically revoked, though, if the user leaves the group.", + ), + ), + ( + "display_on_website", + models.BooleanField( + default=False, + help_text="If enabled, the members of this group will be displayed on a webpage.", + ), + ), + ], + options={ + "ordering": ["group__name"], + }, + ), + migrations.CreateModel( + name="User", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("password", models.CharField(max_length=128, verbose_name="password")), + ("last_login", models.DateTimeField(blank=True, null=True, verbose_name="last login")), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ("first_name", models.CharField(blank=True, max_length=150, verbose_name="first name")), + ("last_name", models.CharField(blank=True, max_length=150, verbose_name="last name")), + ( + "is_staff", + models.BooleanField( + default=False, + help_text="Designates whether the user can log into this admin site.", + verbose_name="staff status", + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", + verbose_name="active", + ), + ), + ("date_joined", models.DateTimeField(default=django.utils.timezone.now, verbose_name="date joined")), + ("username", models.CharField(max_length=30, unique=True)), + ("email", models.EmailField(max_length=254, unique=True)), + ("full_name", models.CharField(max_length=100)), + ("override_display_name", models.CharField(blank=True, max_length=100, null=True)), + ("override_short_name", models.CharField(blank=True, max_length=50, null=True)), + ( + "association", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="users", + to="associations.association", + ), + ), + ( + "groups", + models.ManyToManyField( + blank=True, + help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", + related_name="user_set", + related_query_name="user", + to="auth.group", + verbose_name="groups", + ), + ), + ( + "user_permissions", + models.ManyToManyField( + blank=True, + help_text="Specific permissions for this user.", + related_name="user_set", + related_query_name="user", + to="auth.permission", + verbose_name="user permissions", + ), + ), + ], + options={ + "verbose_name": "user", + "verbose_name_plural": "users", + "abstract": False, + }, + ), + ] diff --git a/website/venues/migrations/0001_initial.py b/website/venues/migrations/0001_initial.py new file mode 100644 index 00000000..991b86aa --- /dev/null +++ b/website/venues/migrations/0001_initial.py @@ -0,0 +1,118 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("associations", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="Venue", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("name", models.CharField(max_length=50, unique=True)), + ("slug", models.SlugField(max_length=100, unique=True)), + ("active", models.BooleanField(default=True)), + ( + "color_in_calendar", + models.CharField( + blank=True, help_text="Color of reservations shown in calendar.", max_length=50, null=True + ), + ), + ("can_be_reserved", models.BooleanField(default=True)), + ( + "automatically_accept_first_reservation", + models.BooleanField( + default=False, + help_text="If enabled, a reservation placed on this venue will be automatically accepted if it does not overlap with another reservation.", + ), + ), + ], + options={ + "ordering": ["-active", "name"], + }, + ), + migrations.CreateModel( + name="Reservation", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("title", models.CharField(max_length=100)), + ("start", models.DateTimeField()), + ("end", models.DateTimeField()), + ( + "needs_music_keys", + models.BooleanField( + default=False, help_text="Whether the music keys are needed during this reservation." + ), + ), + ("comments", models.TextField(blank=True, null=True)), + ("accepted", models.BooleanField(blank=True, default=None, null=True)), + ( + "join_code", + models.CharField( + blank=True, + max_length=255, + null=True, + unique=True, + validators=[django.core.validators.MinLengthValidator(20)], + ), + ), + ( + "association", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="reservations", + to="associations.association", + ), + ), + ( + "user_created", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="reservations_created", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "user_updated", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="reservations_updated", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "users_access", + models.ManyToManyField( + blank=True, related_name="reservations_access", to=settings.AUTH_USER_MODEL + ), + ), + ( + "venue", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, related_name="reservations", to="venues.venue" + ), + ), + ], + options={ + "ordering": ["-start", "-end", "title"], + }, + ), + ] diff --git a/website/yivi/migrations/0001_initial.py b/website/yivi/migrations/0001_initial.py new file mode 100644 index 00000000..ff74ab39 --- /dev/null +++ b/website/yivi/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# Generated by Django 4.2.9 on 2024-04-08 12:50 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="Session", + fields=[ + ("id", models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ("session_token", models.CharField(max_length=20, unique=True)), + ("created_at", models.DateTimeField(auto_now_add=True)), + ( + "user", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + ]