From 024b26759ee7708d04fb1a10c865183aa495588e Mon Sep 17 00:00:00 2001 From: pablohashescobar Date: Fri, 1 Nov 2024 21:50:22 +0530 Subject: [PATCH 1/6] chore: device migration --- ...evice_token_issuetype_is_epic_and_more.py} | 13 +++++- apiserver/plane/db/models/device.py | 41 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) rename apiserver/plane/db/migrations/{0083_issuetype_is_epic_workspace_timezone_and_more.py => 0083_account_device_token_issuetype_is_epic_and_more.py} (98%) create mode 100644 apiserver/plane/db/models/device.py diff --git a/apiserver/plane/db/migrations/0083_issuetype_is_epic_workspace_timezone_and_more.py b/apiserver/plane/db/migrations/0083_account_device_token_issuetype_is_epic_and_more.py similarity index 98% rename from apiserver/plane/db/migrations/0083_issuetype_is_epic_workspace_timezone_and_more.py rename to apiserver/plane/db/migrations/0083_account_device_token_issuetype_is_epic_and_more.py index 4769c51442c..e509a619d32 100644 --- a/apiserver/plane/db/migrations/0083_issuetype_is_epic_workspace_timezone_and_more.py +++ b/apiserver/plane/db/migrations/0083_account_device_token_issuetype_is_epic_and_more.py @@ -1,15 +1,21 @@ -# Generated by Django 4.2.15 on 2024-11-01 15:21 +# Generated by Django 4.2.15 on 2024-11-01 16:14 from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): + dependencies = [ ("db", "0082_alter_issue_managers_alter_cycleissue_issue_and_more"), ] operations = [ + migrations.AddField( + model_name="account", + name="device_token", + field=models.TextField(blank=True, null=True), + ), migrations.AddField( model_name="issuetype", name="is_epic", @@ -663,6 +669,11 @@ class Migration(migrations.Migration): max_length=255, ), ), + migrations.AlterField( + model_name="account", + name="access_token", + field=models.TextField(blank=True, null=True), + ), migrations.AlterField( model_name="account", name="provider", diff --git a/apiserver/plane/db/models/device.py b/apiserver/plane/db/models/device.py new file mode 100644 index 00000000000..ea094254cd1 --- /dev/null +++ b/apiserver/plane/db/models/device.py @@ -0,0 +1,41 @@ +# models.py +from django.db import models +from django.conf import settings +from .base import BaseModel + + +class Device(BaseModel): + user = models.ForeignKey( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name="devices", + ) + device_id = models.CharField(max_length=255, blank=True, null=True) + device_type = models.CharField(max_length=255) + push_token = models.CharField(max_length=255, blank=True, null=True) + is_active = models.BooleanField(default=True) + + class Meta: + unique_together = ["user", "push_token"] + db_table = "devices" + verbose_name = "Device" + verbose_name_plural = "Devices" + + +class DeviceSession(BaseModel): + device = models.ForeignKey( + Device, + on_delete=models.CASCADE, + related_name="sessions", + ) + session_id = models.CharField(max_length=255) + is_active = models.BooleanField(default=True) + user_agent = models.CharField(max_length=255, null=True, blank=True) + ip_address = models.GenericIPAddressField(null=True, blank=True) + start_time = models.DateTimeField(auto_now_add=True) + end_time = models.DateTimeField(null=True, blank=True) + + class Meta: + db_table = "device_sessions" + verbose_name = "Device Session" + verbose_name_plural = "Device Sessions" From 9bb7a41cfdfc449e718413aff14bc79c02165b4d Mon Sep 17 00:00:00 2001 From: pablohashescobar Date: Fri, 1 Nov 2024 22:09:46 +0530 Subject: [PATCH 2/6] chore: devices --- ...083_device_workspace_timezone_and_more.py} | 181 +++++++++++++++--- apiserver/plane/db/models/__init__.py | 12 +- apiserver/plane/db/models/user.py | 4 +- 3 files changed, 170 insertions(+), 27 deletions(-) rename apiserver/plane/db/migrations/{0083_account_device_token_issuetype_is_epic_and_more.py => 0083_device_workspace_timezone_and_more.py} (86%) diff --git a/apiserver/plane/db/migrations/0083_account_device_token_issuetype_is_epic_and_more.py b/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py similarity index 86% rename from apiserver/plane/db/migrations/0083_account_device_token_issuetype_is_epic_and_more.py rename to apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py index e509a619d32..16bf7b2593f 100644 --- a/apiserver/plane/db/migrations/0083_account_device_token_issuetype_is_epic_and_more.py +++ b/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py @@ -1,7 +1,9 @@ -# Generated by Django 4.2.15 on 2024-11-01 16:14 +# Generated by Django 4.2.15 on 2024-11-01 16:33 +from django.conf import settings from django.db import migrations, models import django.db.models.deletion +import uuid class Migration(migrations.Migration): @@ -11,10 +13,83 @@ class Migration(migrations.Migration): ] operations = [ - migrations.AddField( - model_name="account", - name="device_token", - field=models.TextField(blank=True, null=True), + migrations.CreateModel( + name="Device", + 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" + ), + ), + ( + "deleted_at", + models.DateTimeField( + blank=True, null=True, verbose_name="Deleted At" + ), + ), + ( + "id", + models.UUIDField( + db_index=True, + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ( + "device_id", + models.CharField(blank=True, max_length=255, null=True), + ), + ("device_type", models.CharField(max_length=255)), + ( + "push_token", + models.CharField(blank=True, max_length=255, null=True), + ), + ("is_active", models.BooleanField(default=True)), + ( + "created_by", + models.ForeignKey( + 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", + ), + ), + ( + "updated_by", + models.ForeignKey( + 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", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="devices", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "verbose_name": "Device", + "verbose_name_plural": "Devices", + "db_table": "devices", + "unique_together": {("user", "push_token")}, + }, ), migrations.AddField( model_name="issuetype", @@ -669,23 +744,6 @@ class Migration(migrations.Migration): max_length=255, ), ), - migrations.AlterField( - model_name="account", - name="access_token", - field=models.TextField(blank=True, null=True), - ), - migrations.AlterField( - model_name="account", - name="provider", - field=models.CharField( - choices=[ - ("google", "Google"), - ("github", "Github"), - ("gitlab", "GitLab"), - ("firebase", "Firebase"), - ] - ), - ), migrations.AlterField( model_name="issuerelation", name="relation_type", @@ -717,4 +775,83 @@ class Migration(migrations.Migration): to="db.project", ), ), + migrations.CreateModel( + name="DeviceSession", + 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" + ), + ), + ( + "deleted_at", + models.DateTimeField( + blank=True, null=True, verbose_name="Deleted At" + ), + ), + ( + "id", + models.UUIDField( + db_index=True, + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + unique=True, + ), + ), + ("session_id", models.CharField(max_length=255)), + ("is_active", models.BooleanField(default=True)), + ( + "user_agent", + models.CharField(blank=True, max_length=255, null=True), + ), + ( + "ip_address", + models.GenericIPAddressField(blank=True, null=True), + ), + ("start_time", models.DateTimeField(auto_now_add=True)), + ("end_time", models.DateTimeField(blank=True, null=True)), + ( + "created_by", + models.ForeignKey( + 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", + ), + ), + ( + "device", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="sessions", + to="db.device", + ), + ), + ( + "updated_by", + models.ForeignKey( + 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={ + "verbose_name": "Device Session", + "verbose_name_plural": "Device Sessions", + "db_table": "device_sessions", + }, + ), ] diff --git a/apiserver/plane/db/models/__init__.py b/apiserver/plane/db/models/__init__.py index 94dc5008565..dd91a4b1d39 100644 --- a/apiserver/plane/db/models/__init__.py +++ b/apiserver/plane/db/models/__init__.py @@ -5,7 +5,13 @@ from .cycle import Cycle, CycleIssue, CycleUserProperties from .dashboard import Dashboard, DashboardWidget, Widget from .deploy_board import DeployBoard -from .draft import DraftIssue, DraftIssueAssignee, DraftIssueLabel, DraftIssueModule, DraftIssueCycle +from .draft import ( + DraftIssue, + DraftIssueAssignee, + DraftIssueLabel, + DraftIssueModule, + DraftIssueCycle, +) from .estimate import Estimate, EstimatePoint from .exporter import ExporterHistory from .importer import Importer @@ -109,4 +115,6 @@ from .recent_visit import UserRecentVisit -from .label import Label \ No newline at end of file +from .label import Label + +from .device import Device, DeviceSession diff --git a/apiserver/plane/db/models/user.py b/apiserver/plane/db/models/user.py index 81c766e98d3..3b84ec60e27 100644 --- a/apiserver/plane/db/models/user.py +++ b/apiserver/plane/db/models/user.py @@ -213,7 +213,6 @@ class Account(TimeAuditModel): ("google", "Google"), ("github", "Github"), ("gitlab", "GitLab"), - ("firebase", "Firebase"), ) id = models.UUIDField( @@ -230,8 +229,7 @@ class Account(TimeAuditModel): provider = models.CharField( choices=PROVIDER_CHOICES, ) - device_token = models.TextField(blank=True, null=True) - access_token = models.TextField(blank=True, null=True) + access_token = models.TextField() access_token_expired_at = models.DateTimeField(null=True) refresh_token = models.TextField(null=True, blank=True) refresh_token_expired_at = models.DateTimeField(null=True) From bb5118ae86124d327313d5e6fea561424659ad90 Mon Sep 17 00:00:00 2001 From: pablohashescobar Date: Fri, 1 Nov 2024 22:22:55 +0530 Subject: [PATCH 3/6] chore: update device migrations --- ...uetype_is_epic_workspace_timezone_and_more.py} | 15 +++++++++++++-- apiserver/plane/db/models/device.py | 10 +++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) rename apiserver/plane/db/migrations/{0083_device_workspace_timezone_and_more.py => 0083_device_issuetype_is_epic_workspace_timezone_and_more.py} (98%) diff --git a/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py b/apiserver/plane/db/migrations/0083_device_issuetype_is_epic_workspace_timezone_and_more.py similarity index 98% rename from apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py rename to apiserver/plane/db/migrations/0083_device_issuetype_is_epic_workspace_timezone_and_more.py index 16bf7b2593f..e5129e41339 100644 --- a/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py +++ b/apiserver/plane/db/migrations/0083_device_issuetype_is_epic_workspace_timezone_and_more.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.15 on 2024-11-01 16:33 +# Generated by Django 4.2.15 on 2024-11-01 16:51 from django.conf import settings from django.db import migrations, models @@ -49,7 +49,18 @@ class Migration(migrations.Migration): "device_id", models.CharField(blank=True, max_length=255, null=True), ), - ("device_type", models.CharField(max_length=255)), + ( + "device_type", + models.CharField( + choices=[ + ("ANDROID", "Android"), + ("IOS", "iOS"), + ("WEB", "Web"), + ("DESKTOP", "Desktop"), + ], + max_length=255, + ), + ), ( "push_token", models.CharField(blank=True, max_length=255, null=True), diff --git a/apiserver/plane/db/models/device.py b/apiserver/plane/db/models/device.py index ea094254cd1..2396998d8c8 100644 --- a/apiserver/plane/db/models/device.py +++ b/apiserver/plane/db/models/device.py @@ -5,13 +5,20 @@ class Device(BaseModel): + + class DeviceType(models.TextChoices): + ANDROID = "ANDROID", "Android" + IOS = "IOS", "iOS" + WEB = "WEB", "Web" + DESKTOP = "DESKTOP", "Desktop" + user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="devices", ) device_id = models.CharField(max_length=255, blank=True, null=True) - device_type = models.CharField(max_length=255) + device_type = models.CharField(max_length=255, choices=DeviceType.choices) push_token = models.CharField(max_length=255, blank=True, null=True) is_active = models.BooleanField(default=True) @@ -23,6 +30,7 @@ class Meta: class DeviceSession(BaseModel): + device = models.ForeignKey( Device, on_delete=models.CASCADE, From 20d716db10f58d88fc465004890446567f267c76 Mon Sep 17 00:00:00 2001 From: pablohashescobar Date: Fri, 1 Nov 2024 22:24:32 +0530 Subject: [PATCH 4/6] chore: update migration --- ...one_and_more.py => 0083_device_workspace_timezone_and_more.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apiserver/plane/db/migrations/{0083_device_issuetype_is_epic_workspace_timezone_and_more.py => 0083_device_workspace_timezone_and_more.py} (100%) diff --git a/apiserver/plane/db/migrations/0083_device_issuetype_is_epic_workspace_timezone_and_more.py b/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py similarity index 100% rename from apiserver/plane/db/migrations/0083_device_issuetype_is_epic_workspace_timezone_and_more.py rename to apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py From ef7f7847e6c48dd917431bc697959c551404f955 Mon Sep 17 00:00:00 2001 From: pablohashescobar Date: Fri, 1 Nov 2024 22:28:38 +0530 Subject: [PATCH 5/6] chore: update migrations --- .../0083_device_workspace_timezone_and_more.py | 11 +++++++++-- apiserver/plane/db/models/device.py | 8 +++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py b/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py index e5129e41339..ad6f0c684c8 100644 --- a/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py +++ b/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.15 on 2024-11-01 16:51 +# Generated by Django 4.2.15 on 2024-11-01 16:56 from django.conf import settings from django.db import migrations, models @@ -818,7 +818,6 @@ class Migration(migrations.Migration): unique=True, ), ), - ("session_id", models.CharField(max_length=255)), ("is_active", models.BooleanField(default=True)), ( "user_agent", @@ -848,6 +847,14 @@ class Migration(migrations.Migration): to="db.device", ), ), + ( + "session", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="device_sessions", + to="db.session", + ), + ), ( "updated_by", models.ForeignKey( diff --git a/apiserver/plane/db/models/device.py b/apiserver/plane/db/models/device.py index 2396998d8c8..55fb4a2f013 100644 --- a/apiserver/plane/db/models/device.py +++ b/apiserver/plane/db/models/device.py @@ -5,7 +5,6 @@ class Device(BaseModel): - class DeviceType(models.TextChoices): ANDROID = "ANDROID", "Android" IOS = "IOS", "iOS" @@ -30,13 +29,16 @@ class Meta: class DeviceSession(BaseModel): - device = models.ForeignKey( Device, on_delete=models.CASCADE, related_name="sessions", ) - session_id = models.CharField(max_length=255) + session = models.ForeignKey( + "db.Session", + on_delete=models.CASCADE, + related_name="device_sessions", + ) is_active = models.BooleanField(default=True) user_agent = models.CharField(max_length=255, null=True, blank=True) ip_address = models.GenericIPAddressField(null=True, blank=True) From 39e8f5888c3b1c13c195e2934b965b7eebb377e3 Mon Sep 17 00:00:00 2001 From: pablohashescobar Date: Fri, 1 Nov 2024 22:38:53 +0530 Subject: [PATCH 6/6] chore: update device migrations --- .../db/migrations/0083_device_workspace_timezone_and_more.py | 3 +-- apiserver/plane/db/models/device.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py b/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py index ad6f0c684c8..587ee880006 100644 --- a/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py +++ b/apiserver/plane/db/migrations/0083_device_workspace_timezone_and_more.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.15 on 2024-11-01 16:56 +# Generated by Django 4.2.15 on 2024-11-01 17:02 from django.conf import settings from django.db import migrations, models @@ -99,7 +99,6 @@ class Migration(migrations.Migration): "verbose_name": "Device", "verbose_name_plural": "Devices", "db_table": "devices", - "unique_together": {("user", "push_token")}, }, ), migrations.AddField( diff --git a/apiserver/plane/db/models/device.py b/apiserver/plane/db/models/device.py index 55fb4a2f013..862861f9011 100644 --- a/apiserver/plane/db/models/device.py +++ b/apiserver/plane/db/models/device.py @@ -22,7 +22,6 @@ class DeviceType(models.TextChoices): is_active = models.BooleanField(default=True) class Meta: - unique_together = ["user", "push_token"] db_table = "devices" verbose_name = "Device" verbose_name_plural = "Devices"