basyx commited on
Commit
6b8cf38
·
verified ·
1 Parent(s): 51d74bd

Update auth/models.py

Browse files
Files changed (1) hide show
  1. auth/models.py +149 -7
auth/models.py CHANGED
@@ -1,13 +1,155 @@
1
- from sqlalchemy import Column, Integer, String, DateTime
 
 
 
 
 
2
  from datetime import datetime
3
- from .database import Base
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
 
 
 
5
 
6
  class User(Base):
 
 
 
 
7
  __tablename__ = "users"
8
 
9
- id = Column(Integer, primary_key=True, index=True)
10
- email = Column(String, unique=True, index=True)
11
- username = Column(String)
12
- password_hash = Column(String)
13
- createdAt = Column(DateTime, default=datetime.utcnow)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ models.py
3
+ Enterprise ORM Models
4
+ Basyx Whisper V10.1
5
+ """
6
+
7
  from datetime import datetime
8
+ import uuid
9
+
10
+ from sqlalchemy import (
11
+ Column,
12
+ String,
13
+ DateTime,
14
+ Boolean,
15
+ Index,
16
+ func,
17
+ )
18
+ from sqlalchemy.dialects.postgresql import UUID
19
+ from sqlalchemy.orm import validates
20
+
21
+ from database import Base
22
+
23
 
24
+ # ==========================================================
25
+ # USER MODEL
26
+ # ==========================================================
27
 
28
  class User(Base):
29
+ """
30
+ Enterprise-grade User table
31
+ """
32
+
33
  __tablename__ = "users"
34
 
35
+ # ------------------------------------------------------
36
+ # Primary Identifier
37
+ # ------------------------------------------------------
38
+
39
+ id = Column(
40
+ UUID(as_uuid=True),
41
+ primary_key=True,
42
+ default=uuid.uuid4,
43
+ unique=True,
44
+ nullable=False,
45
+ )
46
+
47
+ # ------------------------------------------------------
48
+ # Identity Fields
49
+ # ------------------------------------------------------
50
+
51
+ email = Column(
52
+ String(255),
53
+ unique=True,
54
+ nullable=False,
55
+ index=True,
56
+ )
57
+
58
+ username = Column(
59
+ String(50),
60
+ unique=True,
61
+ nullable=False,
62
+ index=True,
63
+ )
64
+
65
+ password_hash = Column(
66
+ String(255),
67
+ nullable=False,
68
+ )
69
+
70
+ # ------------------------------------------------------
71
+ # Account State
72
+ # ------------------------------------------------------
73
+
74
+ is_active = Column(
75
+ Boolean,
76
+ default=True,
77
+ nullable=False,
78
+ )
79
+
80
+ is_verified = Column(
81
+ Boolean,
82
+ default=False,
83
+ nullable=False,
84
+ )
85
+
86
+ # ------------------------------------------------------
87
+ # Audit Fields
88
+ # ------------------------------------------------------
89
+
90
+ created_at = Column(
91
+ DateTime(timezone=True),
92
+ server_default=func.now(),
93
+ nullable=False,
94
+ )
95
+
96
+ updated_at = Column(
97
+ DateTime(timezone=True),
98
+ server_default=func.now(),
99
+ onupdate=func.now(),
100
+ nullable=False,
101
+ )
102
+
103
+ # ------------------------------------------------------
104
+ # VALIDATION LAYER
105
+ # ------------------------------------------------------
106
+
107
+ @validates("email")
108
+ def validate_email(self, key, value):
109
+ value = value.strip().lower()
110
+
111
+ if "@" not in value:
112
+ raise ValueError("Invalid email address")
113
+
114
+ if len(value) > 255:
115
+ raise ValueError("Email too long")
116
+
117
+ return value
118
+
119
+ @validates("username")
120
+ def validate_username(self, key, value):
121
+ value = value.strip()
122
+
123
+ if len(value) < 3:
124
+ raise ValueError("Username must be at least 3 characters")
125
+
126
+ if len(value) > 50:
127
+ raise ValueError("Username too long")
128
+
129
+ return value
130
+
131
+ # ------------------------------------------------------
132
+ # SERIALIZATION SAFE OUTPUT
133
+ # ------------------------------------------------------
134
+
135
+ def to_dict(self):
136
+ """
137
+ Safe public serialization
138
+ NEVER expose password_hash
139
+ """
140
+
141
+ return {
142
+ "id": str(self.id),
143
+ "email": self.email,
144
+ "username": self.username,
145
+ "createdAt": self.created_at.isoformat(),
146
+ }
147
+
148
+
149
+ # ==========================================================
150
+ # ENTERPRISE INDEX STRATEGY
151
+ # ==========================================================
152
+
153
+ Index("idx_users_email_unique", User.email, unique=True)
154
+ Index("idx_users_username_unique", User.username, unique=True)
155
+ Index("idx_users_created_at", User.created_at)