From 999ca28b67c46f9f11f9ec1ebc0c91cb2fa82287 Mon Sep 17 00:00:00 2001 From: Caine Date: Wed, 1 Apr 2026 22:48:45 +0100 Subject: Add initial migration, create superuser --- kitchen/migrations/0001_initial.py | 179 +++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 kitchen/migrations/0001_initial.py (limited to 'kitchen') diff --git a/kitchen/migrations/0001_initial.py b/kitchen/migrations/0001_initial.py new file mode 100644 index 0000000..aabfd27 --- /dev/null +++ b/kitchen/migrations/0001_initial.py @@ -0,0 +1,179 @@ +# Generated by Django 5.2.12 on 2026-04-01 21:48 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Ingredient', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, unique=True)), + ('default_unit', models.CharField(max_length=20)), + ('shelf_life_days', models.IntegerField(blank=True, help_text='Typical fridge life in days once opened/defrosted', null=True)), + ('aliases', models.JSONField(blank=True, default=list, help_text='Alternative names, e.g. ["noodles", "egg noodle nests"]')), + ], + options={ + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='MetaRecipe', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('method', models.TextField(help_text='Cooking instructions (markdown)')), + ('prep_time_mins', models.IntegerField(blank=True, null=True)), + ('cook_time_mins', models.IntegerField(blank=True, null=True)), + ('default_servings', models.IntegerField(default=2)), + ('gear_needed', models.CharField(blank=True, max_length=200)), + ('tags', models.JSONField(blank=True, default=list)), + ], + options={ + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='Recipe', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200)), + ('method', models.TextField(help_text='Cooking instructions (markdown)')), + ('prep_time_mins', models.IntegerField(blank=True, null=True)), + ('cook_time_mins', models.IntegerField(blank=True, null=True)), + ('servings', models.IntegerField(default=2)), + ('source_url', models.URLField(blank=True)), + ('source_book', models.CharField(blank=True, max_length=200)), + ('gear_needed', models.CharField(blank=True, max_length=200)), + ('tags', models.JSONField(blank=True, default=list)), + ], + options={ + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50, unique=True)), + ], + options={ + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='MetaRecipeBase', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('quantity_per_serving', models.DecimalField(decimal_places=2, max_digits=8)), + ('unit', models.CharField(max_length=20)), + ('ingredient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='kitchen.ingredient')), + ('meta_recipe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='base_ingredients', to='kitchen.metarecipe')), + ], + options={ + 'ordering': ['meta_recipe', 'ingredient__name'], + }, + ), + migrations.CreateModel( + name='PantryItem', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('quantity', models.DecimalField(decimal_places=2, max_digits=8)), + ('unit', models.CharField(max_length=20)), + ('location', models.CharField(choices=[('fridge', 'Fridge'), ('freezer', 'Freezer'), ('cupboard', 'Cupboard')], max_length=20)), + ('stored_date', models.DateField(auto_now_add=True)), + ('expiry_date', models.DateField(blank=True, null=True)), + ('is_staple', models.BooleanField(default=False, help_text='Always restock when gone (onions, frozen chips)')), + ('notes', models.TextField(blank=True)), + ('ingredient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='kitchen.ingredient')), + ], + options={ + 'ordering': ['expiry_date', 'ingredient__name'], + }, + ), + migrations.CreateModel( + name='CookLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField(auto_now_add=True)), + ('slot_choices', models.JSONField(blank=True, default=dict, help_text='Slot choices for meta-recipe, e.g. {"protein": "pork mince", "carb": "noodles"}')), + ('servings', models.IntegerField(default=2)), + ('notes', models.TextField(blank=True)), + ('meta_recipe', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='kitchen.metarecipe')), + ('recipe', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='kitchen.recipe')), + ], + options={ + 'ordering': ['-date'], + }, + ), + migrations.CreateModel( + name='RecipeIngredient', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('quantity', models.DecimalField(decimal_places=2, max_digits=8)), + ('unit', models.CharField(max_length=20)), + ('optional', models.BooleanField(default=False)), + ('ingredient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='kitchen.ingredient')), + ('recipe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ingredients', to='kitchen.recipe')), + ], + options={ + 'ordering': ['recipe', 'ingredient__name'], + }, + ), + migrations.CreateModel( + name='ShoppingListItem', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(help_text='Fallback name if not in ingredients table', max_length=100)), + ('quantity', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True)), + ('unit', models.CharField(blank=True, max_length=20)), + ('reason', models.CharField(blank=True, max_length=200)), + ('added_date', models.DateField(auto_now_add=True)), + ('checked', models.BooleanField(default=False)), + ('ingredient', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='kitchen.ingredient')), + ], + options={ + 'ordering': ['checked', 'added_date'], + }, + ), + migrations.CreateModel( + name='Slot', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50)), + ('required', models.BooleanField(default=True)), + ('max_choices', models.IntegerField(default=1, help_text='Max ingredients to pick (1 for protein, 3 for veg)')), + ('meta_recipe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='slots', to='kitchen.metarecipe')), + ], + options={ + 'ordering': ['meta_recipe', 'name'], + }, + ), + migrations.CreateModel( + name='SlotOption', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('quantity_per_serving', models.DecimalField(decimal_places=2, max_digits=8)), + ('unit', models.CharField(max_length=20)), + ('notes', models.CharField(blank=True, max_length=200)), + ('ingredient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='kitchen.ingredient')), + ('slot', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='options', to='kitchen.slot')), + ], + options={ + 'ordering': ['slot', 'ingredient__name'], + }, + ), + migrations.AddField( + model_name='ingredient', + name='tags', + field=models.ManyToManyField(blank=True, to='kitchen.tag'), + ), + ] -- cgit v1.2.3