diff --git a/temba/flows/migrations/0380_remove_flowrun_session.py b/temba/flows/migrations/0380_remove_flowrun_session.py new file mode 100644 index 0000000000..2abb6c97a0 --- /dev/null +++ b/temba/flows/migrations/0380_remove_flowrun_session.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.4 on 2025-02-26 22:21 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("flows", "0379_remove_flowrun_flows_run_active_or_waiting_has_session"), + ] + + operations = [ + migrations.RemoveField( + model_name="flowrun", + name="session", + ), + ] diff --git a/temba/flows/models.py b/temba/flows/models.py index 87773b4846..d1105ceba8 100644 --- a/temba/flows/models.py +++ b/temba/flows/models.py @@ -1137,9 +1137,6 @@ class FlowRun(models.Model): # current node location of this run in the flow current_node_uuid = models.UUIDField(null=True) - # TODO drop - session = models.ForeignKey(FlowSession, on_delete=models.PROTECT, null=True) - @dataclass class Step: node: UUID diff --git a/temba/flows/tasks.py b/temba/flows/tasks.py index 820a0d261f..225d4c810d 100644 --- a/temba/flows/tasks.py +++ b/temba/flows/tasks.py @@ -9,7 +9,7 @@ from temba.utils.crons import cron_task from temba.utils.models import delete_in_batches -from .models import FlowActivityCount, FlowResultCount, FlowRevision, FlowRun, FlowSession, FlowStartCount +from .models import FlowActivityCount, FlowResultCount, FlowRevision, FlowSession, FlowStartCount logger = logging.getLogger(__name__) @@ -45,10 +45,6 @@ def trim_flow_sessions(): trim_before = timezone.now() - settings.RETENTION_PERIODS["flowsession"] - def pre_delete(session_ids): - # detach any flows runs that belong to these sessions - FlowRun.objects.filter(session_id__in=session_ids).update(session_id=None) - - num_deleted = delete_in_batches(FlowSession.objects.filter(ended_on__lte=trim_before), pre_delete=pre_delete) + num_deleted = delete_in_batches(FlowSession.objects.filter(ended_on__lte=trim_before)) return {"deleted": num_deleted} diff --git a/temba/flows/tests/test_counts.py b/temba/flows/tests/test_counts.py index 0ccd0b3653..dcae343a77 100644 --- a/temba/flows/tests/test_counts.py +++ b/temba/flows/tests/test_counts.py @@ -71,10 +71,10 @@ def create_runs(flow_status_pairs: tuple) -> list: FlowRun( uuid=uuid4(), org=self.org, - session=session, flow=flow, contact=contact, status=status, + session_uuid=session.uuid, created_on=timezone.now(), modified_on=timezone.now(), exited_on=timezone.now() if status not in ("A", "W") else None, diff --git a/temba/flows/tests/test_session.py b/temba/flows/tests/test_session.py index 86a1321a5f..ae74202ba1 100644 --- a/temba/flows/tests/test_session.py +++ b/temba/flows/tests/test_session.py @@ -1,8 +1,8 @@ -from datetime import datetime, timezone as tzone +from datetime import datetime, timedelta, timezone as tzone from django.utils import timezone -from temba.flows.models import FlowRun, FlowSession +from temba.flows.models import FlowSession from temba.flows.tasks import trim_flow_sessions from temba.tests import TembaTest from temba.utils.uuid import uuid4 @@ -11,20 +11,20 @@ class FlowSessionTest(TembaTest): def test_trim(self): contact = self.create_contact("Ben Haggerty", phone="+250788123123") - flow = self.create_flow("Test") - # create some runs that have sessions session1 = FlowSession.objects.create( uuid=uuid4(), contact=contact, output_url="http://sessions.com/123.json", - status=FlowSession.STATUS_WAITING, + status=FlowSession.STATUS_COMPLETED, + ended_on=datetime(2025, 1, 15, 0, 0, 0, 0, tzone.utc), ) session2 = FlowSession.objects.create( uuid=uuid4(), contact=contact, output_url="http://sessions.com/234.json", - status=FlowSession.STATUS_WAITING, + status=FlowSession.STATUS_COMPLETED, + ended_on=datetime(2025, 1, 16, 0, 0, 0, 0, tzone.utc), ) session3 = FlowSession.objects.create( uuid=uuid4(), @@ -32,71 +32,17 @@ def test_trim(self): output_url="http://sessions.com/345.json", status=FlowSession.STATUS_WAITING, ) - run1 = FlowRun.objects.create( - org=self.org, - flow=flow, - contact=contact, - session=session1, - session_uuid=session1.uuid, - status=FlowRun.STATUS_WAITING, - ) - run2 = FlowRun.objects.create( - org=self.org, - flow=flow, - contact=contact, - session=session2, - session_uuid=session2.uuid, - status=FlowRun.STATUS_WAITING, - ) - run3 = FlowRun.objects.create( - org=self.org, - flow=flow, + session4 = FlowSession.objects.create( + uuid=uuid4(), contact=contact, - session=session3, - session_uuid=session3.uuid, - status=FlowRun.STATUS_WAITING, + output_url="http://sessions.com/345.json", + status=FlowSession.STATUS_COMPLETED, + ended_on=timezone.now() - timedelta(days=3), ) - # create an IVR call with session - call = self.create_incoming_call(flow, contact) - run4 = FlowRun.objects.get(session_uuid=call.session_uuid) - - self.assertIsNotNone(run1.session) - self.assertIsNotNone(run2.session) - self.assertIsNotNone(run3.session) - self.assertIsNotNone(run4.session) - - # end run1 and run4's sessions in the past - run1.status = FlowRun.STATUS_COMPLETED - run1.exited_on = datetime(2015, 9, 15, 0, 0, 0, 0, tzone.utc) - run1.save(update_fields=("status", "exited_on")) - run1.session.status = FlowSession.STATUS_COMPLETED - run1.session.ended_on = datetime(2015, 9, 15, 0, 0, 0, 0, tzone.utc) - run1.session.save(update_fields=("status", "ended_on")) - - run4.status = FlowRun.STATUS_INTERRUPTED - run4.exited_on = datetime(2015, 9, 15, 0, 0, 0, 0, tzone.utc) - run4.save(update_fields=("status", "exited_on")) - run4.session.status = FlowSession.STATUS_INTERRUPTED - run4.session.ended_on = datetime(2015, 9, 15, 0, 0, 0, 0, tzone.utc) - run4.session.save(update_fields=("status", "ended_on")) - - # end run2's session now - run2.status = FlowRun.STATUS_EXPIRED - run2.exited_on = timezone.now() - run2.save(update_fields=("status", "exited_on")) - run4.session.status = FlowSession.STATUS_COMPLETED - run2.session.ended_on = timezone.now() - run2.session.save(update_fields=("status", "ended_on")) - trim_flow_sessions() - run1, run2, run3, run4 = FlowRun.objects.order_by("id") - - self.assertIsNone(run1.session) - self.assertIsNotNone(run2.session) # ended too recently to be deleted - self.assertIsNotNone(run3.session) # never ended - self.assertIsNone(run4.session) - - # only sessions for run2 and run3 are left - self.assertEqual(FlowSession.objects.count(), 2) + self.assertFalse(FlowSession.objects.filter(id=session1.id).exists()) + self.assertFalse(FlowSession.objects.filter(id=session2.id).exists()) + self.assertTrue(FlowSession.objects.filter(id=session3.id).exists()) # not ended + self.assertTrue(FlowSession.objects.filter(id=session4.id).exists()) # ended too recently diff --git a/temba/tests/base.py b/temba/tests/base.py index e600c927c5..d724843640 100644 --- a/temba/tests/base.py +++ b/temba/tests/base.py @@ -581,7 +581,6 @@ def create_incoming_call( flow=flow, contact=contact, status=FlowRun.STATUS_COMPLETED, - session=session, session_uuid=session.uuid, exited_on=timezone.now(), )