Coverage for app/models.py: 100%
106 statements
« prev ^ index » next coverage.py v7.6.1, created at 2026-03-24 11:40 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2026-03-24 11:40 +0000
1import uuid
2from datetime import datetime
4from pydantic import EmailStr
5from sqlalchemy import JSON, Column
6from sqlmodel import Field, Relationship, SQLModel
9# Shared properties
10class UserBase(SQLModel):
11 email: EmailStr = Field(unique=True, index=True, max_length=255)
12 is_active: bool = True
13 is_superuser: bool = False
14 full_name: str | None = Field(default=None, max_length=255)
17# Properties to receive via API on creation
18class UserCreate(UserBase):
19 password: str = Field(min_length=8, max_length=40)
22class UserRegister(SQLModel):
23 email: EmailStr = Field(max_length=255)
24 password: str = Field(min_length=8, max_length=40)
25 full_name: str | None = Field(default=None, max_length=255)
28# Properties to receive via API on update, all are optional
29class UserUpdate(UserBase):
30 email: EmailStr | None = Field(default=None, max_length=255) # type: ignore
31 password: str | None = Field(default=None, min_length=8, max_length=40)
32 work_start: int | None = Field(default=None)
33 work_end: int | None = Field(default=None)
36class UserUpdateMe(SQLModel):
37 full_name: str | None = Field(default=None, max_length=255)
38 email: EmailStr | None = Field(default=None, max_length=255)
39 work_start: int | None = Field(default=None)
40 work_end: int | None = Field(default=None)
43class UpdatePassword(SQLModel):
44 current_password: str = Field(min_length=8, max_length=40)
45 new_password: str = Field(min_length=8, max_length=40)
48# Database model, database table inferred from class name
49class User(UserBase, table=True):
50 id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
51 hashed_password: str
52 work_start: int = Field(default=9)
53 work_end: int = Field(default=18)
54 items: list["Item"] = Relationship(back_populates="owner", cascade_delete=True)
55 tasks: list["Task"] = Relationship(back_populates="owner", cascade_delete=True)
58# Properties to return via API, id is always required
59class UserPublic(UserBase):
60 id: uuid.UUID
61 work_start: int = Field(default=9)
62 work_end: int = Field(default=18)
65class UsersPublic(SQLModel):
66 data: list[UserPublic]
67 count: int
70# Shared properties
71class ItemBase(SQLModel):
72 title: str = Field(min_length=1, max_length=255)
73 description: str | None = Field(default=None, max_length=255)
76# Properties to receive on item creation
77class ItemCreate(ItemBase):
78 pass
81# Properties to receive on item update
82class ItemUpdate(ItemBase):
83 title: str | None = Field(default=None, min_length=1, max_length=255) # type: ignore
86# Database model, database table inferred from class name
87class Item(ItemBase, table=True):
88 id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
89 title: str = Field(max_length=255)
90 owner_id: uuid.UUID = Field(
91 foreign_key="user.id", nullable=False, ondelete="CASCADE"
92 )
93 owner: User | None = Relationship(back_populates="items")
96# Properties to return via API, id is always required
97class ItemPublic(ItemBase):
98 id: uuid.UUID
99 owner_id: uuid.UUID
102class ItemsPublic(SQLModel):
103 data: list[ItemPublic]
104 count: int
107# Generic message
108class Message(SQLModel):
109 message: str
112# JSON payload containing access token
113class Token(SQLModel):
114 access_token: str
115 token_type: str = "bearer"
118# Contents of JWT token
119class TokenPayload(SQLModel):
120 sub: str | None = None
123class NewPassword(SQLModel):
124 token: str
125 new_password: str = Field(min_length=8, max_length=40)
128class Priority(SQLModel, table=True):
129 id: int | None = Field(default=None, primary_key=True)
130 name: str | None = Field(default=None, max_length=255)
131 value: int | None = Field(default=None)
134class TaskBase(SQLModel):
135 title: str | None = Field(default=None, max_length=255)
136 description: str | None = Field(default=None, max_length=255)
137 priority_id: int | None = Field(
138 default=None, foreign_key="priority.id", nullable=True
139 )
140 duration: int | None = Field(default=None)
141 due: datetime | None = Field(default=None)
142 scheduled_start: datetime | None = Field(default=None)
143 completed: bool = Field(default=False)
144 position: int | None = Field(default=None, index=True)
145 tags: list[str] | None = Field(default=None, sa_column=Column(JSON))
148class TaskCreate(TaskBase):
149 title: str = Field(min_length=1, max_length=255)
152class TaskUpdate(SQLModel):
153 title: str | None = Field(default=None, min_length=1, max_length=255)
154 description: str | None = Field(default=None, max_length=255)
155 priority_id: int | None = Field(default=None)
156 duration: int | None = Field(default=None)
157 due: datetime | None = Field(default=None)
158 scheduled_start: datetime | None = Field(default=None)
159 completed: bool | None = Field(default=None)
160 tags: list[str] | None = Field(default=None)
163class Task(TaskBase, table=True):
164 id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
165 owner_id: uuid.UUID = Field(
166 foreign_key="user.id", nullable=False, ondelete="CASCADE"
167 )
168 owner: User | None = Relationship(back_populates="tasks")
171class TaskPublic(TaskBase):
172 id: uuid.UUID
173 owner_id: uuid.UUID
176class TasksPublic(SQLModel):
177 data: list[TaskPublic]
178 count: int