docs: update documentation for cart implementation
Updated API reference, error handling, and architecture docs to reflect the new persistent cart system with database storage. API Reference Updates (shop-api-reference.md): - Updated last modified date to 2025-11-23 - Updated cart response schemas to match CartResponse/CartItemResponse models - Added detailed schema tables for all cart endpoints - Documented all cart exceptions with examples (CART_ITEM_NOT_FOUND, INSUFFICIENT_INVENTORY_FOR_CART, etc.) - Added implementation notes about cart persistence and duplicate prevention - Updated all endpoint documentation with proper request/response schemas - Added CartOperationResponse and ClearCartResponse documentation Error Handling Updates (error-handling.md): - Added Shopping Cart Exceptions section with 6 cart-specific exceptions - Added Product Exceptions section - Added Inventory Exceptions section - Updated error response format to show structured WizamartException format - Added examples with error_code, message, status_code, and details fields - Documented the difference between structured and generic error formats Architecture Updates (overview.md): - Added cart_items table to database schema diagram - Documented session-based shopping cart in data model hierarchy 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -46,16 +46,64 @@ from app.exceptions import (
|
||||
|-----------|-------------|-------------|
|
||||
| `RateLimitException` | 429 | Too many requests, rate limit exceeded |
|
||||
|
||||
### Shopping Cart Exceptions
|
||||
|
||||
| Exception | Status Code | Description |
|
||||
|-----------|-------------|-------------|
|
||||
| `CartItemNotFoundException` | 404 | Cart item not found (product not in cart) |
|
||||
| `InsufficientInventoryForCartException` | 400 | Product doesn't have enough inventory for cart operation |
|
||||
| `InvalidCartQuantityException` | 422 | Cart quantity is invalid (e.g., less than min or greater than max) |
|
||||
| `CartValidationException` | 422 | Cart data validation failed |
|
||||
| `EmptyCartException` | 422 | Operation attempted on empty cart |
|
||||
| `ProductNotAvailableForCartException` | 400 | Product is not available for adding to cart |
|
||||
|
||||
### Product Exceptions
|
||||
|
||||
| Exception | Status Code | Description |
|
||||
|-----------|-------------|-------------|
|
||||
| `ProductNotFoundException` | 404 | Product not found in vendor catalog |
|
||||
| `ProductNotActiveException` | 400 | Product is inactive and cannot be purchased |
|
||||
|
||||
### Inventory Exceptions
|
||||
|
||||
| Exception | Status Code | Description |
|
||||
|-----------|-------------|-------------|
|
||||
| `InventoryNotFoundException` | 404 | Inventory record not found |
|
||||
| `InsufficientInventoryException` | 400 | Not enough inventory for operation |
|
||||
|
||||
## Error Response Format
|
||||
|
||||
All errors return a consistent JSON format:
|
||||
All custom exceptions (inheriting from `WizamartException`) return a structured JSON format:
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "Error message describing what went wrong",
|
||||
"status_code": 401,
|
||||
"timestamp": "2024-11-16T13:00:00Z",
|
||||
"path": "/api/v1/auth/login"
|
||||
"error_code": "PRODUCT_NOT_FOUND",
|
||||
"message": "Product with ID '123' not found in vendor 1 catalog",
|
||||
"status_code": 404,
|
||||
"details": {
|
||||
"resource_type": "Product",
|
||||
"identifier": "123",
|
||||
"product_id": 123,
|
||||
"vendor_id": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Standard Fields:**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `error_code` | string | Machine-readable error code (e.g., "CART_ITEM_NOT_FOUND") |
|
||||
| `message` | string | Human-readable error message |
|
||||
| `status_code` | integer | HTTP status code |
|
||||
| `details` | object | Additional context-specific error details |
|
||||
|
||||
**Note:** Generic FastAPI/HTTP errors may still use the simpler format:
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "Error message",
|
||||
"status_code": 401
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Shop API Reference
|
||||
|
||||
**Last Updated:** 2025-11-22
|
||||
**Last Updated:** 2025-11-23
|
||||
**API Version:** v1
|
||||
**Base Path:** `/api/v1/shop`
|
||||
|
||||
@@ -212,27 +212,46 @@ Referer: http://localhost:8000/vendors/wizamart/shop/cart
|
||||
"items": [
|
||||
{
|
||||
"product_id": 1,
|
||||
"product_name": "Sample Product",
|
||||
"quantity": 2,
|
||||
"price": 29.99,
|
||||
"subtotal": 59.98,
|
||||
"product": {
|
||||
"id": 1,
|
||||
"product_id": "PROD-001",
|
||||
"title": "Sample Product",
|
||||
"image_link": "https://example.com/image.jpg"
|
||||
}
|
||||
"line_total": 59.98,
|
||||
"image_url": "https://example.com/image.jpg"
|
||||
}
|
||||
],
|
||||
"subtotal": 59.98,
|
||||
"total": 59.98
|
||||
"total": 59.98,
|
||||
"item_count": 1
|
||||
}
|
||||
```
|
||||
|
||||
**Response Schema:** `CartResponse`
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `vendor_id` | integer | Vendor ID |
|
||||
| `session_id` | string | Shopping session ID |
|
||||
| `items` | array | List of cart items (see CartItemResponse below) |
|
||||
| `subtotal` | float | Subtotal of all items |
|
||||
| `total` | float | Total amount (currently same as subtotal) |
|
||||
| `item_count` | integer | Total number of unique items in cart |
|
||||
|
||||
**CartItemResponse Schema:**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `product_id` | integer | Product ID |
|
||||
| `product_name` | string | Product name |
|
||||
| `quantity` | integer | Quantity in cart |
|
||||
| `price` | float | Price per unit (captured when added to cart) |
|
||||
| `line_total` | float | Total for this line (price × quantity) |
|
||||
| `image_url` | string \| null | Product image URL |
|
||||
|
||||
---
|
||||
|
||||
### Add to Cart
|
||||
|
||||
Add a product to the cart.
|
||||
Add a product to the cart. If the product already exists in the cart, the quantity will be incremented.
|
||||
|
||||
**Endpoint:** `POST /api/v1/shop/cart/{session_id}/items`
|
||||
|
||||
@@ -242,7 +261,14 @@ Add a product to the cart.
|
||||
|-----------|------|-------------|
|
||||
| `session_id` | string | Unique session identifier |
|
||||
|
||||
**Request Body:**
|
||||
**Request Body Schema:** `AddToCartRequest`
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `product_id` | integer | Yes | Product ID to add (must be > 0) |
|
||||
| `quantity` | integer | No | Quantity to add (default: 1, must be >= 1) |
|
||||
|
||||
**Request Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -251,35 +277,97 @@ Add a product to the cart.
|
||||
}
|
||||
```
|
||||
|
||||
**Response (201 Created):**
|
||||
**Response (200 OK):** `CartOperationResponse`
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Item added to cart",
|
||||
"cart": {
|
||||
"vendor_id": 1,
|
||||
"session_id": "session-abc-123",
|
||||
"items": [...],
|
||||
"subtotal": 59.98,
|
||||
"total": 59.98
|
||||
}
|
||||
"message": "Product added to cart",
|
||||
"product_id": 1,
|
||||
"quantity": 2
|
||||
}
|
||||
```
|
||||
|
||||
**Response Schema:**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `message` | string | Operation result message |
|
||||
| `product_id` | integer | Product ID affected |
|
||||
| `quantity` | integer | New quantity in cart |
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
- `404 Not Found` - Product not found or not available
|
||||
- `404 Not Found` - Product not found or vendor not found
|
||||
```json
|
||||
{
|
||||
"error_code": "PRODUCT_NOT_FOUND",
|
||||
"message": "Product with ID '123' not found in vendor 1 catalog",
|
||||
"status_code": 404,
|
||||
"details": {
|
||||
"product_id": 123,
|
||||
"vendor_id": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `400 Bad Request` - Insufficient inventory
|
||||
```json
|
||||
{
|
||||
"error_code": "INSUFFICIENT_INVENTORY_FOR_CART",
|
||||
"message": "Insufficient inventory for product 'Sample Product'. Requested: 10, Available: 5",
|
||||
"status_code": 400,
|
||||
"details": {
|
||||
"product_id": 1,
|
||||
"product_name": "Sample Product",
|
||||
"requested_quantity": 10,
|
||||
"available_quantity": 5
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `422 Unprocessable Entity` - Validation error
|
||||
```json
|
||||
{
|
||||
"error_code": "INVALID_CART_QUANTITY",
|
||||
"message": "Quantity must be at least 1",
|
||||
"status_code": 422,
|
||||
"details": {
|
||||
"field": "quantity",
|
||||
"quantity": 0,
|
||||
"min_quantity": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Notes:**
|
||||
|
||||
- Cart items are stored in the database with persistent storage
|
||||
- Price is captured at time of adding to cart (uses `sale_price` if available, otherwise `price`)
|
||||
- If product already exists in cart, quantity is incremented (duplicate prevention)
|
||||
- Inventory is validated before adding items
|
||||
|
||||
---
|
||||
|
||||
### Update Cart Item
|
||||
|
||||
Update quantity of an item in the cart.
|
||||
Update the quantity of an existing item in the cart.
|
||||
|
||||
**Endpoint:** `PUT /api/v1/shop/cart/{session_id}/items/{product_id}`
|
||||
|
||||
**Request Body:**
|
||||
**Path Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `session_id` | string | Unique session identifier |
|
||||
| `product_id` | integer | Product ID to update (must be > 0) |
|
||||
|
||||
**Request Body Schema:** `UpdateCartItemRequest`
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `quantity` | integer | Yes | New quantity (must be >= 1) |
|
||||
|
||||
**Request Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -287,32 +375,62 @@ Update quantity of an item in the cart.
|
||||
}
|
||||
```
|
||||
|
||||
**Response (200 OK):**
|
||||
**Response (200 OK):** `CartOperationResponse`
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Cart item updated",
|
||||
"cart": {...}
|
||||
"message": "Cart updated",
|
||||
"product_id": 1,
|
||||
"quantity": 3
|
||||
}
|
||||
```
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
- `404 Not Found` - Cart item not found
|
||||
```json
|
||||
{
|
||||
"error_code": "CART_ITEM_NOT_FOUND",
|
||||
"message": "Product 123 not found in cart",
|
||||
"status_code": 404,
|
||||
"details": {
|
||||
"product_id": 123,
|
||||
"session_id": "session-abc-123"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `400 Bad Request` - Insufficient inventory for new quantity
|
||||
- `422 Unprocessable Entity` - Invalid quantity (less than 1)
|
||||
|
||||
---
|
||||
|
||||
### Remove from Cart
|
||||
|
||||
Remove an item from the cart.
|
||||
Remove a specific item from the cart.
|
||||
|
||||
**Endpoint:** `DELETE /api/v1/shop/cart/{session_id}/items/{product_id}`
|
||||
|
||||
**Response (200 OK):**
|
||||
**Path Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `session_id` | string | Unique session identifier |
|
||||
| `product_id` | integer | Product ID to remove (must be > 0) |
|
||||
|
||||
**Response (200 OK):** `CartOperationResponse`
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Item removed from cart",
|
||||
"cart": {...}
|
||||
"product_id": 1
|
||||
}
|
||||
```
|
||||
|
||||
**Error Responses:**
|
||||
|
||||
- `404 Not Found` - Cart item not found (product not in cart)
|
||||
|
||||
---
|
||||
|
||||
### Clear Cart
|
||||
@@ -321,21 +439,28 @@ Remove all items from the cart.
|
||||
|
||||
**Endpoint:** `DELETE /api/v1/shop/cart/{session_id}`
|
||||
|
||||
**Response (200 OK):**
|
||||
**Path Parameters:**
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `session_id` | string | Unique session identifier |
|
||||
|
||||
**Response (200 OK):** `ClearCartResponse`
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Cart cleared",
|
||||
"cart": {
|
||||
"vendor_id": 1,
|
||||
"session_id": "session-abc-123",
|
||||
"items": [],
|
||||
"subtotal": 0,
|
||||
"total": 0
|
||||
}
|
||||
"items_removed": 3
|
||||
}
|
||||
```
|
||||
|
||||
**Response Schema:**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `message` | string | Operation result message |
|
||||
| `items_removed` | integer | Number of items that were removed from cart |
|
||||
|
||||
---
|
||||
|
||||
## Orders
|
||||
|
||||
Reference in New Issue
Block a user