Remove obsolete migration files and update initial migration timestamps for various modules; ensure consistency in migration history across the project.

This commit is contained in:
IGNY8 VPS (Salman)
2025-11-20 23:32:45 +00:00
parent b38553cfc3
commit d14d6d89b1
67 changed files with 12722 additions and 3414 deletions

View File

@@ -1,6 +1,8 @@
from django.db import migrations, models
import django.db.models.deletion
# Generated by Django 5.2.8 on 2025-11-20 23:27
import django.core.validators
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
@@ -8,17 +10,91 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('igny8_core_auth', '0014_remove_plan_operation_limits_phase0'),
('writer', '0009_add_content_site_source_fields'),
('igny8_core_auth', '0001_initial'),
('planner', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='AudienceProfile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Audience Profile',
'verbose_name_plural': 'Audience Profiles',
'db_table': 'igny8_site_builder_audience_profiles',
'ordering': ['order', 'name'],
'abstract': False,
},
),
migrations.CreateModel(
name='BrandPersonality',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Brand Personality',
'verbose_name_plural': 'Brand Personalities',
'db_table': 'igny8_site_builder_brand_personalities',
'ordering': ['order', 'name'],
'abstract': False,
},
),
migrations.CreateModel(
name='BusinessType',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Business Type',
'verbose_name_plural': 'Business Types',
'db_table': 'igny8_site_builder_business_types',
'ordering': ['order', 'name'],
'abstract': False,
},
),
migrations.CreateModel(
name='HeroImageryDirection',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Hero Imagery Direction',
'verbose_name_plural': 'Hero Imagery Directions',
'db_table': 'igny8_site_builder_hero_imagery',
'ordering': ['order', 'name'],
'abstract': False,
},
),
migrations.CreateModel(
name='SiteBlueprint',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('name', models.CharField(help_text='Site name', max_length=255)),
('description', models.TextField(blank=True, help_text='Site description', null=True)),
('config_json', models.JSONField(default=dict, help_text='Wizard configuration: business_type, style, objectives, etc.')),
@@ -27,9 +103,11 @@ class Migration(migrations.Migration):
('hosting_type', models.CharField(choices=[('igny8_sites', 'IGNY8 Sites'), ('wordpress', 'WordPress'), ('shopify', 'Shopify'), ('multi', 'Multiple Destinations')], default='igny8_sites', help_text='Target hosting platform', max_length=50)),
('version', models.IntegerField(default=1, help_text='Blueprint version', validators=[django.core.validators.MinValueValidator(1)])),
('deployed_version', models.IntegerField(blank=True, help_text='Currently deployed version', null=True)),
('account', models.ForeignKey(db_column='tenant_id', on_delete=django.db.models.deletion.CASCADE, related_name='siteblueprint_set', to='igny8_core_auth.tenant')),
('sector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='siteblueprint_set', to='igny8_core_auth.sector')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='siteblueprint_set', to='igny8_core_auth.site')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('account', models.ForeignKey(db_column='tenant_id', on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.account')),
('sector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.sector')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.site')),
],
options={
'verbose_name': 'Site Blueprint',
@@ -42,54 +120,129 @@ class Migration(migrations.Migration):
name='PageBlueprint',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('slug', models.SlugField(help_text='Page URL slug', max_length=255)),
('title', models.CharField(help_text='Page title', max_length=255)),
('type', models.CharField(choices=[('home', 'Home'), ('about', 'About'), ('services', 'Services'), ('products', 'Products'), ('blog', 'Blog'), ('contact', 'Contact'), ('custom', 'Custom')], default='custom', help_text='Page type', max_length=50)),
('blocks_json', models.JSONField(default=list, help_text="Page content blocks: [{'type': 'hero', 'data': {...}}, ...]")),
('status', models.CharField(choices=[('draft', 'Draft'), ('generating', 'Generating'), ('ready', 'Ready')], db_index=True, default='draft', help_text='Page status', max_length=20)),
('status', models.CharField(choices=[('draft', 'Draft'), ('generating', 'Generating'), ('ready', 'Ready'), ('published', 'Published')], db_index=True, default='draft', help_text='Page status', max_length=20)),
('order', models.IntegerField(default=0, help_text='Page order in navigation')),
('account', models.ForeignKey(db_column='tenant_id', on_delete=django.db.models.deletion.CASCADE, related_name='pageblueprint_set', to='igny8_core_auth.tenant')),
('sector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pageblueprint_set', to='igny8_core_auth.sector')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pageblueprint_set', to='igny8_core_auth.site')),
('site_blueprint', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pages', to='site_building.siteblueprint')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('account', models.ForeignKey(db_column='tenant_id', on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.account')),
('sector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.sector')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.site')),
('site_blueprint', models.ForeignKey(help_text='The site blueprint this page belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='pages', to='site_building.siteblueprint')),
],
options={
'verbose_name': 'Page Blueprint',
'verbose_name_plural': 'Page Blueprints',
'db_table': 'igny8_page_blueprints',
'ordering': ['order', 'created_at'],
'unique_together': {('site_blueprint', 'slug')},
},
),
migrations.CreateModel(
name='SiteBlueprintCluster',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('role', models.CharField(choices=[('hub', 'Hub Page'), ('supporting', 'Supporting Page'), ('attribute', 'Attribute Page')], default='hub', max_length=50)),
('coverage_status', models.CharField(choices=[('pending', 'Pending'), ('in_progress', 'In Progress'), ('complete', 'Complete')], default='pending', max_length=50)),
('metadata', models.JSONField(blank=True, default=dict, help_text='Additional coverage metadata (target pages, keyword counts, ai hints)')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('account', models.ForeignKey(db_column='tenant_id', on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.account')),
('cluster', models.ForeignKey(help_text='Planner cluster being mapped into the site blueprint', on_delete=django.db.models.deletion.CASCADE, related_name='blueprint_links', to='planner.clusters')),
('sector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.sector')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.site')),
('site_blueprint', models.ForeignKey(help_text='Site blueprint that is planning coverage for the cluster', on_delete=django.db.models.deletion.CASCADE, related_name='cluster_links', to='site_building.siteblueprint')),
],
options={
'verbose_name': 'Site Blueprint Cluster',
'verbose_name_plural': 'Site Blueprint Clusters',
'db_table': 'igny8_site_blueprint_clusters',
},
),
migrations.CreateModel(
name='SiteBlueprintTaxonomy',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text='Display name', max_length=255)),
('slug', models.SlugField(help_text='Slug/identifier within the site blueprint', max_length=255)),
('taxonomy_type', models.CharField(choices=[('blog_category', 'Blog Category'), ('blog_tag', 'Blog Tag'), ('product_category', 'Product Category'), ('product_tag', 'Product Tag'), ('product_attribute', 'Product Attribute'), ('service_category', 'Service Category')], default='blog_category', max_length=50)),
('description', models.TextField(blank=True, null=True)),
('metadata', models.JSONField(blank=True, default=dict, help_text='Additional taxonomy metadata or AI hints')),
('external_reference', models.CharField(blank=True, help_text='External system ID (WordPress/WooCommerce/etc.)', max_length=255, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('account', models.ForeignKey(db_column='tenant_id', on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.account')),
('clusters', models.ManyToManyField(blank=True, help_text='Planner clusters that this taxonomy maps to', related_name='blueprint_taxonomies', to='planner.clusters')),
('sector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.sector')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_set', to='igny8_core_auth.site')),
('site_blueprint', models.ForeignKey(help_text='Site blueprint this taxonomy belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='taxonomies', to='site_building.siteblueprint')),
],
options={
'verbose_name': 'Site Blueprint Taxonomy',
'verbose_name_plural': 'Site Blueprint Taxonomies',
'db_table': 'igny8_site_blueprint_taxonomies',
},
),
migrations.AddIndex(
model_name='siteblueprint',
index=models.Index(fields=['status'], name='igny8_site__status_247ddc_idx'),
index=models.Index(fields=['status'], name='igny8_site__status_e7ca10_idx'),
),
migrations.AddIndex(
model_name='siteblueprint',
index=models.Index(fields=['hosting_type'], name='igny8_site__hosting_c4bb41_idx'),
index=models.Index(fields=['hosting_type'], name='igny8_site__hosting_7a9a3e_idx'),
),
migrations.AddIndex(
model_name='siteblueprint',
index=models.Index(fields=['site', 'sector'], name='igny8_site__site_id__5f0a4e_idx'),
index=models.Index(fields=['site', 'sector'], name='igny8_site__site_id_cb1aca_idx'),
),
migrations.AddIndex(
model_name='siteblueprint',
index=models.Index(fields=['account', 'status'], name='igny8_site__account__38f18a_idx'),
index=models.Index(fields=['account', 'status'], name='igny8_site__tenant__1bb483_idx'),
),
migrations.AddIndex(
model_name='pageblueprint',
index=models.Index(fields=['site_blueprint', 'status'], name='igny8_page__site_bl_1b5d8b_idx'),
index=models.Index(fields=['site_blueprint', 'status'], name='igny8_page__site_bl_2dede2_idx'),
),
migrations.AddIndex(
model_name='pageblueprint',
index=models.Index(fields=['type'], name='igny8_page__type_b11552_idx'),
index=models.Index(fields=['type'], name='igny8_page__type_4af2bd_idx'),
),
migrations.AddIndex(
model_name='pageblueprint',
index=models.Index(fields=['site_blueprint', 'order'], name='igny8_page__site_bl_7a77d7_idx'),
index=models.Index(fields=['site_blueprint', 'order'], name='igny8_page__site_bl_c56196_idx'),
),
migrations.AlterUniqueTogether(
name='pageblueprint',
unique_together={('site_blueprint', 'slug')},
),
migrations.AddIndex(
model_name='siteblueprintcluster',
index=models.Index(fields=['site_blueprint', 'cluster'], name='igny8_site__site_bl_904406_idx'),
),
migrations.AddIndex(
model_name='siteblueprintcluster',
index=models.Index(fields=['site_blueprint', 'coverage_status'], name='igny8_site__site_bl_cff5ab_idx'),
),
migrations.AddIndex(
model_name='siteblueprintcluster',
index=models.Index(fields=['cluster', 'role'], name='igny8_site__cluster_d75a2f_idx'),
),
migrations.AlterUniqueTogether(
name='siteblueprintcluster',
unique_together={('site_blueprint', 'cluster', 'role')},
),
migrations.AddIndex(
model_name='siteblueprinttaxonomy',
index=models.Index(fields=['site_blueprint', 'taxonomy_type'], name='igny8_site__site_bl_f952f7_idx'),
),
migrations.AddIndex(
model_name='siteblueprinttaxonomy',
index=models.Index(fields=['taxonomy_type'], name='igny8_site__taxonom_178987_idx'),
),
migrations.AlterUniqueTogether(
name='siteblueprinttaxonomy',
unique_together={('site_blueprint', 'slug')},
),
]

View File

@@ -1,159 +0,0 @@
from django.db import migrations, models
def seed_site_builder_metadata(apps, schema_editor):
BusinessType = apps.get_model('site_building', 'BusinessType')
AudienceProfile = apps.get_model('site_building', 'AudienceProfile')
BrandPersonality = apps.get_model('site_building', 'BrandPersonality')
HeroImageryDirection = apps.get_model('site_building', 'HeroImageryDirection')
business_types = [
("Productized Services", "Standardized service offering with clear deliverables."),
("B2B SaaS Platform", "Subscription software platform targeting business teams."),
("eCommerce Brand", "Direct-to-consumer catalog with premium merchandising."),
("Marketplace / Platform", "Two-sided marketplace connecting buyers and sellers."),
("Advisory / Consulting", "Expert advisory firm or boutique consultancy."),
("Education / Training", "Learning platform, cohort, or academy."),
("Community / Membership", "Member-driven experience with gated content."),
("Mission-Driven / Nonprofit", "Impact-focused organization or foundation."),
]
audience_profiles = [
("Enterprise Operations Leaders", "COO / Ops executives at scale-ups."),
("Marketing Directors & CMOs", "Growth and brand owners across industries."),
("Founders & Executive Teams", "Visionaries leading fast-moving companies."),
("Revenue & Sales Leaders", "CROs, VPs of Sales, and GTM owners."),
("Product & Innovation Teams", "Product managers and innovation leaders."),
("IT & Engineering Teams", "Technical buyers evaluating new platforms."),
("HR & People Leaders", "People ops and talent professionals."),
("Healthcare Administrators", "Clinical and operational healthcare leads."),
("Financial Services Professionals", "Banking, fintech, and investment teams."),
("Consumers / Prospects", "End-user or prospect-focused experience."),
]
brand_personalities = [
("Bold Visionary", "Decisive, future-forward, and thought-leading."),
("Trusted Advisor", "Calm, credible, and risk-aware guidance."),
("Analytical Expert", "Data-backed, precise, and rigorous."),
("Friendly Guide", "Welcoming, warm, and supportive tone."),
("Luxe & Premium", "High-touch, elevated, and detail-obsessed."),
("Playful Creative", "Vibrant, unexpected, and energetic."),
("Minimalist Modern", "Clean, refined, and confident."),
("Fearless Innovator", "Experimental, edgy, and fast-moving."),
]
hero_imagery = [
("Real team collaboration photography", "Documentary-style shots of real teams."),
("Product close-ups with UI overlays", "Focus on interfaces and feature highlights."),
("Lifestyle scenes featuring customers", "Story-driven photography of real scenarios."),
("Abstract gradients & motion graphics", "Modern, colorful abstract compositions."),
("Illustration + iconography blend", "Custom illustrations paired with icon systems."),
]
for order, (name, description) in enumerate(business_types):
BusinessType.objects.update_or_create(
name=name,
defaults={'description': description, 'order': order, 'is_active': True},
)
for order, (name, description) in enumerate(audience_profiles):
AudienceProfile.objects.update_or_create(
name=name,
defaults={'description': description, 'order': order, 'is_active': True},
)
for order, (name, description) in enumerate(brand_personalities):
BrandPersonality.objects.update_or_create(
name=name,
defaults={'description': description, 'order': order, 'is_active': True},
)
for order, (name, description) in enumerate(hero_imagery):
HeroImageryDirection.objects.update_or_create(
name=name,
defaults={'description': description, 'order': order, 'is_active': True},
)
class Migration(migrations.Migration):
dependencies = [
('site_building', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='AudienceProfile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Audience Profile',
'verbose_name_plural': 'Audience Profiles',
'db_table': 'igny8_site_builder_audience_profiles',
'ordering': ['order', 'name'],
},
),
migrations.CreateModel(
name='BrandPersonality',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Brand Personality',
'verbose_name_plural': 'Brand Personalities',
'db_table': 'igny8_site_builder_brand_personalities',
'ordering': ['order', 'name'],
},
),
migrations.CreateModel(
name='BusinessType',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Business Type',
'verbose_name_plural': 'Business Types',
'db_table': 'igny8_site_builder_business_types',
'ordering': ['order', 'name'],
},
),
migrations.CreateModel(
name='HeroImageryDirection',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=120, unique=True)),
('description', models.CharField(blank=True, max_length=255)),
('is_active', models.BooleanField(default=True)),
('order', models.PositiveIntegerField(default=0)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Hero Imagery Direction',
'verbose_name_plural': 'Hero Imagery Directions',
'db_table': 'igny8_site_builder_hero_imagery',
'ordering': ['order', 'name'],
},
),
migrations.RunPython(seed_site_builder_metadata, migrations.RunPython.noop),
]

