Shri Jayaram commited on
Commit
49bb65c
·
unverified ·
2 Parent(s): 735e535 87c52f8

Merge pull request #30 from yuvabe-ai-labs/feat/chatbot

Browse files
alembic/versions/5b5a3c7a6255_update_cascade_deletion.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """update: cascade deletion
2
+
3
+ Revision ID: 5b5a3c7a6255
4
+ Revises: 52828bff621c
5
+ Create Date: 2025-11-28 11:27:38.960269
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+ import sqlmodel.sql.sqltypes
13
+
14
+
15
+ # revision identifiers, used by Alembic.
16
+ revision: str = '5b5a3c7a6255'
17
+ down_revision: Union[str, Sequence[str], None] = '52828bff621c'
18
+ branch_labels: Union[str, Sequence[str], None] = None
19
+ depends_on: Union[str, Sequence[str], None] = None
20
+
21
+
22
+ def upgrade() -> None:
23
+ """Upgrade schema."""
24
+ # ### commands auto generated by Alembic - please adjust! ###
25
+ op.drop_constraint(op.f('assets_user_id_fkey'), 'assets', type_='foreignkey')
26
+ op.create_foreign_key(None, 'assets', 'users', ['user_id'], ['id'], ondelete='CASCADE')
27
+ op.drop_constraint(op.f('comments_user_id_fkey'), 'comments', type_='foreignkey')
28
+ op.drop_constraint(op.f('comments_post_id_fkey'), 'comments', type_='foreignkey')
29
+ op.create_foreign_key(None, 'comments', 'posts', ['post_id'], ['id'], ondelete='CASCADE')
30
+ op.create_foreign_key(None, 'comments', 'users', ['user_id'], ['id'], ondelete='CASCADE')
31
+ op.drop_constraint(op.f('emotion_logs_user_id_fkey'), 'emotion_logs', type_='foreignkey')
32
+ op.create_foreign_key(None, 'emotion_logs', 'users', ['user_id'], ['id'], ondelete='CASCADE')
33
+ op.drop_constraint(op.f('knowledge_chunk_kb_id_fkey'), 'knowledge_chunk', type_='foreignkey')
34
+ op.create_foreign_key(None, 'knowledge_chunk', 'knowledge_base', ['kb_id'], ['id'], ondelete='CASCADE')
35
+ op.alter_column('leave', 'mentor_id',
36
+ existing_type=sa.UUID(),
37
+ nullable=True)
38
+ op.alter_column('leave', 'lead_id',
39
+ existing_type=sa.UUID(),
40
+ nullable=True)
41
+ op.drop_constraint(op.f('leave_lead_id_fkey'), 'leave', type_='foreignkey')
42
+ op.drop_constraint(op.f('leave_user_id_fkey'), 'leave', type_='foreignkey')
43
+ op.drop_constraint(op.f('leave_mentor_id_fkey'), 'leave', type_='foreignkey')
44
+ op.create_foreign_key(None, 'leave', 'users', ['user_id'], ['id'], ondelete='CASCADE')
45
+ op.create_foreign_key(None, 'leave', 'users', ['mentor_id'], ['id'], ondelete='SET NULL')
46
+ op.create_foreign_key(None, 'leave', 'users', ['lead_id'], ['id'], ondelete='SET NULL')
47
+ op.drop_constraint(op.f('likes_user_id_fkey'), 'likes', type_='foreignkey')
48
+ op.drop_constraint(op.f('likes_post_id_fkey'), 'likes', type_='foreignkey')
49
+ op.create_foreign_key(None, 'likes', 'users', ['user_id'], ['id'], ondelete='CASCADE')
50
+ op.create_foreign_key(None, 'likes', 'posts', ['post_id'], ['id'], ondelete='CASCADE')
51
+ op.drop_constraint(op.f('user_devices_user_id_fkey'), 'user_devices', type_='foreignkey')
52
+ op.create_foreign_key(None, 'user_devices', 'users', ['user_id'], ['id'], ondelete='CASCADE')
53
+ op.drop_constraint(op.f('user_teams_role_team_id_fkey'), 'user_teams_role', type_='foreignkey')
54
+ op.drop_constraint(op.f('user_teams_role_role_id_fkey'), 'user_teams_role', type_='foreignkey')
55
+ op.drop_constraint(op.f('user_teams_role_user_id_fkey'), 'user_teams_role', type_='foreignkey')
56
+ op.create_foreign_key(None, 'user_teams_role', 'teams', ['team_id'], ['id'], ondelete='CASCADE')
57
+ op.create_foreign_key(None, 'user_teams_role', 'users', ['user_id'], ['id'], ondelete='CASCADE')
58
+ op.create_foreign_key(None, 'user_teams_role', 'roles', ['role_id'], ['id'], ondelete='CASCADE')
59
+ # ### end Alembic commands ###
60
+
61
+
62
+ def downgrade() -> None:
63
+ """Downgrade schema."""
64
+ # ### commands auto generated by Alembic - please adjust! ###
65
+ op.drop_constraint(None, 'user_teams_role', type_='foreignkey')
66
+ op.drop_constraint(None, 'user_teams_role', type_='foreignkey')
67
+ op.drop_constraint(None, 'user_teams_role', type_='foreignkey')
68
+ op.create_foreign_key(op.f('user_teams_role_user_id_fkey'), 'user_teams_role', 'users', ['user_id'], ['id'])
69
+ op.create_foreign_key(op.f('user_teams_role_role_id_fkey'), 'user_teams_role', 'roles', ['role_id'], ['id'])
70
+ op.create_foreign_key(op.f('user_teams_role_team_id_fkey'), 'user_teams_role', 'teams', ['team_id'], ['id'])
71
+ op.drop_constraint(None, 'user_devices', type_='foreignkey')
72
+ op.create_foreign_key(op.f('user_devices_user_id_fkey'), 'user_devices', 'users', ['user_id'], ['id'])
73
+ op.drop_constraint(None, 'likes', type_='foreignkey')
74
+ op.drop_constraint(None, 'likes', type_='foreignkey')
75
+ op.create_foreign_key(op.f('likes_post_id_fkey'), 'likes', 'posts', ['post_id'], ['id'])
76
+ op.create_foreign_key(op.f('likes_user_id_fkey'), 'likes', 'users', ['user_id'], ['id'])
77
+ op.drop_constraint(None, 'leave', type_='foreignkey')
78
+ op.drop_constraint(None, 'leave', type_='foreignkey')
79
+ op.drop_constraint(None, 'leave', type_='foreignkey')
80
+ op.create_foreign_key(op.f('leave_mentor_id_fkey'), 'leave', 'users', ['mentor_id'], ['id'])
81
+ op.create_foreign_key(op.f('leave_user_id_fkey'), 'leave', 'users', ['user_id'], ['id'])
82
+ op.create_foreign_key(op.f('leave_lead_id_fkey'), 'leave', 'users', ['lead_id'], ['id'])
83
+ op.alter_column('leave', 'lead_id',
84
+ existing_type=sa.UUID(),
85
+ nullable=False)
86
+ op.alter_column('leave', 'mentor_id',
87
+ existing_type=sa.UUID(),
88
+ nullable=False)
89
+ op.drop_constraint(None, 'knowledge_chunk', type_='foreignkey')
90
+ op.create_foreign_key(op.f('knowledge_chunk_kb_id_fkey'), 'knowledge_chunk', 'knowledge_base', ['kb_id'], ['id'])
91
+ op.drop_constraint(None, 'emotion_logs', type_='foreignkey')
92
+ op.create_foreign_key(op.f('emotion_logs_user_id_fkey'), 'emotion_logs', 'users', ['user_id'], ['id'])
93
+ op.drop_constraint(None, 'comments', type_='foreignkey')
94
+ op.drop_constraint(None, 'comments', type_='foreignkey')
95
+ op.create_foreign_key(op.f('comments_post_id_fkey'), 'comments', 'posts', ['post_id'], ['id'])
96
+ op.create_foreign_key(op.f('comments_user_id_fkey'), 'comments', 'users', ['user_id'], ['id'])
97
+ op.drop_constraint(None, 'assets', type_='foreignkey')
98
+ op.create_foreign_key(op.f('assets_user_id_fkey'), 'assets', 'users', ['user_id'], ['id'])
99
+ # ### end Alembic commands ###
alembic/versions/e96769f268bc_fix_post_s_user_cascade.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """fix: post's user cascade
2
+
3
+ Revision ID: e96769f268bc
4
+ Revises: 5b5a3c7a6255
5
+ Create Date: 2025-11-28 11:58:45.282329
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+ import sqlmodel.sql.sqltypes
13
+
14
+
15
+ # revision identifiers, used by Alembic.
16
+ revision: str = 'e96769f268bc'
17
+ down_revision: Union[str, Sequence[str], None] = '5b5a3c7a6255'
18
+ branch_labels: Union[str, Sequence[str], None] = None
19
+ depends_on: Union[str, Sequence[str], None] = None
20
+
21
+
22
+ def upgrade() -> None:
23
+ """Upgrade schema."""
24
+ # ### commands auto generated by Alembic - please adjust! ###
25
+ op.alter_column('posts', 'user_id',
26
+ existing_type=sa.UUID(),
27
+ nullable=True)
28
+ op.drop_constraint(op.f('posts_user_id_fkey'), 'posts', type_='foreignkey')
29
+ op.create_foreign_key(None, 'posts', 'users', ['user_id'], ['id'], ondelete='SET NULL')
30
+ # ### end Alembic commands ###
31
+
32
+
33
+ def downgrade() -> None:
34
+ """Downgrade schema."""
35
+ # ### commands auto generated by Alembic - please adjust! ###
36
+ op.drop_constraint(None, 'posts', type_='foreignkey')
37
+ op.create_foreign_key(op.f('posts_user_id_fkey'), 'posts', 'users', ['user_id'], ['id'])
38
+ op.alter_column('posts', 'user_id',
39
+ existing_type=sa.UUID(),
40
+ nullable=False)
41
+ # ### end Alembic commands ###
src/chatbot/models.py CHANGED
@@ -4,7 +4,9 @@ from typing import List
4
 
