Org Web Adapter

hungryroot/jira/be_7470_create_service_layer_for_upsert_in_cookbooks_app.org

ID
4cd39eca-3a3f-4dba-9d92-5c23aebc3db4

BE-7470 Create service layer for upsert in cookbooks app

- source :: https://hungryroot.atlassian.net/browse/BE-7470

- tags :: Hungryroot API Project

- epic :: EP-627 Exp 232: Cookbook MVP

- sprint :: HR BE Sprint 107

- status :: Status - To Do

- priority :: Priority - High

- points :: 1

Description

Following our service-first architecture, we need to implement the business

logic layer for Cookbooks. This task involves creating the CookbookService class

to handle complex upsert (create or update) operations based on the slug field.

This service must manage transactional integrity when handling nested data,

including Cookbook Authors, Dietary Tags, and Cookbook Items. Logic should be

abstracted away from the API views to ensure reusability and data consistency.

Acceptance Criteria

Service Structure: CookbookService class is created at

cookbooks/services/cookbook_service.py.

Upsert Logic: The upsert_cookbook method correctly creates a new cookbook or

updates an existing one based on the slug.

Transactional Integrity: All database operations within the upsert process are

wrapped in transaction.atomic() to ensure rollback on failure.

Related Entities:

Author: Correctly links an existing CookbookAuthor based on slug (no creation of

authors in this flow).

Tags: Correctly sets Many-to-Many dietary_tags.

Items: Correctly replaces existing items (clear old, create new) based on

provided data.

Testing: Unit tests cover:

Successful creation of a cookbook with nested data.

Successful update of an existing cookbook.

Transaction rollback verification (simulate an error during item creation to

ensure cookbook isn't partially saved).

Code Quality: Type hinting matches the provided specification; code passes

linting.

Technical Implementation Notes

File Path: cookbooks/services/cookbook_service.py

Key Considerations:

Atomic Transactions: Ensure transaction.atomic() is used at the top level of

upsert_cookbook.

Item Replacement: The current spec requires a "clear and recreate" strategy for

items (cookbook.items.clear()). Ensure this is intentional per design (vs.

updating existing items by ID).

Author Handling: The service should link an existing author, not create a new

one during this flow. If the author slug doesn't exist, the author field should

remain unchanged or handle gracefully (per code spec above).