Phase 7: End-to-End API Testing - Database setup, migrations, and application fixes
- Switched from psycopg2 to asyncpg for async SQLAlchemy support - Fixed router registration in main.py - removed duplicate prefixes - Added user_data export to routers/__init__.py - Refactored decks router to use DeckManager service layer - Integrated FuzzyCardMatcher into card_router search endpoints - Made WishlistCreate.card_id optional for proper schema validation - Set PostgreSQL password and configured scram-sha-256 auth - Updated alembic.ini to use local PostgreSQL instead of Docker hostname - Created generic_schemas.py for reusable schema patterns - Added test_routers.py and test_schema_validation.py test files - All 6 Alembic migrations applied successfully (37 tables created) - Application running on port 8000 with all services connected
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"""Pydantic schemas for user deck building features."""
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
from typing import Optional, List, Dict, Any
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
@@ -48,6 +48,8 @@ class UserDeckUpdate(BaseModel):
|
||||
|
||||
class UserDeckResponse(BaseModel):
|
||||
"""Deck response with card count."""
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: int
|
||||
user_id: int
|
||||
name: str
|
||||
@@ -62,9 +64,6 @@ class UserDeckResponse(BaseModel):
|
||||
card_count: int = 0
|
||||
is_owner: bool = False
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class UserDeckListResponse(BaseModel):
|
||||
"""List of user decks."""
|
||||
@@ -94,16 +93,14 @@ class DeckCardUpdate(BaseModel):
|
||||
|
||||
class DeckCardResponse(BaseModel):
|
||||
"""Deck card response."""
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: int
|
||||
deck_id: int
|
||||
card_id: int
|
||||
quantity: int
|
||||
zone: str
|
||||
position: Optional[int]
|
||||
created_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class DeckCardWithDetailsResponse(DeckCardResponse):
|
||||
@@ -139,6 +136,8 @@ class PrecedentUpdate(BaseModel):
|
||||
|
||||
class PrecedentResponse(BaseModel):
|
||||
"""Deck precedent response."""
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: int
|
||||
name: str
|
||||
description: Optional[str]
|
||||
@@ -149,9 +148,6 @@ class PrecedentResponse(BaseModel):
|
||||
updated_at: datetime
|
||||
card_count: int = 0
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class PrecedentListResponse(BaseModel):
|
||||
"""List of deck precedents."""
|
||||
@@ -172,6 +168,8 @@ class SuggestionCreate(BaseModel):
|
||||
|
||||
class SuggestionResponse(BaseModel):
|
||||
"""Card suggestion response."""
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: int
|
||||
deck_id: int
|
||||
card_id: int
|
||||
@@ -182,9 +180,6 @@ class SuggestionResponse(BaseModel):
|
||||
created_at: datetime
|
||||
card_name: str = ""
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class SuggestionListResponse(BaseModel):
|
||||
"""List of card suggestions."""
|
||||
@@ -220,23 +215,3 @@ class CardSearchRequest(BaseModel):
|
||||
limit: int = Field(50, ge=1, le=200)
|
||||
offset: int = Field(0, ge=0)
|
||||
|
||||
|
||||
class CardSearchResponse(BaseModel):
|
||||
"""Card search response."""
|
||||
cards: List[Dict[str, Any]]
|
||||
total: int
|
||||
page: int
|
||||
page_size: int
|
||||
total_pages: int
|
||||
|
||||
|
||||
# ===== Generic Schemas =====
|
||||
|
||||
class MessageResponse(BaseModel):
|
||||
"""Generic message response."""
|
||||
message: str
|
||||
|
||||
|
||||
class CountResponse(BaseModel):
|
||||
"""Generic count response."""
|
||||
count: int
|
||||
|
||||
Reference in New Issue
Block a user