Description
The templates/api-service-fastapi/ template has three issues that would cause problems in production use.
1. Missing Category Routes
CategoryRepository is defined in crud.py and CookbookCategory model exists, but there is no routes/categories.py. Users can't create categories via the API, yet items.py routes reference category_id. The template is unusable as-is.
Fix: Add routes/categories.py with basic CRUD endpoints (list, create, get, update, delete).
2. N+1 Query Problem — Missing Eager Loading
ItemRead schema includes category: CategoryRead, but ItemRepository.list() and .get() don't use joinedload/selectinload. This causes:
- N+1 queries (one per item to load category)
DetachedInstanceError if expire_on_commit=True and session closes before serialization
Fix: Add eager loading:
stmt = select(CookbookItem).options(selectinload(CookbookItem.category))
3. passive_deletes=True Without CUBRID FK Cascade Verification
models.py:22: CookbookCategory relationship uses passive_deletes=True with ondelete="CASCADE". CUBRID's foreign key cascade support varies by version. If CUBRID doesn't support ON DELETE CASCADE, deleting a category will fail or leave orphan items.
Fix: Either remove passive_deletes=True (let SQLAlchemy handle cascade via cascade="all, delete-orphan"), or add a migration that verifies FK cascade support and document the CUBRID version requirement.
Context
Found during line-by-line code review (2025-07-23).
Description
The
templates/api-service-fastapi/template has three issues that would cause problems in production use.1. Missing Category Routes
CategoryRepositoryis defined incrud.pyandCookbookCategorymodel exists, but there is noroutes/categories.py. Users can't create categories via the API, yetitems.pyroutes referencecategory_id. The template is unusable as-is.Fix: Add
routes/categories.pywith basic CRUD endpoints (list, create, get, update, delete).2. N+1 Query Problem — Missing Eager Loading
ItemReadschema includescategory: CategoryRead, butItemRepository.list()and.get()don't usejoinedload/selectinload. This causes:DetachedInstanceErrorifexpire_on_commit=Trueand session closes before serializationFix: Add eager loading:
3.
passive_deletes=TrueWithout CUBRID FK Cascade Verificationmodels.py:22:CookbookCategoryrelationship usespassive_deletes=Truewithondelete="CASCADE". CUBRID's foreign key cascade support varies by version. If CUBRID doesn't supportON DELETE CASCADE, deleting a category will fail or leave orphan items.Fix: Either remove
passive_deletes=True(let SQLAlchemy handle cascade viacascade="all, delete-orphan"), or add a migration that verifies FK cascade support and document the CUBRID version requirement.Context
Found during line-by-line code review (2025-07-23).