View File

@@ -1,119 +0,0 @@
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('planner', '0007_merge_20251109_2138'),
('site_building', '0002_sitebuilder_metadata'),
('igny8_core_auth', '0014_remove_plan_operation_limits_phase0'),
]
operations = [
migrations.CreateModel(
name='SiteBlueprintCluster',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('role', models.CharField(choices=[('hub', 'Hub Page'), ('supporting', 'Supporting Page'), ('attribute', 'Attribute Page')], default='hub', max_length=50)),
('coverage_status', models.CharField(choices=[('pending', 'Pending'), ('in_progress', 'In Progress'), ('complete', 'Complete')], default='pending', max_length=50)),
('metadata', models.JSONField(blank=True, default=dict, help_text='Additional coverage metadata (target pages, keyword counts, ai hints)')),
('account', models.ForeignKey(db_column='tenant_id', on_delete=django.db.models.deletion.CASCADE, related_name='siteblueprintcluster_set', to='igny8_core_auth.tenant')),
('cluster', models.ForeignKey(help_text='Planner cluster being mapped into the site blueprint', on_delete=django.db.models.deletion.CASCADE, related_name='blueprint_links', to='planner.clusters')),
('sector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='siteblueprintcluster_set', to='igny8_core_auth.sector')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='siteblueprintcluster_set', to='igny8_core_auth.site')),
('site_blueprint', models.ForeignKey(help_text='Site blueprint that is planning coverage for the cluster', on_delete=django.db.models.deletion.CASCADE, related_name='cluster_links', to='site_building.siteblueprint')),
],
options={
'verbose_name': 'Site Blueprint Cluster',
'verbose_name_plural': 'Site Blueprint Clusters',
'db_table': 'igny8_site_blueprint_clusters',
'ordering': ['-created_at'],
'unique_together': {('site_blueprint', 'cluster', 'role')},
},
),
migrations.CreateModel(
name='WorkflowState',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('current_step', models.CharField(default='business_details', max_length=50)),
('step_status', models.JSONField(blank=True, default=dict, help_text='Dictionary of step → status/progress metadata')),
('blocking_reason', models.TextField(blank=True, help_text='Human-readable explanation when blocked', null=True)),
('completed', models.BooleanField(default=False, help_text='Marks wizard completion')),
('metadata', models.JSONField(blank=True, default=dict)),
('account', models.ForeignKey(db_column='tenant_id', on_delete=django.db.models.deletion.CASCADE, related_name='workflowstate_set', to='igny8_core_auth.tenant')),
('sector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workflowstate_set', to='igny8_core_auth.sector')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workflowstate_set', to='igny8_core_auth.site')),
('site_blueprint', models.OneToOneField(help_text='Blueprint whose progress is being tracked', on_delete=django.db.models.deletion.CASCADE, related_name='workflow_state', to='site_building.siteblueprint')),
],
options={
'verbose_name': 'Workflow State',
'verbose_name_plural': 'Workflow States',
'db_table': 'igny8_site_blueprint_workflow_states',
'ordering': ['-created_at'],
},
),
migrations.CreateModel(
name='SiteBlueprintTaxonomy',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('name', models.CharField(help_text='Display name', max_length=255)),
('slug', models.SlugField(help_text='Slug/identifier within the site blueprint', max_length=255)),
('taxonomy_type', models.CharField(choices=[('blog_category', 'Blog Category'), ('blog_tag', 'Blog Tag'), ('product_category', 'Product Category'), ('product_tag', 'Product Tag'), ('product_attribute', 'Product Attribute'), ('service_category', 'Service Category')], default='blog_category', max_length=50)),
('description', models.TextField(blank=True, null=True)),
('metadata', models.JSONField(blank=True, default=dict, help_text='Additional taxonomy metadata or AI hints')),
('external_reference', models.CharField(blank=True, help_text='External system ID (WordPress/WooCommerce/etc.)', max_length=255, null=True)),
('account', models.ForeignKey(db_column='tenant_id', on_delete=django.db.models.deletion.CASCADE, related_name='siteblueprinttaxonomy_set', to='igny8_core_auth.tenant')),
('sector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='siteblueprinttaxonomy_set', to='igny8_core_auth.sector')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='siteblueprinttaxonomy_set', to='igny8_core_auth.site')),
('site_blueprint', models.ForeignKey(help_text='Site blueprint this taxonomy belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='taxonomies', to='site_building.siteblueprint')),
('clusters', models.ManyToManyField(blank=True, help_text='Planner clusters that this taxonomy maps to', related_name='blueprint_taxonomies', to='planner.clusters')),
],
options={
'verbose_name': 'Site Blueprint Taxonomy',
'verbose_name_plural': 'Site Blueprint Taxonomies',
'db_table': 'igny8_site_blueprint_taxonomies',
'ordering': ['-created_at'],
'unique_together': {('site_blueprint', 'slug')},
},
),
migrations.AddIndex(
model_name='siteblueprintcluster',
index=models.Index(fields=['site_blueprint', 'cluster'], name='site_buildi_site_bl_4234c0_idx'),
),
migrations.AddIndex(
model_name='siteblueprintcluster',
index=models.Index(fields=['cluster', 'role'], name='site_buildi_cluster__9a078f_idx'),
),
migrations.AddIndex(
model_name='siteblueprintcluster',
index=models.Index(fields=['site_blueprint', 'coverage_status'], name='site_buildi_site_bl_459d80_idx'),
),
migrations.AddIndex(
model_name='workflowstate',
index=models.Index(fields=['site_blueprint'], name='site_buildi_site_bl_312cd0_idx'),
),
migrations.AddIndex(
model_name='workflowstate',
index=models.Index(fields=['current_step'], name='site_buildi_current_a25dce_idx'),
),
migrations.AddIndex(
model_name='workflowstate',
index=models.Index(fields=['completed'], name='site_buildi_complet_4649af_idx'),
),
migrations.AddIndex(
model_name='siteblueprinttaxonomy',
index=models.Index(fields=['site_blueprint', 'taxonomy_type'], name='site_buildi_site_bl_33fadc_idx'),
),
migrations.AddIndex(
model_name='siteblueprinttaxonomy',
index=models.Index(fields=['taxonomy_type'], name='site_buildi_taxonom_4a7dde_idx'),
),
]