bottleneckcrm/backend/webhooks/migrations/0001_initial.py
Ashwin e26ab380fc Add unit tests for ticket board provider, status settable, web forms, CSV import, deal aging badge, and tickets selection
- Implement comprehensive tests for the ticket board provider to validate kanban and pipeline modes, including ticket movement and error handling.
- Create tests for ticket status settable to ensure proper status selection logic.
- Enhance web form model tests to cover ticket-specific fields and submission behavior.
- Introduce CSV import sheet tests to verify file handling and error reporting.
- Add deal aging badge tests to confirm correct display of aging statuses.
- Implement tickets selection tests to ensure UI responsiveness and functionality at various screen sizes.
2026-09-26 16:53:22 +05:30

256 lines
9 KiB
Python

# Generated by Django 6.1.1 on 2026-09-26 08:16
import uuid
import django.db.models.deletion
from django.conf import settings
from django.db import connection, migrations, models
import webhooks.models
from common.rls import get_disable_policy_sql, get_enable_policy_sql
# Registered in common/rls/__init__.py:ORG_SCOPED_TABLES. One list here so the
# enable and disable directions cannot drift apart.
WEBHOOK_TABLES = ["webhook_endpoint", "webhook_delivery"]
def enable_rls(apps, schema_editor):
if connection.vendor != "postgresql":
return
with connection.cursor() as cursor:
for table in WEBHOOK_TABLES:
cursor.execute(get_enable_policy_sql(table))
def disable_rls(apps, schema_editor):
if connection.vendor != "postgresql":
return
with connection.cursor() as cursor:
for table in WEBHOOK_TABLES:
cursor.execute(get_disable_policy_sql(table))
class Migration(migrations.Migration):
initial = True
# RLS policy creation cannot run inside an atomic block.
atomic = False
dependencies = [
# 0042, not the newest: nothing here needs a later common migration.
("common", "0042_recompute_tag_slugs"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="WebhookEndpoint",
fields=[
(
"created_at",
models.DateTimeField(auto_now_add=True, verbose_name="Created At"),
),
(
"updated_at",
models.DateTimeField(
auto_now=True, verbose_name="Last Modified At"
),
),
(
"id",
models.UUIDField(
db_index=True,
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
unique=True,
),
),
("url", models.URLField(max_length=500)),
(
"description",
models.CharField(blank=True, default="", max_length=255),
),
("events", models.JSONField(default=list)),
(
"format",
models.CharField(
choices=[
("json", "Signed JSON"),
("slack", "Slack incoming webhook"),
],
default="json",
max_length=10,
),
),
("is_active", models.BooleanField(default=True)),
(
"disabled_reason",
models.CharField(blank=True, default="", max_length=255),
),
(
"secret",
models.CharField(
default=webhooks.models.generate_secret,
editable=False,
max_length=100,
),
),
(
"created_by",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="%(class)s_created_by",
to=settings.AUTH_USER_MODEL,
verbose_name="Created By",
),
),
(
"org",
models.ForeignKey(
help_text="Organization this record belongs to",
on_delete=django.db.models.deletion.CASCADE,
related_name="%(class)s_set",
to="common.org",
),
),
(
"updated_by",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="%(class)s_updated_by",
to=settings.AUTH_USER_MODEL,
verbose_name="Last Modified By",
),
),
],
options={
"db_table": "webhook_endpoint",
"ordering": ("-created_at",),
},
),
migrations.CreateModel(
name="WebhookDelivery",
fields=[
(
"created_at",
models.DateTimeField(auto_now_add=True, verbose_name="Created At"),
),
(
"updated_at",
models.DateTimeField(
auto_now=True, verbose_name="Last Modified At"
),
),
(
"id",
models.UUIDField(
db_index=True,
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
unique=True,
),
),
("event", models.CharField(max_length=64)),
("event_id", models.UUIDField()),
("payload", models.JSONField()),
(
"status",
models.CharField(
choices=[
("pending", "Pending"),
("succeeded", "Succeeded"),
("failed", "Failed"),
],
default="pending",
max_length=10,
),
),
("attempts", models.PositiveSmallIntegerField(default=0)),
(
"response_status",
models.PositiveSmallIntegerField(blank=True, null=True),
),
("error", models.CharField(blank=True, default="", max_length=255)),
("next_attempt_at", models.DateTimeField(blank=True, null=True)),
("last_attempt_at", models.DateTimeField(blank=True, null=True)),
(
"created_by",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="%(class)s_created_by",
to=settings.AUTH_USER_MODEL,
verbose_name="Created By",
),
),
(
"org",
models.ForeignKey(
help_text="Organization this record belongs to",
on_delete=django.db.models.deletion.CASCADE,
related_name="%(class)s_set",
to="common.org",
),
),
(
"updated_by",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="%(class)s_updated_by",
to=settings.AUTH_USER_MODEL,
verbose_name="Last Modified By",
),
),
(
"endpoint",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="deliveries",
to="webhooks.webhookendpoint",
),
),
],
options={
"db_table": "webhook_delivery",
"ordering": ("-created_at",),
},
),
migrations.AddIndex(
model_name="webhookendpoint",
index=models.Index(
fields=["org", "-created_at"], name="webhook_end_org_id_6f4e49_idx"
),
),
migrations.AddIndex(
model_name="webhookdelivery",
index=models.Index(
fields=["org", "-created_at"], name="webhook_del_org_id_9dcdff_idx"
),
),
migrations.AddIndex(
model_name="webhookdelivery",
index=models.Index(
fields=["endpoint", "-created_at"],
name="webhook_del_endpoin_de9b03_idx",
),
),
migrations.AddIndex(
model_name="webhookdelivery",
index=models.Index(
fields=["status", "next_attempt_at"],
name="webhook_del_status_f9cf36_idx",
),
),
migrations.RunPython(enable_rls, reverse_code=disable_rls),
]