Hp137 commited on
Commit
618461c
·
1 Parent(s): bf5da85

fix:Bug fixed sorting and assets

Browse files
alembic/versions/81425575a724_modified_assets_and_leave_table.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """modified assets and leave table
2
+
3
+ Revision ID: 711b27b4aefb
4
+ Revises: c5bdab52a98c
5
+ Create Date: 2025-12-11 09:57:04.269110
6
+ """
7
+
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+
13
+ revision: str = "81425575a724"
14
+ down_revision: Union[str, Sequence[str], None] = "c5bdab52a98c"
15
+ branch_labels: Union[str, Sequence[str], None] = None
16
+ depends_on: Union[str, Sequence[str], None] = None
17
+
18
+
19
+ def upgrade() -> None:
20
+
21
+ # 1️⃣ Add asset_id as NULLABLE first (to avoid NOT NULL error)
22
+ op.add_column("assets", sa.Column("asset_id", sa.String(), nullable=True))
23
+
24
+ # 2️⃣ Populate asset_id for existing rows (if any)
25
+ op.execute("UPDATE assets SET asset_id = 'TEMP-' || id::text")
26
+
27
+ # 3️⃣ Make asset_id NOT NULL
28
+ op.alter_column("assets", "asset_id", nullable=False)
29
+
30
+ # 4️⃣ Add unique constraint
31
+ op.create_unique_constraint("unique_assetid_type", "assets", ["asset_id", "type"])
32
+
33
+ # 5️⃣ Drop old 'name' column safely
34
+ op.drop_column("assets", "name")
35
+
36
+ # 6️⃣ Leave the `id` column alone — DO NOT convert VARCHAR → UUID
37
+ # (This fixes the UUID casting error)
38
+
39
+ # 7️⃣ Convert leave timestamps
40
+ op.alter_column(
41
+ "leave",
42
+ "requested_at",
43
+ existing_type=sa.DATE(),
44
+ type_=sa.DateTime(),
45
+ existing_nullable=False,
46
+ )
47
+
48
+ op.alter_column(
49
+ "leave",
50
+ "updated_at",
51
+ existing_type=sa.DATE(),
52
+ type_=sa.DateTime(),
53
+ existing_nullable=False,
54
+ )
55
+
56
+
57
+ def downgrade() -> None:
58
+
59
+ # Reverse leave changes
60
+ op.alter_column(
61
+ "leave",
62
+ "updated_at",
63
+ existing_type=sa.DateTime(),
64
+ type_=sa.DATE(),
65
+ existing_nullable=False,
66
+ )
67
+
68
+ op.alter_column(
69
+ "leave",
70
+ "requested_at",
71
+ existing_type=sa.DateTime(),
72
+ type_=sa.DATE(),
73
+ existing_nullable=False,
74
+ )
75
+
76
+ # Restore name field
77
+ op.add_column("assets", sa.Column("name", sa.String(), nullable=False))
78
+
79
+ # Drop unique constraint
80
+ op.drop_constraint("unique_assetid_type", "assets", type_="unique")
81
+
82
+ # Remove asset_id
83
+ op.drop_column("assets", "asset_id")
src/core/models.py CHANGED
@@ -94,7 +94,10 @@ class UserTeamsRole(SQLModel, table=True):
94
 
95
  class Assets(SQLModel, table=True):
96
  __tablename__ = "assets"
97
- id: str = Field(primary_key=True)
 
 
 
98
  user_id: uuid.UUID = Field(
99
  sa_column=Column(
100
  UUID(as_uuid=True),
@@ -102,10 +105,11 @@ class Assets(SQLModel, table=True):
102
  nullable=False,
103
  )
104
  )
105
- name: str = Field(nullable=False)
106
  type: str = Field(nullable=False)
107
  status: AssetStatus = Field(default=AssetStatus.UNAVAILABLE)
108
  user: "Users" = Relationship(back_populates="asset")
 
109
 
110
 
111
  class EmotionLogs(SQLModel, table=True):
 
94
 
95
  class Assets(SQLModel, table=True):
96
  __tablename__ = "assets"
97
+ id: uuid.UUID = Field(
98
+ default_factory=uuid.uuid4,
99
+ primary_key=True,
100
+ )
101
  user_id: uuid.UUID = Field(
102
  sa_column=Column(
103
  UUID(as_uuid=True),
 
105
  nullable=False,
106
  )
107
  )