5
  from pgvector.sqlalchemy import Vector
6
  from sqlalchemy import Column
7
- from sqlmodel import Field, Relationship, SQLModel
 
 
8
 
9
 
10
  class KnowledgeBase(SQLModel, table=True):
@@ -21,7 +23,12 @@ class KnowledgeBase(SQLModel, table=True):
21
  class KnowledgeChunk(SQLModel, table=True):
22
  __tablename__ = "knowledge_chunk"
23
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
24
- kb_id: uuid.UUID = Field(foreign_key="knowledge_base.id", nullable=False)
 
 
 
 
 
25
  chunk_index: int
26
  chunk_text: str
27
  embedding: List[float] = Field(sa_column=Column(Vector(768)))
 
4
 
5
  from pgvector.sqlalchemy import Vector
6
  from sqlalchemy import Column
7
+ from sqlmodel import Field, Relationship, SQLModel, ForeignKey
8
+
9
+ from sqlalchemy.dialects.postgresql import UUID
10
 
11
 
12
  class KnowledgeBase(SQLModel, table=True):
 
23
  class KnowledgeChunk(SQLModel, table=True):
24
  __tablename__ = "knowledge_chunk"
25
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
26
+ kb_id: uuid.UUID = Field(
27
+ sa_column=Column(UUID(as_uuid=True),
28
+ ForeignKey("knowledge_base.id", ondelete="CASCADE"),
29
+ nullable=False
30
+ )
31
+ )
32
  chunk_index: int
