# Generated by Django 5.2.6 on 2026-06-14 17:44

import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ("organizations", "0002_workspace_template_user_context_pref"),
        ("storage", "0003_phase0c_fileasset_enhancement"),
        ("tenants", "0002_add_plan_fk"),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name="ReportDefinition",
            fields=[
                (
                    "id",
                    models.BigAutoField(
                        auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
                    ),
                ),
                (
                    "is_deleted",
                    models.BooleanField(db_index=True, default=False, verbose_name="deleted"),
                ),
                (
                    "deleted_at",
                    models.DateTimeField(blank=True, null=True, verbose_name="deleted at"),
                ),
                ("version", models.PositiveIntegerField(default=0, verbose_name="version")),
                (
                    "created_at",
                    models.DateTimeField(
                        auto_now_add=True, db_index=True, verbose_name="created at"
                    ),
                ),
                ("updated_at", models.DateTimeField(auto_now=True, verbose_name="updated at")),
                (
                    "public_id",
                    models.UUIDField(
                        db_index=True,
                        default=uuid.uuid4,
                        editable=False,
                        unique=True,
                        verbose_name="public id",
                    ),
                ),
                (
                    "code",
                    models.CharField(
                        db_index=True,
                        help_text="Unique code per tenant, e.g. 'crm.leads_by_status'",
                        max_length=128,
                        verbose_name="code",
                    ),
                ),
                ("name", models.CharField(max_length=255, verbose_name="name")),
                (
                    "description",
                    models.TextField(blank=True, default="", verbose_name="description"),
                ),
                (
                    "module",
                    models.CharField(
                        blank=True,
                        db_index=True,
                        default="",
                        help_text="Owning module, e.g. 'crm', 'helpdesk'",
                        max_length=64,
                        verbose_name="module",
                    ),
                ),
                (
                    "entity_type",
                    models.CharField(
                        blank=True,
                        default="",
                        help_text="Dot-notation entity, e.g. 'crm.lead'",
                        max_length=128,
                        verbose_name="entity type",
                    ),
                ),
                (
                    "resource",
                    models.CharField(
                        blank=True,
                        default="",
                        help_text="API endpoint that returns report data, e.g. '/api/v1/crm/leads/report/'",
                        max_length=512,
                        verbose_name="resource URL",
                    ),
                ),
                (
                    "columns",
                    models.JSONField(
                        blank=True,
                        default=list,
                        help_text='Ordered list of column definitions: [{"key": "name", "label": "Full Name", "type": "text"}, ...]',
                        verbose_name="columns",
                    ),
                ),
                (
                    "filters_schema",
                    models.JSONField(
                        blank=True,
                        default=list,
                        help_text="List of filter field definitions for the ReportFilter UI",
                        verbose_name="filters schema",
                    ),
                ),
                (
                    "parameters",
                    models.JSONField(
                        blank=True,
                        default=dict,
                        help_text="Configurable report parameters as key-value pairs",
                        verbose_name="parameters",
                    ),
                ),
                (
                    "group_by",
                    models.JSONField(
                        blank=True,
                        default=list,
                        help_text="List of field keys to group results by",
                        verbose_name="group by",
                    ),
                ),
                (
                    "sort_by",
                    models.CharField(
                        blank=True,
                        default="",
                        help_text="Default sort field, optionally prefixed with '-' for descending",
                        max_length=128,
                        verbose_name="sort by",
                    ),
                ),
                ("page_size", models.PositiveIntegerField(default=100, verbose_name="page size")),
                (
                    "export_formats",
                    models.JSONField(
                        blank=True,
                        default=list,
                        help_text="Allowed export formats: ['csv', 'xlsx', 'pdf']",
                        verbose_name="export formats",
                    ),
                ),
                (
                    "is_active",
                    models.BooleanField(db_index=True, default=True, verbose_name="is active"),
                ),
                (
                    "is_builtin",
                    models.BooleanField(
                        default=False,
                        help_text="True for module-registered reports; False for user-created",
                        verbose_name="is built-in",
                    ),
                ),
                (
                    "deleted_by",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                        related_name="+",
                        to=settings.AUTH_USER_MODEL,
                        verbose_name="deleted by",
                    ),
                ),
                (
                    "organization_node",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.PROTECT,
                        related_name="+",
                        to="organizations.organizationnode",
                        verbose_name="organization node",
                    ),
                ),
                (
                    "tenant",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        related_name="+",
                        to="tenants.tenant",
                        verbose_name="tenant",
                    ),
                ),
            ],
            options={
                "verbose_name": "report definition",
                "verbose_name_plural": "report definitions",
                "ordering": ("module", "name"),
            },
        ),
        migrations.CreateModel(
            name="ScheduledReport",
            fields=[
                (
                    "id",
                    models.BigAutoField(
                        auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
                    ),
                ),
                (
                    "is_deleted",
                    models.BooleanField(db_index=True, default=False, verbose_name="deleted"),
                ),
                (
                    "deleted_at",
                    models.DateTimeField(blank=True, null=True, verbose_name="deleted at"),
                ),
                ("version", models.PositiveIntegerField(default=0, verbose_name="version")),
                (
                    "created_at",
                    models.DateTimeField(
                        auto_now_add=True, db_index=True, verbose_name="created at"
                    ),
                ),
                ("updated_at", models.DateTimeField(auto_now=True, verbose_name="updated at")),
                (
                    "public_id",
                    models.UUIDField(
                        db_index=True,
                        default=uuid.uuid4,
                        editable=False,
                        unique=True,
                        verbose_name="public id",
                    ),
                ),
                (
                    "cron_expression",
                    models.CharField(
                        help_text="Standard cron expression, e.g. '0 8 * * 1' for Monday 08:00",
                        max_length=128,
                        verbose_name="cron expression",
                    ),
                ),
                (
                    "format",
                    models.CharField(
                        choices=[
                            ("csv", "CSV"),
                            ("xlsx", "Excel"),
                            ("pdf", "PDF"),
                            ("json", "JSON"),
                        ],
                        default="csv",
                        max_length=8,
                        verbose_name="output format",
                    ),
                ),
                (
                    "recipients",
                    models.JSONField(
                        blank=True,
                        default=list,
                        help_text="List of user IDs or email addresses",
                        verbose_name="recipients",
                    ),
                ),
                (
                    "is_active",
                    models.BooleanField(db_index=True, default=True, verbose_name="is active"),
                ),
                (
                    "last_run_at",
                    models.DateTimeField(blank=True, null=True, verbose_name="last run at"),
                ),
                (
                    "next_run_at",
                    models.DateTimeField(
                        blank=True, db_index=True, null=True, verbose_name="next run at"
                    ),
                ),
                ("run_count", models.PositiveBigIntegerField(default=0, verbose_name="run count")),
                (
                    "deleted_by",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                        related_name="+",
                        to=settings.AUTH_USER_MODEL,
                        verbose_name="deleted by",
                    ),
                ),
                (
                    "organization_node",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.PROTECT,
                        related_name="+",
                        to="organizations.organizationnode",
                        verbose_name="organization node",
                    ),
                ),
                (
                    "report",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        related_name="schedules",
                        to="reporting.reportdefinition",
                        verbose_name="report",
                    ),
                ),
                (
                    "tenant",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        related_name="+",
                        to="tenants.tenant",
                        verbose_name="tenant",
                    ),
                ),
            ],
            options={
                "verbose_name": "scheduled report",
                "verbose_name_plural": "scheduled reports",
                "ordering": ("-created_at",),
            },
        ),
        migrations.CreateModel(
            name="ReportExecution",
            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, verbose_name="created at"
                    ),
                ),
                ("updated_at", models.DateTimeField(auto_now=True, verbose_name="updated at")),
                (
                    "public_id",
                    models.UUIDField(
                        db_index=True,
                        default=uuid.uuid4,
                        editable=False,
                        unique=True,
                        verbose_name="public id",
                    ),
                ),
                (
                    "status",
                    models.CharField(
                        choices=[
                            ("pending", "Pending"),
                            ("running", "Running"),
                            ("completed", "Completed"),
                            ("failed", "Failed"),
                        ],
                        db_index=True,
                        default="pending",
                        max_length=16,
                        verbose_name="status",
                    ),
                ),
                (
                    "format",
                    models.CharField(
                        blank=True,
                        choices=[
                            ("csv", "CSV"),
                            ("xlsx", "Excel"),
                            ("pdf", "PDF"),
                            ("json", "JSON"),
                        ],
                        default="",
                        max_length=8,
                        verbose_name="output format",
                    ),
                ),
                (
                    "parameters",
                    models.JSONField(blank=True, default=dict, verbose_name="parameters"),
                ),
                (
                    "filters_applied",
                    models.JSONField(blank=True, default=dict, verbose_name="filters applied"),
                ),
                (
                    "row_count",
                    models.PositiveIntegerField(blank=True, null=True, verbose_name="row count"),
                ),
                (
                    "error_message",
                    models.TextField(blank=True, default="", verbose_name="error message"),
                ),
                (
                    "started_at",
                    models.DateTimeField(blank=True, null=True, verbose_name="started at"),
                ),
                (
                    "finished_at",
                    models.DateTimeField(blank=True, null=True, verbose_name="finished at"),
                ),
                (
                    "duration_seconds",
                    models.FloatField(blank=True, null=True, verbose_name="duration seconds"),
                ),
                (
                    "file",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                        related_name="+",
                        to="storage.filemetadata",
                        verbose_name="output file",
                    ),
                ),
                (
                    "organization_node",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.PROTECT,
                        related_name="+",
                        to="organizations.organizationnode",
                        verbose_name="organization node",
                    ),
                ),
                (
                    "report",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                        related_name="executions",
                        to="reporting.reportdefinition",
                        verbose_name="report",
                    ),
                ),
                (
                    "tenant",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        related_name="+",
                        to="tenants.tenant",
                        verbose_name="tenant",
                    ),
                ),
                (
                    "triggered_by",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                        related_name="+",
                        to=settings.AUTH_USER_MODEL,
                        verbose_name="triggered by",
                    ),
                ),
                (
                    "schedule",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                        related_name="executions",
                        to="reporting.scheduledreport",
                        verbose_name="schedule",
                    ),
                ),
            ],
            options={
                "verbose_name": "report execution",
                "verbose_name_plural": "report executions",
                "ordering": ("-started_at",),
                "get_latest_by": "started_at",
            },
        ),
        migrations.CreateModel(
            name="DashboardDefinition",
            fields=[
                (
                    "id",
                    models.BigAutoField(
                        auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
                    ),
                ),
                (
                    "is_deleted",
                    models.BooleanField(db_index=True, default=False, verbose_name="deleted"),
                ),
                (
                    "deleted_at",
                    models.DateTimeField(blank=True, null=True, verbose_name="deleted at"),
                ),
                ("version", models.PositiveIntegerField(default=0, verbose_name="version")),
                (
                    "created_at",
                    models.DateTimeField(
                        auto_now_add=True, db_index=True, verbose_name="created at"
                    ),
                ),
                ("updated_at", models.DateTimeField(auto_now=True, verbose_name="updated at")),
                (
                    "public_id",
                    models.UUIDField(
                        db_index=True,
                        default=uuid.uuid4,
                        editable=False,
                        unique=True,
                        verbose_name="public id",
                    ),
                ),
                (
                    "code",
                    models.CharField(
                        db_index=True,
                        help_text="Unique code per tenant, e.g. 'crm.sales_dashboard'",
                        max_length=128,
                        verbose_name="code",
                    ),
                ),
                ("name", models.CharField(max_length=255, verbose_name="name")),
                (
                    "description",
                    models.TextField(blank=True, default="", verbose_name="description"),
                ),
                (
                    "module",
                    models.CharField(
                        blank=True, db_index=True, default="", max_length=64, verbose_name="module"
                    ),
                ),
                (
                    "layout",
                    models.JSONField(
                        blank=True,
                        default=dict,
                        help_text="Grid layout with widget placements as JSON",
                        verbose_name="layout",
                    ),
                ),
                (
                    "is_active",
                    models.BooleanField(db_index=True, default=True, verbose_name="is active"),
                ),
                (
                    "is_default",
                    models.BooleanField(
                        default=False,
                        help_text="True if this is the default dashboard for the tenant",
                        verbose_name="is default",
                    ),
                ),
                ("is_builtin", models.BooleanField(default=False, verbose_name="is built-in")),
                (
                    "deleted_by",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                        related_name="+",
                        to=settings.AUTH_USER_MODEL,
                        verbose_name="deleted by",
                    ),
                ),
                (
                    "organization_node",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.PROTECT,
                        related_name="+",
                        to="organizations.organizationnode",
                        verbose_name="organization node",
                    ),
                ),
                (
                    "tenant",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        related_name="+",
                        to="tenants.tenant",
                        verbose_name="tenant",
                    ),
                ),
            ],
            options={
                "verbose_name": "dashboard definition",
                "verbose_name_plural": "dashboard definitions",
                "ordering": ("-is_default", "module", "name"),
                "indexes": [
                    models.Index(
                        fields=["tenant", "module"], name="reporting_d_tenant__a45adb_idx"
                    ),
                    models.Index(
                        fields=["tenant", "is_default"], name="reporting_d_tenant__26e46b_idx"
                    ),
                ],
                "constraints": [
                    models.UniqueConstraint(
                        fields=("tenant", "code"), name="uq_dashboard_definition_tenant_code"
                    )
                ],
            },
        ),
        migrations.CreateModel(
            name="KPIDefinition",
            fields=[
                (
                    "id",
                    models.BigAutoField(
                        auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
                    ),
                ),
                (
                    "is_deleted",
                    models.BooleanField(db_index=True, default=False, verbose_name="deleted"),
                ),
                (
                    "deleted_at",
                    models.DateTimeField(blank=True, null=True, verbose_name="deleted at"),
                ),
                ("version", models.PositiveIntegerField(default=0, verbose_name="version")),
                (
                    "created_at",
                    models.DateTimeField(
                        auto_now_add=True, db_index=True, verbose_name="created at"
                    ),
                ),
                ("updated_at", models.DateTimeField(auto_now=True, verbose_name="updated at")),
                (
                    "public_id",
                    models.UUIDField(
                        db_index=True,
                        default=uuid.uuid4,
                        editable=False,
                        unique=True,
                        verbose_name="public id",
                    ),
                ),
                (
                    "code",
                    models.CharField(
                        db_index=True,
                        help_text="Unique code per tenant, e.g. 'crm.open_leads_count'",
                        max_length=128,
                        verbose_name="code",
                    ),
                ),
                ("name", models.CharField(max_length=255, verbose_name="name")),
                (
                    "description",
                    models.TextField(blank=True, default="", verbose_name="description"),
                ),
                (
                    "module",
                    models.CharField(
                        blank=True, db_index=True, default="", max_length=64, verbose_name="module"
                    ),
                ),
                (
                    "resource",
                    models.CharField(
                        help_text="API endpoint returning {value, change?, trend?}",
                        max_length=512,
                        verbose_name="resource URL",
                    ),
                ),
                (
                    "trend_resource",
                    models.CharField(
                        blank=True,
                        default="",
                        help_text="Optional endpoint for chartable trend data",
                        max_length=512,
                        verbose_name="trend resource URL",
                    ),
                ),
                (
                    "format",
                    models.CharField(
                        choices=[
                            ("number", "Number"),
                            ("currency", "Currency"),
                            ("percent", "Percent"),
                            ("duration", "Duration"),
                        ],
                        default="number",
                        max_length=16,
                        verbose_name="metric format",
                    ),
                ),
                (
                    "unit",
                    models.CharField(
                        blank=True,
                        default="",
                        help_text="Unit label, e.g. 'USD', '%', 'hrs'",
                        max_length=32,
                        verbose_name="unit",
                    ),
                ),
                (
                    "decimal_places",
                    models.PositiveSmallIntegerField(default=0, verbose_name="decimal places"),
                ),
                (
                    "threshold_warning",
                    models.FloatField(blank=True, null=True, verbose_name="warning threshold"),
                ),
                (
                    "threshold_critical",
                    models.FloatField(blank=True, null=True, verbose_name="critical threshold"),
                ),
                (
                    "is_active",
                    models.BooleanField(db_index=True, default=True, verbose_name="is active"),
                ),
                ("is_builtin", models.BooleanField(default=False, verbose_name="is built-in")),
                (
                    "deleted_by",
                    models.ForeignKey(
                        blank=True,
                        null=True,
                        on_delete=django.db.models.deletion.SET_NULL,
                        related_name="+",
                        to=settings.AUTH_USER_MODEL,
                        verbose_name="deleted by",
                    ),
                ),
                (
                    "organization_node",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.PROTECT,
                        related_name="+",
                        to="organizations.organizationnode",
                        verbose_name="organization node",
                    ),
                ),
                (
                    "tenant",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        related_name="+",
                        to="tenants.tenant",
                        verbose_name="tenant",
                    ),
                ),
            ],
            options={
                "verbose_name": "KPI definition",
                "verbose_name_plural": "KPI definitions",
                "ordering": ("module", "name"),
                "indexes": [
                    models.Index(
                        fields=["tenant", "module"], name="reporting_k_tenant__e3d5a8_idx"
                    ),
                    models.Index(
                        fields=["tenant", "is_active"], name="reporting_k_tenant__a4d506_idx"
                    ),
                ],
                "constraints": [
                    models.UniqueConstraint(
                        fields=("tenant", "code"), name="uq_kpi_definition_tenant_code"
                    )
                ],
            },
        ),
        migrations.AddIndex(
            model_name="reportdefinition",
            index=models.Index(fields=["tenant", "module"], name="reporting_r_tenant__7f9bad_idx"),
        ),
        migrations.AddIndex(
            model_name="reportdefinition",
            index=models.Index(
                fields=["tenant", "is_active"], name="reporting_r_tenant__5d5832_idx"
            ),
        ),
        migrations.AddConstraint(
            model_name="reportdefinition",
            constraint=models.UniqueConstraint(
                fields=("tenant", "code"), name="uq_report_definition_tenant_code"
            ),
        ),
        migrations.AddIndex(
            model_name="scheduledreport",
            index=models.Index(
                fields=["tenant", "is_active", "next_run_at"], name="reporting_s_tenant__787f97_idx"
            ),
        ),
        migrations.AddIndex(
            model_name="reportexecution",
            index=models.Index(fields=["tenant", "report"], name="reporting_r_tenant__c8b775_idx"),
        ),
        migrations.AddIndex(
            model_name="reportexecution",
            index=models.Index(
                fields=["tenant", "schedule"], name="reporting_r_tenant__2e76e0_idx"
            ),
        ),
        migrations.AddIndex(
            model_name="reportexecution",
            index=models.Index(fields=["tenant", "status"], name="reporting_r_tenant__f4e92b_idx"),
        ),
    ]
