From 69b510a547c0ba11af6f747b07fde9f7e8085331 Mon Sep 17 00:00:00 2001 From: MandarK07 Date: Mon, 27 Jul 2026 13:12:57 +0530 Subject: [PATCH 1/2] refactor: use Generic PaginatedResponse for list endpoints --- backend/app/api/routes/items.py | 6 +++--- backend/app/api/routes/users.py | 6 +++--- backend/app/models.py | 18 ++++++++---------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/backend/app/api/routes/items.py b/backend/app/api/routes/items.py index f0eb30e4ce..dfcb0d3f24 100644 --- a/backend/app/api/routes/items.py +++ b/backend/app/api/routes/items.py @@ -5,12 +5,12 @@ from sqlmodel import col, func, select from app.api.deps import CurrentUser, SessionDep -from app.models import Item, ItemCreate, ItemPublic, ItemsPublic, ItemUpdate, Message +from app.models import Item, ItemCreate, ItemPublic, PaginatedResponse, ItemUpdate, Message router = APIRouter(prefix="/items", tags=["items"]) -@router.get("/", response_model=ItemsPublic) +@router.get("/", response_model=PaginatedResponse[ItemPublic]) def read_items( session: SessionDep, current_user: CurrentUser, skip: int = 0, limit: int = 100 ) -> Any: @@ -42,7 +42,7 @@ def read_items( items = session.exec(statement).all() items_public = [ItemPublic.model_validate(item) for item in items] - return ItemsPublic(data=items_public, count=count) + return PaginatedResponse(data=items_public, count=count) @router.get("/{id}", response_model=ItemPublic) diff --git a/backend/app/api/routes/users.py b/backend/app/api/routes/users.py index 1748f58484..d0784be0e7 100644 --- a/backend/app/api/routes/users.py +++ b/backend/app/api/routes/users.py @@ -20,7 +20,7 @@ UserCreate, UserPublic, UserRegister, - UsersPublic, + PaginatedResponse, UserUpdate, UserUpdateMe, ) @@ -32,7 +32,7 @@ @router.get( "/", dependencies=[Depends(get_current_active_superuser)], - response_model=UsersPublic, + response_model=PaginatedResponse[UserPublic], ) def read_users(session: SessionDep, skip: int = 0, limit: int = 100) -> Any: """ @@ -48,7 +48,7 @@ def read_users(session: SessionDep, skip: int = 0, limit: int = 100) -> Any: users = session.exec(statement).all() users_public = [UserPublic.model_validate(user) for user in users] - return UsersPublic(data=users_public, count=count) + return PaginatedResponse(data=users_public, count=count) @router.post( diff --git a/backend/app/models.py b/backend/app/models.py index dcedf9a2f5..a6c2030a8b 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -1,5 +1,6 @@ import uuid from datetime import UTC, datetime +from typing import Generic, TypeVar from pydantic import EmailStr from sqlalchemy import DateTime @@ -10,6 +11,13 @@ def get_datetime_utc() -> datetime: return datetime.now(UTC) +T = TypeVar("T") + +class PaginatedResponse(SQLModel, Generic[T]): + data: list[T] + count: int + + # Shared properties class UserBase(SQLModel): email: EmailStr = Field(unique=True, index=True, max_length=255) @@ -65,11 +73,6 @@ class UserPublic(UserBase): created_at: datetime | None = None -class UsersPublic(SQLModel): - data: list[UserPublic] - count: int - - # Shared properties class ItemBase(SQLModel): title: str = Field(min_length=1, max_length=255) @@ -107,11 +110,6 @@ class ItemPublic(ItemBase): created_at: datetime | None = None -class ItemsPublic(SQLModel): - data: list[ItemPublic] - count: int - - # Generic message class Message(SQLModel): message: str From 06b70eafc12a519d1cba0894685ee245ed74d036 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2026 15:27:22 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=8E=A8=20Auto=20format=20and=20update?= =?UTF-8?q?=20with=20pre-commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/routes/items.py | 9 +++- backend/app/api/routes/users.py | 2 +- backend/app/models.py | 1 + frontend/src/client/schemas.gen.ts | 72 ++++++++++++++---------------- frontend/src/client/sdk.gen.ts | 4 +- frontend/src/client/types.gen.ts | 24 +++++----- 6 files changed, 58 insertions(+), 54 deletions(-) diff --git a/backend/app/api/routes/items.py b/backend/app/api/routes/items.py index dfcb0d3f24..3169da671a 100644 --- a/backend/app/api/routes/items.py +++ b/backend/app/api/routes/items.py @@ -5,7 +5,14 @@ from sqlmodel import col, func, select from app.api.deps import CurrentUser, SessionDep -from app.models import Item, ItemCreate, ItemPublic, PaginatedResponse, ItemUpdate, Message +from app.models import ( + Item, + ItemCreate, + ItemPublic, + ItemUpdate, + Message, + PaginatedResponse, +) router = APIRouter(prefix="/items", tags=["items"]) diff --git a/backend/app/api/routes/users.py b/backend/app/api/routes/users.py index d0784be0e7..b099b67659 100644 --- a/backend/app/api/routes/users.py +++ b/backend/app/api/routes/users.py @@ -15,12 +15,12 @@ from app.models import ( Item, Message, + PaginatedResponse, UpdatePassword, User, UserCreate, UserPublic, UserRegister, - PaginatedResponse, UserUpdate, UserUpdateMe, ) diff --git a/backend/app/models.py b/backend/app/models.py index a6c2030a8b..645b551c81 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -13,6 +13,7 @@ def get_datetime_utc() -> datetime: T = TypeVar("T") + class PaginatedResponse(SQLModel, Generic[T]): data: list[T] count: int diff --git a/frontend/src/client/schemas.gen.ts b/frontend/src/client/schemas.gen.ts index ea7b4f5cff..36fc70a946 100644 --- a/frontend/src/client/schemas.gen.ts +++ b/frontend/src/client/schemas.gen.ts @@ -177,25 +177,6 @@ export const ItemUpdateSchema = { title: 'ItemUpdate' } as const; -export const ItemsPublicSchema = { - properties: { - data: { - items: { - '$ref': '#/components/schemas/ItemPublic' - }, - type: 'array', - title: 'Data' - }, - count: { - type: 'integer', - title: 'Count' - } - }, - type: 'object', - required: ['data', 'count'], - title: 'ItemsPublic' -} as const; - export const MessageSchema = { properties: { message: { @@ -226,6 +207,40 @@ export const NewPasswordSchema = { title: 'NewPassword' } as const; +export const PaginatedResponse_ItemPublic_Schema = { + properties: { + data: { + items: {}, + type: 'array', + title: 'Data' + }, + count: { + type: 'integer', + title: 'Count' + } + }, + type: 'object', + required: ['data', 'count'], + title: 'PaginatedResponse[ItemPublic]' +} as const; + +export const PaginatedResponse_UserPublic_Schema = { + properties: { + data: { + items: {}, + type: 'array', + title: 'Data' + }, + count: { + type: 'integer', + title: 'Count' + } + }, + type: 'object', + required: ['data', 'count'], + title: 'PaginatedResponse[UserPublic]' +} as const; + export const PrivateUserCreateSchema = { properties: { email: { @@ -514,25 +529,6 @@ export const UserUpdateMeSchema = { title: 'UserUpdateMe' } as const; -export const UsersPublicSchema = { - properties: { - data: { - items: { - '$ref': '#/components/schemas/UserPublic' - }, - type: 'array', - title: 'Data' - }, - count: { - type: 'integer', - title: 'Count' - } - }, - type: 'object', - required: ['data', 'count'], - title: 'UsersPublic' -} as const; - export const ValidationErrorSchema = { properties: { loc: { diff --git a/frontend/src/client/sdk.gen.ts b/frontend/src/client/sdk.gen.ts index ba79e3f726..fab86c5ef0 100644 --- a/frontend/src/client/sdk.gen.ts +++ b/frontend/src/client/sdk.gen.ts @@ -12,7 +12,7 @@ export class ItemsService { * @param data The data for the request. * @param data.skip * @param data.limit - * @returns ItemsPublic Successful Response + * @returns PaginatedResponse_ItemPublic_ Successful Response * @throws ApiError */ public static readItems(data: ItemsReadItemsData = {}): CancelablePromise { @@ -242,7 +242,7 @@ export class UsersService { * @param data The data for the request. * @param data.skip * @param data.limit - * @returns UsersPublic Successful Response + * @returns PaginatedResponse_UserPublic_ Successful Response * @throws ApiError */ public static readUsers(data: UsersReadUsersData = {}): CancelablePromise { diff --git a/frontend/src/client/types.gen.ts b/frontend/src/client/types.gen.ts index 596b8fc476..e1f8daeb62 100644 --- a/frontend/src/client/types.gen.ts +++ b/frontend/src/client/types.gen.ts @@ -26,11 +26,6 @@ export type ItemPublic = { created_at?: (string | null); }; -export type ItemsPublic = { - data: Array; - count: number; -}; - export type ItemUpdate = { title?: (string | null); description?: (string | null); @@ -45,6 +40,16 @@ export type NewPassword = { new_password: string; }; +export type PaginatedResponse_ItemPublic_ = { + data: Array; + count: number; +}; + +export type PaginatedResponse_UserPublic_ = { + data: Array; + count: number; +}; + export type PrivateUserCreate = { email: string; password: string; @@ -85,11 +90,6 @@ export type UserRegister = { full_name?: (string | null); }; -export type UsersPublic = { - data: Array; - count: number; -}; - export type UserUpdate = { email?: (string | null); is_active?: (boolean | null); @@ -118,7 +118,7 @@ export type ItemsReadItemsData = { skip?: number; }; -export type ItemsReadItemsResponse = (ItemsPublic); +export type ItemsReadItemsResponse = (PaginatedResponse_ItemPublic_); export type ItemsCreateItemData = { requestBody: ItemCreate; @@ -182,7 +182,7 @@ export type UsersReadUsersData = { skip?: number; }; -export type UsersReadUsersResponse = (UsersPublic); +export type UsersReadUsersResponse = (PaginatedResponse_UserPublic_); export type UsersCreateUserData = { requestBody: UserCreate;