33
  chunk_text: str
34
  embedding: List[float] = Field(sa_column=Column(Vector(768)))
src/core/models.py CHANGED
@@ -6,7 +6,8 @@ from enum import Enum
6
  from typing import List, Optional
7
 
8
 
9
- from sqlalchemy import CheckConstraint, UniqueConstraint
 
10
  from sqlmodel import Field, Relationship, SQLModel
11
 
12
 
@@ -48,15 +49,34 @@ class Roles(SQLModel, table=True):
48
  class UserTeamsRole(SQLModel, table=True):
49
  __tablename__ = "user_teams_role"
50
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
51
- user_id: uuid.UUID = Field(foreign_key="users.id", nullable=False)
52
- team_id: uuid.UUID = Field(foreign_key="teams.id", nullable=False)
53
- role_id: uuid.UUID = Field(foreign_key="roles.id", nullable=False)
54
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  class Assets(SQLModel, table=True):
57
  __tablename__ = "assets"
58
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
59
- user_id: uuid.UUID = Field(foreign_key="users.id", nullable=False)
 
 
 
 
 
60
  name: str = Field(nullable=False)
61
  type: str = Field(nullable=False)
62
  status: AssetStatus = Field(default=AssetStatus.UNAVAILABLE)
@@ -71,7 +91,12 @@ class EmotionLogs(SQLModel, table=True):
71
  CheckConstraint("evening_emotion BETWEEN 1 AND 7 or evening_emotion IS NULL"),
72
  )
73
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
74
- user_id: uuid.UUID = Field(foreign_key="users.id", nullable=False)
 
 
 
 
 
75
  morning_emotion: Optional[int] = Field(default=None, ge=1, le=7)
76
  evening_emotion: Optional[int] = Field(default=None, ge=1, le=7)
77
  log_date: date = Field(default_factory=date.today)
 
6
  from typing import List, Optional
7
 
8
 
9
+ from sqlalchemy.dialects.postgresql import UUID
10
+ from sqlalchemy import CheckConstraint, UniqueConstraint, ForeignKey
11
  from sqlmodel import Field, Relationship, SQLModel
