Skip to content

Commit afc6a8e

Browse files
feat(business): replace numeric ID with UUID for Company and Promo models.
1 parent fc7324d commit afc6a8e

File tree

6 files changed

+130
-106
lines changed

6 files changed

+130
-106
lines changed

promo_code/business/migrations/0001_initial.py

Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
# Generated by Django 5.2b1 on 2025-03-25 14:18
1+
# Generated by Django 5.2b1 on 2025-03-30 18:24
22

3+
import django.db.models.deletion
4+
import uuid
35
from django.db import migrations, models
46

57

@@ -13,15 +15,6 @@ class Migration(migrations.Migration):
1315
migrations.CreateModel(
1416
name='Company',
1517
fields=[
16-
(
17-
'id',
18-
models.BigAutoField(
19-
auto_created=True,
20-
primary_key=True,
21-
serialize=False,
22-
verbose_name='ID',
23-
),
24-
),
2518
(
2619
'password',
2720
models.CharField(max_length=128, verbose_name='password'),
@@ -32,6 +25,16 @@ class Migration(migrations.Migration):
3225
blank=True, null=True, verbose_name='last login'
3326
),
3427
),
28+
(
29+
'id',
30+
models.UUIDField(
31+
default=uuid.uuid4,
32+
editable=False,
33+
primary_key=True,
34+
serialize=False,
35+
verbose_name='UUID',
36+
),
37+
),
3538
('email', models.EmailField(max_length=120, unique=True)),
3639
('name', models.CharField(max_length=50)),
3740
('token_version', models.IntegerField(default=0)),
@@ -42,4 +45,78 @@ class Migration(migrations.Migration):
4245
'abstract': False,
4346
},
4447
),
48+
migrations.CreateModel(
49+
name='Promo',
50+
fields=[
51+
(
52+
'id',
53+
models.UUIDField(
54+
default=uuid.uuid4,
55+
editable=False,
56+
primary_key=True,
57+
serialize=False,
58+
verbose_name='UUID',
59+
),
60+
),
61+
('description', models.CharField(max_length=300)),
62+
(
63+
'image_url',
64+
models.URLField(blank=True, max_length=350, null=True),
65+
),
66+
('target', models.JSONField(default=dict)),
67+
('max_count', models.IntegerField()),
68+
('active_from', models.DateField(blank=True, null=True)),
69+
('active_until', models.DateField(blank=True, null=True)),
70+
(
71+
'mode',
72+
models.CharField(
73+
choices=[('COMMON', 'Common'), ('UNIQUE', 'Unique')],
74+
max_length=10,
75+
),
76+
),
77+
(
78+
'promo_common',
79+
models.CharField(blank=True, max_length=30, null=True),
80+
),
81+
('active', models.BooleanField(default=True)),
82+
('created_at', models.DateTimeField(auto_now_add=True)),
83+
(
84+
'company',
85+
models.ForeignKey(
86+
blank=True,
87+
null=True,
88+
on_delete=django.db.models.deletion.CASCADE,
89+
to='business.company',
90+
),
91+
),
92+
],
93+
),
94+
migrations.CreateModel(
95+
name='PromoCode',
96+
fields=[
97+
(
98+
'id',
99+
models.BigAutoField(
100+
auto_created=True,
101+
primary_key=True,
102+
serialize=False,
103+
verbose_name='ID',
104+
),
105+
),
106+
('code', models.CharField(max_length=30)),
107+
('is_used', models.BooleanField(default=False)),
108+
('used_at', models.DateTimeField(blank=True, null=True)),
109+
(
110+
'promo',
111+
models.ForeignKey(
112+
on_delete=django.db.models.deletion.CASCADE,
113+
related_name='unique_codes',
114+
to='business.promo',
115+
),
116+
),
117+
],
118+
options={
119+
'unique_together': {('promo', 'code')},
120+
},
121+
),
45122
]

promo_code/business/migrations/0002_promo_promocode.py

Lines changed: 0 additions & 87 deletions
This file was deleted.

promo_code/business/models.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import uuid
2+
13
import django.contrib.auth.models
24
import django.db.models
35

@@ -19,6 +21,12 @@ def create_company(self, email, name, password=None, **extra_fields):
1921

2022

2123
class Company(django.contrib.auth.models.AbstractBaseUser):
24+
id = django.db.models.UUIDField(
25+
'UUID',
26+
primary_key=True,
27+
default=uuid.uuid4,
28+
editable=False,
29+
)
2230
email = django.db.models.EmailField(
2331
unique=True,
2432
max_length=120,
@@ -46,6 +54,13 @@ class Promo(django.db.models.Model):
4654
(MODE_UNIQUE, 'Unique'),
4755
]
4856

