POST /api/v1/checkout/ always converted the customer's entire multi-store cart into orders. Add an optional store_uuids field to CheckoutSerializer — when given, checkout() only processes those stores' cart groups and only clears their items, leaving the rest of the cart intact for a later checkout. Omitted, behavior is unchanged (whole cart checks out). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
3.3 KiB
3.3 KiB
Changelog
[Unreleased]
Fixed
GET /api/v1/stores/— documented thecategory,neighborhood,search,lat, andlngquery params for drf-spectacular so they render in swagger. The filtering itself already worked; only the OpenAPI schema was missing them (apps/stores/views.py).GET /api/v1/products/— same issue: documented the existingstore,category, andsearchquery params for swagger (apps/catalog/views.py).- Cart items:
CartItemViewwas registered on both/api/v1/cart/items/and/api/v1/cart/items/{item_uuid}/, so swagger showed POST/PATCH/DELETE on both paths — 3 of those 6 combinations crashed with aTypeErrorat runtime (item_uuidmissing or unexpected). Split intoCartItemView(POST only, list path) andCartItemDetailView(PATCH/DELETE only, detail path) so swagger only shows the combinations that actually work (apps/orders/views.py,apps/orders/urls.py). - Cancelling an order never restored the product stock that
checkout()decremented, so cancelled orders' items stayed permanently out of stock. Added_restock_order_items(), run on theCANCELLEDtransition (apps/orders/services.py). POST /api/v1/checkout/always checked out the customer's entire cart, even when it held items from stores the customer didn't intend to order from yet. It now checks out only the requested stores whenstore_uuidsis given (default: whole cart, unchanged), and only clears those stores' items — the rest of the cart is left intact for a later checkout (apps/orders/serializers.py,apps/orders/services.py).
Added
GET /api/v1/cities/?search=— search cities by name (apps/locations/views.py); previously no text search existed.GET /api/v1/neighborhoods/?search=— search neighborhoods by neighborhood name or city name, alongside the existingcityUUID filter (apps/locations/views.py).GET /api/v1/stores/now returnsphone_numberin the list (previously only on the single-store detail view) and adistance_kmfield, populated wheneverlat/lngare passed (apps/stores/serializers.py).- Store
latitude/longitudenow come back on every store response — list, retrieve, and the seller's own store (GET/PATCH/POST /api/v1/seller/store/) — derived fromStore.locationvia newStore.latitude/Store.longitudeproperties (apps/stores/models.py,apps/stores/serializers.py). Previously they were write-only on the seller serializer and absent everywhere else. - Test coverage for
StoreViewSetlist filtering (apps/stores/tests/test_store_list.py) — previously untested. - Test coverage for
ProductViewSetlist filtering (apps/catalog/tests/test_product_list.py) — previously untested. - Test coverage for
CityViewSet/NeighborhoodViewSetlist filtering (apps/locations/tests/test_location_list.py) — previously untested.
Changed
- Replaced hand-rolled
get_querysetfiltering withdjango-filterFilterSetclasses (apps/{stores,catalog,locations,reviews}/filters.py) andfilterset_fields(apps/ordersstatus).django-filterwas already installed and set asDEFAULT_FILTER_BACKENDSbut unused everywhere; params are now auto-documented in swagger by drf-spectacular's django-filter integration, so the manualOpenApiParameterdeclarations for those fields were removed (stores keepslat/lngmanual since geo-distance isn't a plain filter).