Spaces:
Running
Running
File size: 2,707 Bytes
6b8cf38 fbebf10 6b8cf38 fbebf10 283463a fbebf10 283463a fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 6b8cf38 fbebf10 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | import uuid
from sqlalchemy import Column, String, Boolean, DateTime, func, Index
from sqlalchemy.dialects.postgresql import UUID
from auth.database import Base
# =========================================================
# USERS TABLE (CORE AUTH ENTITY)
# =========================================================
class User(Base):
__tablename__ = "users"
# -----------------------------
# Primary Key (UUID for Supabase compatibility)
# -----------------------------
id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
nullable=False,
)
# -----------------------------
# Identity Fields
# -----------------------------
email = Column(String(255), unique=True, nullable=False, index=True)
username = Column(String(100), unique=True, nullable=True, index=True)
# -----------------------------
# Security Fields
# NOTE: stores hashed password only (never plaintext)
# -----------------------------
hashed_password = Column(String(255), nullable=False)
# -----------------------------
# Account State
# -----------------------------
is_active = Column(Boolean, default=True, nullable=False)
is_verified = Column(Boolean, default=False, nullable=False)
# -----------------------------
# Audit Fields
# -----------------------------
created_at = Column(
DateTime(timezone=True),
server_default=func.now(),
nullable=False,
)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now(),
nullable=False,
)
# =========================================================
# OPTIONAL: API KEY TABLE (FOR AUTOMATION / N8N / WORKFLOWS)
# =========================================================
class ApiKey(Base):
__tablename__ = "api_keys"
id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
nullable=False,
)
user_id = Column(
UUID(as_uuid=True),
nullable=False,
index=True,
)
key_hash = Column(String(255), nullable=False, unique=True)
name = Column(String(120), nullable=True)
is_active = Column(Boolean, default=True, nullable=False)
created_at = Column(
DateTime(timezone=True),
server_default=func.now(),
nullable=False,
)
# =========================================================
# INDEXES (PERFORMANCE OPTIMIZATION)
# =========================================================
Index("idx_users_email", User.email)
Index("idx_users_username", User.username)
Index("idx_api_keys_user_id", ApiKey.user_id) |