57+
id = django.db.models.UUIDField(
58+
'UUID',
59+
primary_key=True,
60+
default=uuid.uuid4,
61+
editable=False,
62+
)
63+
4964
company = django.db.models.ForeignKey(
5065
Company,
5166
on_delete=django.db.models.CASCADE,
@@ -81,6 +96,7 @@ class PromoCode(django.db.models.Model):
8196
Promo,
8297
on_delete=django.db.models.CASCADE,
8398
related_name='unique_codes',
99+
to_field='id',
84100
)
85101
code = django.db.models.CharField(max_length=30)
86102
is_used = django.db.models.BooleanField(default=False)

promo_code/business/serializers.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import uuid
2+
13
import django.contrib.auth.password_validation
24
import django.core.exceptions
35
import django.core.validators
@@ -15,6 +17,7 @@
1517

1618

1719
class CompanySignUpSerializer(rest_framework.serializers.ModelSerializer):
20+
id = rest_framework.serializers.UUIDField(read_only=True)
1821
password = rest_framework.serializers.CharField(
1922
write_only=True,
2023
required=True,
@@ -43,6 +46,7 @@ class CompanySignUpSerializer(rest_framework.serializers.ModelSerializer):
4346
class Meta:
4447
model = business_models.Company
4548
fields = (
49+
'id',
4650
'name',
4751
'email',
4852
'password',
@@ -119,7 +123,9 @@ def validate(self, attrs):
119123
)
120124

121125
try:
122-
company = business_models.Company.objects.get(id=company_id)
126+
company = business_models.Company.objects.get(
127+
id=uuid.UUID(company_id),
128+
)
123129
except business_models.Company.DoesNotExist:
124130
raise rest_framework_simplejwt.exceptions.InvalidToken(
125131
'Company not found',
@@ -131,7 +137,15 @@ def validate(self, attrs):
131137
'Token is blacklisted',
132138
)
133139

134-
return super().validate(attrs)
140+
new_refresh = rest_framework_simplejwt.tokens.RefreshToken()
141+
new_refresh['user_type'] = 'company'
142+
new_refresh['company_id'] = str(company.id)
143+
new_refresh['token_version'] = company.token_version
144+
145+
return {
146+
'access': str(new_refresh.access_token),
147+
'refresh': str(new_refresh),
148+
}
135149

136150

137151
class TargetSerializer(rest_framework.serializers.Serializer):

promo_code/business/tests/auth/test_tokens.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def setUp(self):
109109
self.company_refresh.payload.update(
110110
{
111111
'user_type': 'company',
112-
'company_id': self.company.id,
112+
'company_id': str(self.company.id),
113113
'token_version': self.company.token_version,
114114
},
115115
)
@@ -194,7 +194,11 @@ def test_missing_company_id(self):
194194
def test_company_not_found(self):
195195
invalid_refresh = rest_framework_simplejwt.tokens.RefreshToken()
196196
invalid_refresh.payload.update(
197-
{'user_type': 'company', 'company_id': 999, 'token_version': 1},
197+
{
198+
'user_type': 'company',
199+
'company_id': 'da3ad08d-9b86-41ff-ad70-a30a64d3d170',
200+
'token_version': 1,
201+
},
198202
)
199203

200204
response = self.client.post(

promo_code/business/views.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ def post(self, request):
3737

3838
refresh = rest_framework_simplejwt.tokens.RefreshToken()
3939
refresh['user_type'] = 'company'
40-
refresh['company_id'] = company.id
40+
refresh['company_id'] = str(company.id)
4141
refresh['token_version'] = company.token_version
4242

4343
access_token = refresh.access_token
4444
access_token['user_type'] = 'company'
45-
access_token['company_id'] = company.id
45+
access_token['company_id'] = str(company.id)
4646
refresh['token_version'] = company.token_version
4747

4848
response_data = {
@@ -83,12 +83,12 @@ def post(self, request):
8383

8484
refresh = rest_framework_simplejwt.tokens.RefreshToken()
8585
refresh['user_type'] = 'company'
86-
refresh['company_id'] = company.id
86+
refresh['company_id'] = str(company.id)
8787
refresh['token_version'] = company.token_version
8888

8989
access_token = refresh.access_token
9090
access_token['user_type'] = 'company'
91-
access_token['company_id'] = company.id
91+
access_token['company_id'] = str(company.id)
9292

9393
response_data = {
9494
'access': str(access_token),
@@ -120,7 +120,7 @@ def post(self, request, *args, **kwargs):
120120
if serializer.is_valid():
121121
instance = serializer.save()
122122
return rest_framework.response.Response(
123-
{'id': instance.id},
123+
{'id': str(instance.id)},
124124
status=rest_framework.status.HTTP_201_CREATED,
125125
)
126126

0 commit comments

Comments
 (0)