12
 
13
 
 
49
  class UserTeamsRole(SQLModel, table=True):
50
  __tablename__ = "user_teams_role"
51
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
52
+ user_id: uuid.UUID = Field(
53
+ sa_column=Column(UUID(as_uuid=True),
54
+ ForeignKey("users.id", ondelete="CASCADE"),
55
+ nullable=False
56
+ )
57
+ )
58
+ team_id: uuid.UUID = Field(
59
+ sa_column=Column(UUID(as_uuid=True),
60
+ ForeignKey("teams.id", ondelete="CASCADE"),
61
+ nullable=False
62
+ )
63
+ )
64
+ role_id: uuid.UUID = Field(
65
+ sa_column=Column(UUID(as_uuid=True),
66
+ ForeignKey("roles.id", ondelete="CASCADE"),
67
+ nullable=False
68
+ )
69
+ )
70
 
71
  class Assets(SQLModel, table=True):
72
  __tablename__ = "assets"
73
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
74
+ user_id: uuid.UUID = Field(
75
+ sa_column=Column(UUID(as_uuid=True),
76
+ ForeignKey("users.id", ondelete="CASCADE"),
77
+ nullable=False
78
+ )
79
+ )
80
  name: str = Field(nullable=False)
81
  type: str = Field(nullable=False)
82
  status: AssetStatus = Field(default=AssetStatus.UNAVAILABLE)
 
91
  CheckConstraint("evening_emotion BETWEEN 1 AND 7 or evening_emotion IS NULL"),
92
  )
93
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
94
+ user_id: uuid.UUID = Field(
95
+ sa_column=Column(UUID(as_uuid=True),
96
+ ForeignKey("users.id", ondelete="CASCADE"),
97
+ nullable=False
98
+ )
99
+ )
100
  morning_emotion: Optional[int] = Field(default=None, ge=1, le=7)
101
  evening_emotion: Optional[int] = Field(default=None, ge=1, le=7)
102
  log_date: date = Field(default_factory=date.today)
src/feed/models.py CHANGED
@@ -3,8 +3,9 @@ from datetime import datetime
3
  from enum import Enum
4
  from typing import Optional
5
 
6
- from sqlalchemy import UniqueConstraint
7
  from sqlmodel import Field, SQLModel
 
8
 
9
 
10
  class PostType(str, Enum):
@@ -22,7 +23,12 @@ class PostCategory(str, Enum):
22
  class Posts(SQLModel, table=True):
23
  __tablename__ = "posts"
24
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
25
- user_id: uuid.UUID = Field(foreign_key="users.id", nullable=False)
 
 
 
 
 
26
  type: PostType = Field(default=PostType.NOTICE)
27
  category: PostCategory = Field(default=PostCategory.GLOBAL)
28
  caption: Optional[str] = None
@@ -34,8 +40,18 @@ class Posts(SQLModel, table=True):
34
  class Comments(SQLModel, table=True):
35
  __tablename__ = "comments"
36
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
37
- post_id: uuid.UUID = Field(foreign_key="posts.id", nullable=False)
38
- user_id: uuid.UUID = Field(foreign_key="users.id", nullable=False)
 
 
 
 
 
 
 
 
 
 
39
  comment: str = Field(nullable=False)
40
  created_at: datetime = Field(default_factory=datetime.now, nullable=False)
41
 
@@ -44,6 +60,16 @@ class Likes(SQLModel, table=True):
44
  __tablename__ = "likes"
45
  __table_args__ = (UniqueConstraint("user_id", "post_id"),)
46
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
47
- post_id: uuid.UUID = Field(foreign_key="posts.id", nullable=False)
48
- user_id: uuid.UUID = Field(foreign_key="users.id", nullable=False)
 
 
 
 
 
 
 
 
 
 
49
  liked_at: datetime = Field(default_factory=datetime.now, nullable=False)
 
3
  from enum import Enum
4
  from typing import Optional
5
 
6
+ from sqlalchemy import UniqueConstraint, ForeignKey, Column
7
  from sqlmodel import Field, SQLModel
8
+ from sqlalchemy.dialects.postgresql import UUID
9
 
10
 
11
  class PostType(str, Enum):
 
23
  class Posts(SQLModel, table=True):
24
  __tablename__ = "posts"
25
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
26
+ user_id: uuid.UUID = Field(
27
+ sa_column=Column(UUID(as_uuid=True),
28
+ ForeignKey("users.id", ondelete="SET NULL"),
29
+ nullable=True
30
+ )
31
+ )
32
  type: PostType = Field(default=PostType.NOTICE)
