Skip to content

Commit

Permalink
Merge pull request #121 from kucc/exp
Browse files Browse the repository at this point in the history
Exp : 검색 로직 개선 및 Response 스키마 수정
  • Loading branch information
smreosms13 authored Dec 28, 2024
2 parents 059b4d2 + d715725 commit 8a1b802
Show file tree
Hide file tree
Showing 28 changed files with 425 additions and 198 deletions.
Binary file modified requirements.txt
Binary file not shown.
14 changes: 14 additions & 0 deletions sql/V4__create_settings_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
CREATE TABLE `settings` (
`id` BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
`start_date` DATETIME NOT NULL,
`end_date` DATETIME NOT NULL,
`extend_days` TINYINT unsigned NOT NULL,
`extend_max_count` TINYINT unsigned NOT NULL,
`loan_days` TINYINT unsigned NOT NULL,
`loan_max_book` TINYINT unsigned NOT NULL,
`request_max_count` TINYINT unsigned NOT NULL,
`request_max_price` INT unsigned NOT NULL,
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` BOOLEAN NOT NULL DEFAULT FALSE
);
2 changes: 2 additions & 0 deletions sql/__update_user_table_password.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE `user`
ADD password TEXT NOT NULL;
11 changes: 9 additions & 2 deletions src/domain/schemas/auth_schemas.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from pydantic import BaseModel, Field
from typing import Optional

from pydantic import BaseModel, EmailStr, Field


class UserInfo(BaseModel):
Expand All @@ -20,7 +22,8 @@ class FirebaseLoginRequest(BaseModel):


class LoginRequest(BaseModel):
auth_id: str = Field(..., example="테스트 이름")
email: EmailStr = Field(..., example="test@test.com")
password: str = Field(..., example="asdf1234")


class LoginResponse(BaseModel):
Expand All @@ -30,7 +33,11 @@ class LoginResponse(BaseModel):


class RegisterRequest(BaseModel):
email: EmailStr = Field(..., example="test@test.com")
password: str = Field(..., example="asdf1234")
user_name: str = Field(..., example="테스트 이름")
github: Optional[str] = Field(default=None)
instagram: Optional[str] = Field(default=None)
is_active: bool = Field(..., example=True)


Expand Down
29 changes: 21 additions & 8 deletions src/domain/schemas/book_review_schemas.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime as _datetime
from datetime import datetime

from pydantic import BaseModel, Field

Expand All @@ -8,26 +8,38 @@ class DomainResGetReviewByInfoId(BaseModel):
user_id: int = Field(title="user_id", description="리뷰한 사용자 ID", example=1, gt=0)
user_name: str = Field(title="user_name", description="리뷰한 사용자 이름", example="test")
review_content: str = Field(title="review_content", description="리뷰 내용")
created_at: _datetime = Field(title="create_at", description="생성일시", example=_datetime.now())
updated_at: _datetime = Field(title="update_at", description="수정일시", example=_datetime.now())
created_at: datetime = Field(title="create_at", description="생성일시", example=datetime.now())
updated_at: datetime = Field(title="update_at", description="수정일시", example=datetime.now())
book_title: str = Field(title="book_title", description="책 제목", example="FastAPI Tutorial")


class DomainResGetReviewListByInfoId(BaseModel):
data: list[DomainResGetReviewByInfoId]
total: int = Field(description="BookReview 객체의 총 요소 개수")


class Review(BaseModel):
id: int = Field(title="book_review_id", description="리뷰 정보 id", example=1, gt=0)
user_id: int = Field(title="user_id", description="리뷰한 사용자 ID", example=1, gt=0)
book_id: int = Field(title="book_id", description="리뷰한 책 정보 ID", example=1, gt=0)
review_content: str = Field(title="review_content", description="리뷰 내용")
created_at: _datetime = Field(title="create_at", description="생성일시", example=_datetime.now())
updated_at: _datetime = Field(title="update_at", description="수정일시", example=_datetime.now())
created_at: datetime = Field(title="create_at", description="생성일시", example=datetime.now())
updated_at: datetime = Field(title="update_at", description="수정일시", example=datetime.now())


class DomainResGetReviewItem(BaseModel):
review_id: int = Field(title="book_review_id", description="리뷰 id", example=1, gt=0)
user_id: int = Field(title="user_id", description="리뷰한 사용자 ID", example=1, gt=0)
book_id: int = Field(title="book_id", description="리뷰한 책 정보 ID", example=1, gt=0)
review_content: str = Field(title="review_content", description="리뷰 내용")
created_at: _datetime = Field(title="create_at", description="생성일시", example=_datetime.now())
updated_at: _datetime = Field(title="update_at", description="수정일시", example=_datetime.now())
created_at: datetime = Field(title="create_at", description="생성일시", example=datetime.now())
updated_at: datetime = Field(title="update_at", description="수정일시", example=datetime.now())
book_title: str = Field(title="book_title", description="책 제목", example="FastAPI Tutorial")


class DomainResGetReviewList(BaseModel):
data: list[DomainResGetReviewItem]
total: int = Field(description="BookReview 객체의 총 요소 개수")


class DomainReqPostReview(BaseModel):
Expand All @@ -42,7 +54,8 @@ class DomainResPostReview(BaseModel):
user_name: str = Field(title="user_name", description="리뷰한 사용자 이름")
book_id: int = Field(title="book_id", description="리뷰한 책 정보 ID", example=1, gt=0)
review_content: str = Field(title="review_content", description="리뷰 내용")
created_at: _datetime = Field(title="create_at", description="생성일시", example=_datetime.now())
created_at: datetime = Field(title="create_at", description="생성일시", example=datetime.now())


class DomainReqPutReview(BaseModel):
review_id: int = Field(title="book_review_id", description="리뷰 id", example=1, gt=0)
Expand Down
1 change: 1 addition & 0 deletions src/domain/schemas/book_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class DomainResGetBookList(BaseModel):
book_status: bool = Field(title="book_stauts", description="책 상태", example=True)
created_at: datetime = Field(title="create_at", description="생성일시", example=datetime.now())
updated_at: datetime = Field(title="update_at", description="수정일시", example=datetime.now())
loan_status: bool | None = Field(title="loan_status", description="대출 상태", example=False)

class DomainReqAdminPostBook(BaseModel):
book_title: str = Field(title="book_title", description="책 제목", example="FastAPI Tutorial")
Expand Down
6 changes: 5 additions & 1 deletion src/domain/schemas/loan_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class DomainResGetLoan(BaseModel):
overdue_days: int = Field(title="overdue_days", description="연체 일자", example=1)
return_status: bool = Field(title="return_status", description="반납 상태", example=False)
return_date: date | None = Field(title="return_date", description="반납 날짜", example=None)
book_title: str = Field(title="book_title", description="책 제목", example="FastAPI Tutorial")
code: str = Field(title="code", description="책 코드", example="A3")
version: str | None = Field(title="version", description="판본", example="10e")


class DomainReqPutLoan(BaseModel):
Expand All @@ -42,13 +45,14 @@ class DomainReqPostLoan(BaseModel):
book_id: int = Field(title="book_id", description="대출한 책 ID", example=1, gt=0)


class DomainAdminGetLoan(BaseModel):
class DomainResAdminGetLoan(BaseModel):
loan_id: int = Field(title="loan_id", description="대출 id", example=1, gt=0)
book_id: int = Field(title="book_id", description="대출한 책 ID", example=1, gt=0)
user_id: int = Field(title="user_id", description="대출한 사용자 ID", example=1, gt=0)
user_name: str = Field(title="user_name", description="리뷰한 사용자 이름", example="test")
code: str = Field(title="code", description="책 코드", example="A3")
book_title: str = Field(title="book_title", description="구매 요청한 책 제목", example="book1")
category_name: str = Field(title="category_name", description="카테고리명", example="웹")
loan_date: date = Field(title="loan_date", description="대출 날짜", example=datetime.today().date())
due_date: date = Field(title="due_date", description="반납 기한", example=(datetime.today() + timedelta(days=14)).date())
extend_status: bool = Field(title="extend_status", description="연장 상태", example=True)
Expand Down
10 changes: 5 additions & 5 deletions src/domain/schemas/user_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,36 @@ class DomainResGetUser(BaseModel):

class DomainReqPutUser(BaseModel):
user_id: int = Field(title="user_id", description="유저 고유 ID", example=1111, gt=0)
user_name: str = Field(title="user_name", description="사용자 이름", example="홍길동")
user_name: str | None = Field(title="user_name", description="사용자 이름", example="홍길동")
github: str | None = Field(None, title="github", description="깃허브 주소", example="https://github.com/kucc")
instagram: str | None = Field(None, title="instagram", description="인스타그램 주소", example="https://www.instagram.com/")

class DomainResPutUser(BaseModel):
user_id: int = Field(title="user_id", description="유저 고유 ID", example=1111, gt=0)
auth_id: str = Field(title="auth_id", description="로그인 ID", example="gildong1")
email: str = Field(title="email", description="이메일 주소", example="KUCC@korea.ac.kr")
user_name: str = Field(title="user_name", description="사용자 이름", example="홍길동")
user_name: str | None = Field(title="user_name", description="사용자 이름", example="홍길동")
is_active: bool = Field(title="is_active", description="활동 상태", example=1)
github: str | None = Field(None, title="github", description="깃허브 주소", example="https://github.com/kucc")
instagram: str | None = Field(None, title="instagram", description="인스타그램 주소", example="https://www.instagram.com/")

class DomainAdminGetUserItem(BaseModel):
user_id: int = Field(title="user_id", description="대출한 사용자 ID", example=1, gt=0)
auth_id: str = Field(title="auth_id", description="인증 ID", max_length=255)
auth_type: str = Field(default="FIREBASE", description="인증 타입", max_length=20)
email: str = Field(title="email", description="이메일", max_length=100)
user_name: str = Field(title="user_name", description="사용자 이름", max_length=45)
github_id: str | None = Field(default=None, title="github_id", description="깃허브 ID", max_length=100)
instagram_id: str | None = Field(default=None, title="instagram_id", description="인스타그램 ID", max_length=100)
is_active: bool = Field(title="is_active", description="활동 상태")
created_at: datetime = Field(title="create_at", description="생성일시")
updated_at: datetime = Field(title="update_at", description="수정일시")
is_admin: bool = Field(title="is_admin", description="관리자 권환")

class DomainReqAdminPutUser(BaseModel):
user_id: int = Field(title="user_id", description="관리자의 회원 ID", gt=0)
user_status: bool | None = Field(None, title="is_active", description="회원 상태(대출 가능 여부)", examples=[True])
user_status: bool | None = Field(None, title="is_active", description="회원 상태(대출 가능 여부",examples=[True])
admin_status: bool | None = Field(None, title="admin_status", description="관리자 권한 상태")
expiration_date : date | None = Field(None, title="expiration_date", description="관리자 권한 만료일, \
expiration_date : date | None = Field(None, title="expiration_date", description="관리자 권한 만료일,\
기본적으로 권한 부여일로부터 1년", examples=["2025-07-02"])
class DomainResAdminPutUser(BaseModel):
user_id: int = Field(title="user_id", description="유저 고유 ID", example=1111, gt=0)
Expand Down
6 changes: 5 additions & 1 deletion src/domain/services/admin/book_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ async def service_admin_search_books(
return_status: bool | None,
db: Session
) -> list[DomainAdminGetBookItem]:
stmt = (select(Book).options(selectinload(Book.loans)).where(Book.is_deleted == False,))
stmt = (
select(Book)
.options(selectinload(Book.loans))
.where(Book.is_deleted == False)
)

if book_title:
stmt = (
Expand Down
110 changes: 69 additions & 41 deletions src/domain/services/admin/loan_service.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# ruff: noqa: C901
from datetime import datetime

from fastapi import HTTPException, status
from sqlalchemy import select, text
from sqlalchemy.orm import Session, joinedload, selectinload
from sqlalchemy.orm import Session, selectinload

from domain.schemas.loan_schemas import DomainAdminGetLoan, DomainResGetLoan
from domain.schemas.loan_schemas import DomainResAdminGetLoan, DomainResGetLoan
from repositories.models import Loan
from utils.crud_utils import get_item

Expand Down Expand Up @@ -59,12 +60,15 @@ async def service_admin_search_loans(
category_name: str | None,
return_status: str | None,
db: Session
) -> list[DomainAdminGetLoan]:
) -> list[DomainResAdminGetLoan]:
stmt = (
select(Loan)
.options(joinedload(Loan.user), joinedload(Loan.book))
.join(Loan.user)
.join(Loan.book)
.join(Loan.user)
.options(
selectinload(Loan.user),
selectinload(Loan.book)
)
.where(
Loan.is_deleted == False
)
Expand All @@ -82,7 +86,7 @@ async def service_admin_search_loans(
)
if category_name:
stmt = (
stmt.where(text("MATCH(category_name) AGAINST(:category_name IN BOOLEAN MODE)"))
stmt.where(text("MATCH(book.category_name) AGAINST(:category_name IN BOOLEAN MODE)"))
.params(category_name=f"{category_name}*")
)
if return_status is not None:
Expand All @@ -94,24 +98,36 @@ async def service_admin_search_loans(
if not loans:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Loans not found")

search_loans = [
DomainAdminGetLoan(
loan_id=loan.id,
book_id=loan.book_id,
user_id=loan.user_id,
user_name=loan.user.user_name,
code=loan.book.code,
book_title=loan.book.book_title,
loan_date=loan.loan_date,
due_date=loan.due_date,
extend_status=loan.extend_status,
return_status=loan.return_status,
return_date=loan.return_date,
created_at=loan.created_at,
updated_at=loan.updated_at,
search_loans = []
for loan in loans:
if not loan.user:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"User with ID {loan.user_id} not found for loan ID {loan.id}"
)
if not loan.book:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Book with ID {loan.book_id} not found for loan ID {loan.id}"
)
search_loans.append(
DomainResAdminGetLoan(
loan_id=loan.id,
book_id=loan.book_id,
user_id=loan.user_id,
user_name=loan.user.user_name,
code=loan.book.code,
book_title=loan.book.book_title,
category_name=loan.book.category_name,
loan_date=loan.loan_date,
due_date=loan.due_date,
extend_status=loan.extend_status,
return_status=loan.return_status,
return_date=loan.return_date,
created_at=loan.created_at,
updated_at=loan.updated_at,
)
)
for loan in loans
]

except HTTPException as e:
raise e
Expand All @@ -124,7 +140,7 @@ async def service_admin_search_loans(
return search_loans


async def service_admin_read_loans(db: Session) -> list[DomainAdminGetLoan]:
async def service_admin_read_loans(db: Session) -> list[DomainResAdminGetLoan]:
stmt = (
select(Loan)
.options(
Expand All @@ -142,24 +158,36 @@ async def service_admin_read_loans(db: Session) -> list[DomainAdminGetLoan]:
if not loans:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Books not found")

search_loans = [
DomainAdminGetLoan(
loan_id=loan.id,
book_id=loan.book_id,
user_id=loan.user_id,
user_name=loan.user.user_name,
code=loan.book.code,
book_title=loan.book.book_title,
loan_date=loan.loan_date,
due_date=loan.due_date,
extend_status=loan.extend_status,
return_status=loan.return_status,
return_date=loan.return_date,
created_at=loan.created_at,
updated_at=loan.updated_at,
search_loans = []
for loan in loans:
if not loan.user:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"User with ID {loan.user_id} not found for loan ID {loan.id}"
)
if not loan.book:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Book with ID {loan.book_id} not found for loan ID {loan.id}"
)
search_loans.append(
DomainResAdminGetLoan(
loan_id=loan.id,
book_id=loan.book_id,
user_id=loan.user_id,
user_name=loan.user.user_name,
code=loan.book.code,
book_title=loan.book.book_title,
category_name=loan.book.category_name,
loan_date=loan.loan_date,
due_date=loan.due_date,
extend_status=loan.extend_status,
return_status=loan.return_status,
return_date=loan.return_date,
created_at=loan.created_at,
updated_at=loan.updated_at,
)
)
for loan in loans
]

except HTTPException as e:
raise e
Expand Down
4 changes: 2 additions & 2 deletions src/domain/services/admin/user_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ async def service_admin_search_users(
DomainAdminGetUserItem(
user_id=user.id,
auth_id=user.auth_id,
auth_type=user.auth_type,
email=user.email,
user_name=user.user_name,
github_id=user.github_id,
instagram_id=user.instagram_id,
is_active=user.is_active,
created_at=user.created_at,
updated_at=user.updated_at,
is_admin=True if user.admin and user.admin[-1].admin_status else False
)
for user in users
]
Expand Down Expand Up @@ -93,14 +93,14 @@ async def service_admin_read_users(db: Session) -> list[DomainAdminGetUserItem]:
DomainAdminGetUserItem(
user_id=user.id,
auth_id=user.auth_id,
auth_type=user.auth_type,
email=user.email,
user_name=user.user_name,
github_id=user.github_id,
instagram_id=user.instagram_id,
is_active=user.is_active,
created_at=user.created_at,
updated_at=user.updated_at,
is_admin=True if user.admin and user.admin[-1].admin_status else False
)
for user in users
]
Expand Down
Loading

0 comments on commit 8a1b802

Please sign in to comment.