feat: backend core — models, auth, CRUD, tests

This commit is contained in:
Nox (OpenClaw)
2026-03-17 16:16:08 +00:00
parent d8c2048a9b
commit 21339d771d
35 changed files with 2161 additions and 1 deletions
View File
+32
View File
@@ -0,0 +1,32 @@
import uuid
from pydantic import BaseModel, EmailStr
class UserCreate(BaseModel):
email: EmailStr
password: str
full_name: str
class UserResponse(BaseModel):
id: uuid.UUID
email: str
full_name: str
model_config = {"from_attributes": True}
class Token(BaseModel):
access_token: str
refresh_token: str
token_type: str = "bearer"
class TokenRefresh(BaseModel):
access_token: str
token_type: str = "bearer"
class TokenRefreshRequest(BaseModel):
refresh_token: str
+31
View File
@@ -0,0 +1,31 @@
import uuid
from datetime import datetime
from pydantic import BaseModel
from app.models.category import CategoryType
class CategoryCreate(BaseModel):
name: str
type: CategoryType
color: str | None = None
icon: str | None = None
class CategoryUpdate(BaseModel):
name: str | None = None
color: str | None = None
icon: str | None = None
class CategoryResponse(BaseModel):
id: uuid.UUID
name: str
type: CategoryType
color: str | None
icon: str | None
is_default: bool
created_at: datetime
model_config = {"from_attributes": True}
+12
View File
@@ -0,0 +1,12 @@
from typing import Generic, TypeVar
from pydantic import BaseModel
T = TypeVar("T")
class PaginatedResponse(BaseModel, Generic[T]):
items: list[T]
total: int
page: int
per_page: int
+60
View File
@@ -0,0 +1,60 @@
import uuid
from datetime import date, datetime
from pydantic import BaseModel, field_validator
from app.models.transaction import TransactionType
from app.schemas.common import PaginatedResponse
class CategoryBrief(BaseModel):
id: uuid.UUID
name: str
color: str | None
model_config = {"from_attributes": True}
class TransactionCreate(BaseModel):
amount_cents: int
type: TransactionType
category_id: uuid.UUID
description: str | None = None
transaction_date: date
@field_validator("amount_cents")
@classmethod
def amount_must_be_positive(cls, v: int) -> int:
if v <= 0:
raise ValueError("amount_cents must be greater than 0")
return v
class TransactionUpdate(BaseModel):
amount_cents: int | None = None
type: TransactionType | None = None
category_id: uuid.UUID | None = None
description: str | None = None
transaction_date: date | None = None
@field_validator("amount_cents")
@classmethod
def amount_must_be_positive(cls, v: int | None) -> int | None:
if v is not None and v <= 0:
raise ValueError("amount_cents must be greater than 0")
return v
class TransactionResponse(BaseModel):
id: uuid.UUID
amount_cents: int
type: TransactionType
description: str | None
category: CategoryBrief
transaction_date: date
created_at: datetime
model_config = {"from_attributes": True}
PaginatedTransactions = PaginatedResponse[TransactionResponse]