33
  category: PostCategory = Field(default=PostCategory.GLOBAL)
34
  caption: Optional[str] = None
 
40
  class Comments(SQLModel, table=True):
41
  __tablename__ = "comments"
42
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
43
+ post_id: uuid.UUID = Field(
44
+ sa_column=Column(UUID(as_uuid=True),
45
+ ForeignKey("posts.id", ondelete="CASCADE"),
46
+ nullable=False
47
+ )
48
+ )
49
+ user_id: uuid.UUID = Field(
50
+ sa_column=Column(UUID(as_uuid=True),
51
+ ForeignKey("users.id", ondelete="CASCADE"),
52
+ nullable=False
53
+ )
54
+ )
55
  comment: str = Field(nullable=False)
56
  created_at: datetime = Field(default_factory=datetime.now, nullable=False)
57
 
 
60
  __tablename__ = "likes"
61
  __table_args__ = (UniqueConstraint("user_id", "post_id"),)
62
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
63
+ post_id: uuid.UUID = Field(
64
+ sa_column=Column(UUID(as_uuid=True),
65
+ ForeignKey("posts.id", ondelete="CASCADE"),
66
+ nullable=False
67
+ )
68
+ )
69
+ user_id: uuid.UUID = Field(
70
+ sa_column=Column(UUID(as_uuid=True),
71
+ ForeignKey("users.id", ondelete="CASCADE"),
72
+ nullable=False
73
+ )
74
+ )
75
  liked_at: datetime = Field(default_factory=datetime.now, nullable=False)
src/profile/models.py CHANGED
@@ -5,7 +5,8 @@ from datetime import date, datetime
5
  from enum import Enum
6
  from typing import List, Optional
7
 
8
- from sqlmodel import Field, Relationship, SQLModel
 
9
 
10
  class LeaveType(str, Enum):
11
  SICK = "Sick"
@@ -21,9 +22,24 @@ class LeaveStatus(str, Enum):
21
  class Leave(SQLModel, table=True):
22
  __tablename__ = "leave"
23
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
24
- user_id: uuid.UUID = Field(foreign_key="users.id", nullable=False)
25
- mentor_id: uuid.UUID = Field(foreign_key="users.id", nullable=False)
26
- lead_id: uuid.UUID = Field(foreign_key="users.id", nullable=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  leave_type: LeaveType = Field(default=LeaveType.SICK)
28
  from_date: date = Field(nullable=False)
29
  to_date: date = Field(nullable=False)
@@ -39,7 +55,12 @@ class Leave(SQLModel, table=True):
39
  class UserDevices(SQLModel, table=True):
40
  __tablename__ = "user_devices"
41
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
42
- user_id: uuid.UUID = Field(foreign_key="users.id", nullable=False)
 
 
 
 
 
43
  device_token: str
44
  last_seen: datetime = Field(default_factory=datetime.now)
45
  device_model: str
 
5
  from enum import Enum
6
  from typing import List, Optional
7
 
8
+ from sqlalchemy.dialects.postgresql import UUID
9
+ from sqlmodel import Field, Relationship, SQLModel, ForeignKey
10
 
11
  class LeaveType(str, Enum):
12
  SICK = "Sick"
 
22
  class Leave(SQLModel, table=True):
23
  __tablename__ = "leave"
24
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
25
+ user_id: uuid.UUID = Field(
26
+ sa_column=Column(UUID(as_uuid=True),
27
+ ForeignKey("users.id", ondelete="CASCADE"),
28
+ nullable=False
29
+ )
30
+ )
31
+ mentor_id: uuid.UUID = Field(
32
+ sa_column=Column(UUID(as_uuid=True),
33
+ ForeignKey("users.id", ondelete="SET NULL"),
34
+ nullable=True
35
+ )
36
+ )
37
+ lead_id: uuid.UUID = Field(
38
+ sa_column=Column(UUID(as_uuid=True),
39
+ ForeignKey("users.id", ondelete="SET NULL"),
40
+ nullable=True
41
+ )
42
+ )
43
  leave_type: LeaveType = Field(default=LeaveType.SICK)
44
  from_date: date = Field(nullable=False)
45
  to_date: date = Field(nullable=False)
 
55
  class UserDevices(SQLModel, table=True):
56
  __tablename__ = "user_devices"
57
  id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
58
+ user_id: uuid.UUID = Field(
59
+ sa_column=Column(UUID(as_uuid=True),
60
+ ForeignKey("users.id", ondelete="CASCADE"),
61
+ nullable=False
62
+ )
63
+ )
64
  device_token: str
65
  last_seen: datetime = Field(default_factory=datetime.now)
66
  device_model: str