108
+ asset_id: str = Field(sa_column=Column("asset_id", String, nullable=False))
109
  type: str = Field(nullable=False)
110
  status: AssetStatus = Field(default=AssetStatus.UNAVAILABLE)
111
  user: "Users" = Relationship(back_populates="asset")
112
+ __table_args__ = (UniqueConstraint("asset_id", "type", name="unique_assetid_type"),)
113
 
114
 
115
  class EmotionLogs(SQLModel, table=True):
src/data_add/seed_from_excel.py CHANGED
@@ -194,16 +194,30 @@ async def seed_from_excel(session: AsyncSession, excel_path="src/data_add/users.
194
  assets_list = parse_assets_from_excel(clean(row["assets"]))
195
 
196
  for asset in assets_list:
197
- asset_id = normalize_asset_id(asset.get("id"))
198
- asset_type = asset.get("type", "Unknown")
199
 
200
- if not asset_id:
201
  continue
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  asset_obj = Assets(
204
- id=asset_id,
205
  user_id=user.id,
206
- name=asset_type,
207
  type=asset_type,
208
  status=AssetStatus.ACTIVE,
209
  )
 
194
  assets_list = parse_assets_from_excel(clean(row["assets"]))
195
 
196
  for asset in assets_list:
197
+ raw_id = clean(asset.get("id"))
198
+ raw_type = clean(asset.get("type"))
199
 
200
+ if not raw_id:
201
  continue
202
 
203
+ # Clean & normalize asset id (your YB-12 format)
204
+ asset_id = normalize_asset_id(raw_id)
205
+ asset_type = raw_type or "Unknown"
206
+
207
+ # Skip duplicates (because of unique constraint asset_id + type)
208
+ existing = await session.exec(
209
+ select(Assets).where(
210
+ Assets.asset_id == asset_id, Assets.type == asset_type
211
+ )
212
+ )
213
+ if existing.first():
214
+ print(f"⚠ Skipping duplicate asset: {asset_id} ({asset_type})")
215
+ continue
216
+
217
+ # Insert new asset
218
  asset_obj = Assets(
 
219
  user_id=user.id,
220
+ asset_id=asset_id,
221
  type=asset_type,
222
  status=AssetStatus.ACTIVE,
223
  )
src/data_add/users.xlsx CHANGED
Binary files a/src/data_add/users.xlsx and b/src/data_add/users.xlsx differ
 
src/profile/models.py CHANGED
@@ -48,8 +48,8 @@ class Leave(SQLModel, table=True):
48
  status: LeaveStatus = Field(default=LeaveStatus.PENDING)
49
  is_delivered: bool = Field(default= False)
50
  is_read: bool = Field(default=False)
51
- requested_at: date = Field(default_factory=date.today)
52
- updated_at: date = Field(default_factory=date.today)
53
  reject_reason: Optional[str] = None
54
 
55
  class UserDevices(SQLModel, table=True):
 
48
  status: LeaveStatus = Field(default=LeaveStatus.PENDING)
49
  is_delivered: bool = Field(default= False)
50
  is_read: bool = Field(default=False)
51
+ requested_at: datetime = Field(default_factory=datetime.utcnow)
52
+ updated_at: datetime = Field(default_factory=datetime.utcnow)
53
  reject_reason: Optional[str] = None
54
 
55
  class UserDevices(SQLModel, table=True):
src/profile/router.py CHANGED
@@ -645,9 +645,9 @@ async def get_profile(
645
  # Convert SQL rows → Pydantic
646
  assets_dto = [
647
  AssetResponse(
648
- id=a.id,
649
  user_id=a.user_id,
650
- name=a.name,
651
  type=a.type,
652
  status=a.status,
653
  )
 
645
  # Convert SQL rows → Pydantic
646
  assets_dto = [
647
  AssetResponse(
648
+ id=str(a.id),
649
  user_id=a.user_id,
650
+ asset_id=a.asset_id,
651
  type=a.type,
652
  status=a.status,
653
  )
src/profile/schemas.py CHANGED
@@ -95,7 +95,7 @@ class AssetUpdateRequest(BaseModel):
95
  class AssetResponse(BaseModel):
96
  id: str
97
  user_id: uuid.UUID
98
- name: str
99
  type: str
100
  status: AssetStatus
101
 
 
95
  class AssetResponse(BaseModel):
96
  id: str
97
  user_id: uuid.UUID
98
+ asset_id: str
99
  type: str
100
  status: AssetStatus
101