Spaces:
Build error
Build error
| """ | |
| SQLModel database models. | |
| This module defines the database entities for the task management system. | |
| The Task model includes user ownership for strict data isolation. | |
| Phase III: Adds Conversation and Message models for AI chatbot functionality. | |
| """ | |
| from sqlmodel import SQLModel, Field, Relationship | |
| from datetime import datetime | |
| from typing import Optional, List | |
| from passlib.context import CryptContext | |
| import uuid | |
| import hashlib | |
| from sqlalchemy import Column, Text | |
| # Password hashing context - using sha256_crypt as fallback for Python 3.13 compatibility | |
| pwd_context = CryptContext(schemes=["sha256_crypt"], deprecated="auto") | |
| class TaskBase(SQLModel): | |
| """ | |
| Base class for Task with common fields. | |
| Provides shared attributes for Task, TaskCreate, and TaskUpdate models. | |
| """ | |
| title: str = Field( | |
| min_length=1, | |
| max_length=200, | |
| description="Task title (1-200 characters)" | |
| ) | |
| description: Optional[str] = Field( | |
| default=None, | |
| max_length=1000, | |
| description="Optional task description (0-1000 characters)" | |
| ) | |
| completed: bool = Field( | |
| default=False, | |
| description="Task completion status" | |
| ) | |
| class Task(TaskBase, table=True): | |
| """ | |
| Task database model. | |
| Represents a task entity stored in the tasks table. | |
| Each task is owned by exactly one user (user_id references users table). | |
| Table Name: tasks | |
| """ | |
| __tablename__ = "tasks" | |
| id: Optional[int] = Field( | |
| default=None, | |
| primary_key=True, | |
| description="Auto-incrementing primary key" | |
| ) | |
| user_id: str = Field( | |
| default="", | |
| index=True, | |
| nullable=False, | |
| description="Owner's user ID (foreign key to users.id)" | |
| ) | |
| created_at: datetime = Field( | |
| default_factory=datetime.utcnow, | |
| description="Task creation timestamp" | |
| ) | |
| updated_at: datetime = Field( | |
| default_factory=datetime.utcnow, | |
| description="Last update timestamp" | |
| ) | |
| class User(SQLModel, table=True): | |
| """ | |
| User database model. | |
| Represents a user account in the users table. | |
| Stores hashed passwords for secure authentication. | |
| Table Name: users | |
| """ | |
| __tablename__ = "users" | |
| id: str = Field( | |
| default_factory=lambda: str(uuid.uuid4()), | |
| primary_key=True, | |
| description="Unique user identifier (UUID)" | |
| ) | |
| email: str = Field( | |
| unique=True, | |
| index=True, | |
| nullable=False, | |
| description="User's email address (unique)" | |
| ) | |
| name: str = Field( | |
| default="", | |
| description="User's display name" | |
| ) | |
| hashed_password: str = Field( | |
| description="Hashed password" | |
| ) | |
| created_at: datetime = Field( | |
| default_factory=datetime.utcnow, | |
| description="Account creation timestamp" | |
| ) | |
| def set_password(self, password: str) -> None: | |
| """Hash and set the user's password.""" | |
| self.hashed_password = pwd_context.hash(password) | |
| def verify_password(self, password: str) -> bool: | |
| """Verify a password against the stored hash.""" | |
| return pwd_context.verify(password, self.hashed_password) | |
| class UserRead(SQLModel): | |
| """ | |
| User response schema (excludes password). | |
| """ | |
| id: str | |
| email: str | |
| name: str | |
| class Conversation(SQLModel, table=True): | |
| """ | |
| Conversation database model. | |
| Represents a chat session between a user and the AI assistant. | |
| Stores conversation metadata and relates to messages. | |
| Table Name: conversation | |
| """ | |
| __tablename__ = "conversation" | |
| id: Optional[int] = Field(default=None, primary_key=True) | |
| user_id: str = Field( | |
| foreign_key="users.id", | |
| index=True, | |
| nullable=False, | |
| description="Owner's user ID from Better Auth" | |
| ) | |
| created_at: datetime = Field(default_factory=datetime.utcnow) | |
| updated_at: datetime = Field(default_factory=datetime.utcnow) | |
| # Relationship to messages | |
| messages: List["Message"] = Relationship(back_populates="conversation") | |
| class Message(SQLModel, table=True): | |
| """ | |
| Message database model. | |
| Represents a single message in a conversation (either user or assistant). | |
| Messages are linked to both conversation and user for efficient querying. | |
| Table Name: message | |
| """ | |
| __tablename__ = "message" | |
| id: Optional[int] = Field(default=None, primary_key=True) | |
| conversation_id: int = Field( | |
| foreign_key="conversation.id", | |
| index=True, | |
| nullable=False, | |
| description="Parent conversation" | |
| ) | |
| user_id: str = Field( | |
| nullable=False, | |
| description="Redundant copy for fast filtering" | |
| ) | |
| role: str = Field( | |
| nullable=False, | |
| description="Message sender: 'user' or 'assistant'" | |
| ) | |
| content: str = Field( | |
| sa_column=Column(Text, nullable=False), | |
| description="Message content" | |
| ) | |
| created_at: datetime = Field(default_factory=datetime.utcnow) | |
| # Relationship to conversation | |
| conversation: Optional[Conversation] = Relationship(back_populates="messages") | |