Market¶
Overview¶
The Market app powers Jend-Z's e-commerce functionality, enabling users to create stores, list products, process orders, and manage customer reviews. The system supports location-based commerce, allowing users to discover local businesses and products within their geographic area or specific communities.
Data Models¶
Store Model¶
The central Store model represents business storefronts on the platform.
Core Fields¶
id(UUID): Unique identifiername(CharField): Store display name (max 255 characters)owner(ForeignKey): Store owner (CustomUser)slug(SlugField): Unique URL identifier (max 50 characters)description(TextField): Store description (optional)created_at(DateTimeField): Store creation timestampupdated_at(DateTimeField): Last modification timestamp
Verification & Social¶
is_verified(BooleanField): Official verification statusinstagram_url(URLField): Instagram profile link (validated format)
Location Fields¶
latitude(DecimalField): Geographic latitude coordinatelongitude(DecimalField): Geographic longitude coordinatelocation(ForeignKey): Reference to Location modelcommunity(ForeignKey): Reference to Community model (optional)
Media Fields¶
logo(ImageField): Store logo imagebanner(ImageField): Store banner/cover image
Automatic Behaviors¶
- Location Inheritance: If no coordinates provided, inherits owner's location
- Slug Validation: Ensures unique, URL-safe store identifiers
Product Model¶
Represents items available for sale in stores.
Core Fields¶
id(UUID): Unique identifierstore(ForeignKey): Associated storename(CharField): Product name (max 255 characters)description(TextField): Product description (optional)created_at(DateTimeField): Product creation timestampupdated_at(DateTimeField): Last modification timestamp
Categorization¶
category(CharField): Product category from predefined choices
Available Categories:
electronics - "Electronics & Gadgets"
apparel - "Apparel & Accessories"
home_garden - "Home & Garden"
food_beverage - "Food & Beverage"
health_beauty - "Health & Beauty"
sports_outdoors - "Sports & Outdoors"
toys_games - "Toys & Games"
arts_crafts - "Arts, Crafts & Collectibles"
books_music - "Books, Music & Media"
automotive - "Automotive"
misc - "Miscellaneous / Other"
Pricing System¶
price_type(CharField): Pricing modelfixed: Fixed pricenegotiable: Price open to negotiationvariable: Variable pricingprice(DecimalField): Product price (required for fixed pricing)
Inventory¶
stock(PositiveIntegerField): Available quantity
ProductImage Model¶
Supports multiple images per product.
Fields¶
id(UUID): Unique identifierproduct(ForeignKey): Associated productimage(ImageField): Product image file
Storage: Images stored in products/images/ directory
Order Model¶
Tracks customer purchases and order status.
Core Fields¶
id(UUID): Unique identifieruser(ForeignKey): Customer who placed orderproduct(ForeignKey): Ordered productquantity(PositiveIntegerField): Number of items orderedtotal_price(DecimalField): Total order amountcreated_at(DateTimeField): Order placement timestamp
Order Status¶
status(CharField): Current order statuspending: Order placed, awaiting processingprocessing: Order being preparedshipped: Order dispatcheddelivered: Order completed
Review Model¶
Customer feedback and ratings system.
Fields¶
id(UUID): Unique identifieruser(ForeignKey): Review authorproduct(ForeignKey): Reviewed productrating(PositiveIntegerField): Numeric ratingcomment(TextField): Review text (optional)created_at(DateTimeField): Review submission timestamp
API Endpoints¶
Store Management¶
1. List Stores¶
Endpoint: GET /api/stores/stores/
Description: Retrieve all stores with filtering and search capabilities.
Query Parameters:
location(UUID): Filter by location IDslug(string): Filter by specific store slugsearch(string): Search in store name and descriptionpage(integer): Page number for paginationpage_size(integer): Items per page (default: 50, max: 100)
Response:
{
"count": 25,
"next": "http://api.example.com/api/stores/stores/?page=2",
"previous": null,
"results": [
{
"id": "store-uuid",
"name": "Local Coffee Shop",
"slug": "local-coffee-shop",
"owner": {
"username": "coffeelover",
"display_name": "Coffee Lover"
},
"description": "Best coffee in the neighborhood, freshly roasted daily",
"instagram_url": "https://instagram.com/localcoffeeshop",
"location": {
"id": "location-uuid",
"name": "Downtown District"
},
"community": null,
"logo": "https://example.com/media/stores/logos/coffee-logo.jpg",
"banner": "https://example.com/media/stores/banners/coffee-banner.jpg",
"created_at": "2024-01-15T10:30:00Z"
}
]
}
2. Create Store¶
Endpoint: POST /api/stores/stores/
Authentication: Bearer token required
Content-Type: multipart/form-data (for image uploads)
Request Body:
{
"name": "My Awesome Store",
"slug": "my-awesome-store",
"description": "We sell amazing products for everyone",
"instagram_url": "https://instagram.com/myawesomestore",
"location": "location-uuid",
"community": "community-uuid",
"logo": "logo_image_file",
"banner": "banner_image_file"
}
Required Fields:
name: Store nameslug: Unique URL identifier
Slug Validation Rules:
- Must be unique across all stores
- Only letters, numbers, hyphens, and underscores allowed
- Maximum 50 characters
Success Response:
{
"id": "new-store-uuid",
"name": "My Awesome Store",
"slug": "my-awesome-store",
"owner": {
"username": "storeowner",
"display_name": "Store Owner"
},
"description": "We sell amazing products for everyone",
"instagram_url": "https://instagram.com/myawesomestore",
"location": {
"id": "location-uuid",
"name": "Location Name"
},
"community": null,
"logo": "https://example.com/media/stores/logos/logo.jpg",
"banner": "https://example.com/media/stores/banners/banner.jpg",
"created_at": "2024-01-15T15:45:00Z"
}
3. Get Store Details¶
Endpoint: GET /api/stores/stores/{store_id}/
Response: Same format as create store response.
4. Update Store¶
Endpoint: PUT /api/stores/stores/{store_id}/ or PATCH /api/stores/stores/{store_id}/
Authentication: Bearer token required (must be store owner)
Note: The is_verified field cannot be updated through this endpoint.
5. Delete Store¶
Endpoint: DELETE /api/stores/stores/{store_id}/
Authentication: Bearer token required (must be store owner)
6. Get My Stores¶
Endpoint: GET /api/stores/stores/my_store/
Authentication: Bearer token required
Description: Returns all stores owned by the current user.
Response:
[
{
"id": "store-uuid",
"name": "My Store",
"slug": "my-store",
"owner": {
"username": "current_user",
"display_name": "Current User"
},
"description": "My store description",
"instagram_url": null,
"location": {
"id": "location-uuid",
"name": "Location Name"
},
"community": null,
"logo": null,
"banner": null,
"created_at": "2024-01-15T10:30:00Z"
}
]
7. Sync Store Location¶
Endpoint: PATCH /api/stores/stores/{store_id}/sync_location/
Authentication: Bearer token required (must be store owner)
Description: Synchronizes store location with owner's current location.
Prerequisites: User must have a valid location set.
Success Response:
{
"id": "store-uuid",
"name": "Store Name",
"slug": "store-slug",
"owner": {
"username": "owner",
"display_name": "Owner Name"
},
"location": {
"id": "updated-location-uuid",
"name": "Updated Location"
}
}
Error Responses:
Product Management¶
1. List Products¶
Endpoint: GET /api/stores/products/
Description: Retrieve products with filtering and search capabilities.
Query Parameters:
category(string): Filter by product categoryprice(decimal): Filter by exact pricestore(UUID): Filter by store IDsearch(string): Search in product name and descriptionpage(integer): Page number for paginationpage_size(integer): Items per page (default: 20, max: 100)
Response:
{
"count": 45,
"next": "http://api.example.com/api/stores/products/?page=2",
"previous": null,
"results": [
{
"id": "product-uuid",
"store": {
"id": "store-uuid",
"name": "Local Coffee Shop",
"slug": "local-coffee-shop",
"owner": {
"username": "coffeelover",
"display_name": "Coffee Lover"
},
"description": "Best coffee in town",
"location": {
"id": "location-uuid",
"name": "Downtown District"
}
},
"name": "Premium Coffee Beans",
"description": "Freshly roasted arabica beans from Colombia",
"category": "food_beverage",
"price_type": "fixed",
"price": "25.99",
"stock": 50,
"images": [
{
"id": "image-uuid",
"image": "https://example.com/media/products/images/coffee-beans.jpg"
}
],
"created_at": "2024-01-15T12:00:00Z"
}
]
}
2. Get Products by Location¶
Endpoint: GET /api/stores/products/by-location/
Description: Discover products available in a specific geographic area using location hierarchy.
Query Parameters:
location_id(UUID, required): Target location IDsearch(string, optional): Search in product name and descriptioncategories(string, optional): Comma-separated list of categories to filter
Location Hierarchy Search: The system searches through the location hierarchy to find the best match with available products, starting from the most specific level.
Response:
{
"count": 15,
"next": "http://api.example.com/api/stores/products/by-location/?page=2",
"previous": null,
"location_name": "Downtown District",
"products": [
{
"id": "product-uuid",
"store": {
"id": "store-uuid",
"name": "Local Boutique",
"slug": "local-boutique"
},
"name": "Handmade Jewelry",
"description": "Beautiful handcrafted jewelry pieces",
"category": "arts_crafts",
"price_type": "fixed",
"price": "45.00",
"stock": 12,
"images": [
{
"id": "image-uuid",
"image": "https://example.com/media/products/images/jewelry.jpg"
}
],
"created_at": "2024-01-15T14:20:00Z"
}
]
}
Filter Examples:
GET /api/stores/products/by-location/?location_id=uuid&categories=electronics,apparel
GET /api/stores/products/by-location/?location_id=uuid&search=coffee&categories=food_beverage
No Products Response:
3. Create Product¶
Endpoint: POST /api/stores/products/
Authentication: Bearer token required
Content-Type: multipart/form-data (for image uploads)
Request Body:
{
"store_id": "store-uuid",
"name": "Amazing Product",
"description": "This product will change your life",
"category": "electronics",
"price_type": "fixed",
"price": "99.99",
"stock": 25,
"uploaded_images": ["image1.jpg", "image2.jpg"]
}
Required Fields:
store_id: UUID of the store (must be owned by current user)name: Product namecategory: Product category from available choicesstock: Available quantityprice: Required whenprice_typeis "fixed"
Price Type Rules:
- Fixed: Must provide a
pricevalue - Negotiable: Price is optional, customers can negotiate
- Variable: Price can vary based on options/customization
Success Response:
{
"id": "new-product-uuid",
"store": {
"id": "store-uuid",
"name": "My Store",
"slug": "my-store"
},
"name": "Amazing Product",
"description": "This product will change your life",
"category": "electronics",
"price_type": "fixed",
"price": "99.99",
"stock": 25,
"images": [
{
"id": "image-uuid-1",
"image": "https://example.com/media/products/images/image1.jpg"
},
{
"id": "image-uuid-2",
"image": "https://example.com/media/products/images/image2.jpg"
}
],
"created_at": "2024-01-15T16:30:00Z"
}
4. Update Product¶
Endpoint: PUT /api/stores/products/{product_id}/ or PATCH /api/stores/products/{product_id}/
Authentication: Bearer token required (must be store owner)
Request Body: Same as create product, with additional image management:
{
"name": "Updated Product Name",
"description": "Updated description",
"price": "89.99",
"stock": 30,
"uploaded_images": ["new_image.jpg"],
"images_to_delete": ["image-uuid-to-delete"]
}
Image Management:
uploaded_images: New images to addimages_to_delete: Array of image UUIDs to remove
5. Delete Product¶
Endpoint: DELETE /api/stores/products/{product_id}/
Authentication: Bearer token required (must be store owner)
Automatic Cleanup: All associated product images are automatically deleted from storage.
Order Management¶
1. List Orders¶
Endpoint: GET /api/stores/orders/
Authentication: Bearer token required
Description: Returns orders for the current user.
Response:
{
"count": 8,
"next": null,
"previous": null,
"results": [
{
"id": "order-uuid",
"user": "user-uuid",
"product": "product-uuid",
"quantity": 2,
"total_price": "49.98",
"status": "delivered",
"created_at": "2024-01-10T14:30:00Z"
}
]
}
2. Create Order¶
Endpoint: POST /api/stores/orders/
Authentication: Bearer token required
Request Body:
Automatic Calculation: Total price is automatically calculated as product.price * quantity.
Success Response:
{
"id": "new-order-uuid",
"user": "user-uuid",
"product": "product-uuid",
"quantity": 2,
"total_price": "49.98",
"status": "pending",
"created_at": "2024-01-15T16:45:00Z"
}
3. Update Order Status¶
Endpoint: PATCH /api/stores/orders/{order_id}/
Authentication: Bearer token required
Request Body:
Available Status Values:
pending: Order placed, awaiting processingprocessing: Order being preparedshipped: Order dispatcheddelivered: Order completed
Review System¶
1. List Reviews¶
Endpoint: GET /api/stores/reviews/
Authentication: Bearer token required
Response:
{
"count": 12,
"next": null,
"previous": null,
"results": [
{
"id": "review-uuid",
"user": "user-uuid",
"product": "product-uuid",
"rating": 5,
"comment": "Excellent product! Highly recommend.",
"created_at": "2024-01-12T09:15:00Z"
}
]
}
2. Create Review¶
Endpoint: POST /api/stores/reviews/
Authentication: Bearer token required
Request Body:
Required Fields:
product: UUID of the reviewed productrating: Numeric rating (positive integer)
Success Response:
{
"id": "new-review-uuid",
"user": "user-uuid",
"product": "product-uuid",
"rating": 5,
"comment": "Amazing quality and fast delivery!",
"created_at": "2024-01-15T17:00:00Z"
}
Location Integration¶
Geographic Commerce¶
The market system integrates deeply with Jend-Z's location hierarchy to enable local commerce discovery.
Store Location Behavior¶
- Automatic Location: Stores inherit owner's location if none specified
- Location Sync: Owners can update store location to match their current location
- Community Association: Stores can be associated with specific communities
Product Discovery¶
The location-based product search follows this hierarchy:
- Exact Location Match: Products in stores at the specified location
- Hierarchical Fallback: Searches broader geographic areas
- No Results: Returns empty response if no products found at any level
Location Hierarchy (most specific to least):
amenity → building → commercial → road → neighbourhood →
quarter → borough → suburb → municipality → hamlet →
village → town → city → district → county → state → country
Search Strategy¶
When searching for products by location, the system:
- Starts with the most specific location level available
- Finds all locations matching that level
- Returns products from stores in those locations
- If no products found, moves to the next broader level
- Continues until products are found or all levels exhausted
Image Management¶
Product Images¶
- Multiple Images: Each product supports multiple images
- Automatic Upload: Images processed during product creation/update
- Storage Path:
products/images/ - Format Support: JPEG, PNG, GIF, WebP
- URL Generation: Full URLs provided in API responses
Store Images¶
- Logo: Square/circular store branding image
- Banner: Rectangular cover/header image
- Storage Paths:
- Logos:
stores/logos/ - Banners:
stores/banners/
Image Deletion¶
- Automatic Cleanup: Product images deleted when product is removed
- Selective Deletion: Individual images can be removed via
images_to_deletefield - File System Cleanup: Physical files removed from storage
Pricing System¶
Price Types¶
Fixed Pricing¶
- Behavior: Set price, no negotiation
- Validation:
pricefield required - Use Case: Standard retail products
Negotiable Pricing¶
- Behavior: Listed price is starting point for negotiation
- Validation:
pricefield optional - Use Case: Used goods, custom items, bulk orders
Variable Pricing¶
- Behavior: Price depends on customization options
- Validation:
pricefield optional - Use Case: Services, custom orders, configurable products
Currency Handling¶
- Decimal Precision: 2 decimal places for currency amounts
- Storage: Stored as decimal values for precision
- Display: Format according to local currency conventions
Search & Filtering¶
Product Search Capabilities¶
Text Search¶
- Fields: Name and description
- Behavior: Case-insensitive partial matching
- Usage:
?search=coffee
Category Filtering¶
- Single Category:
?category=electronics - Multiple Categories:
?categories=electronics,apparel - Exact Match: Category must match predefined choices
Price Filtering¶
- Exact Price:
?price=25.99 - Use Case: Finding products at specific price points
Store Filtering¶
- By Store:
?store=store-uuid - Use Case: Browse products from specific store
Store Search Capabilities¶
Text Search¶
- Fields: Name and description
- Usage:
?search=coffee shop
Location Filtering¶
- By Location:
?location=location-uuid - Use Case: Find stores in specific area
Slug Filtering¶
- By Slug:
?slug=my-store - Use Case: Direct store lookup
Permissions & Security¶
Store Permissions¶
- Create: Any authenticated user
- View: Public access
- Update/Delete: Store owner only
- Verification: Admin controlled
Product Permissions¶
- Create: Store owner only
- View: Public access
- Update/Delete: Store owner only
- Store Validation: Must own the target store
Order Permissions¶
- Create: Any authenticated user
- View: Order participant only (buyer/seller)
- Update: Seller can update status
Review Permissions¶
- Create: Any authenticated user
- View: Public access
- Update/Delete: Review author only
Analytics & Insights¶
Store Analytics¶
- Product Count: Number of products per store
- Order Volume: Track orders and revenue
- Location Performance: Geographic sales patterns
Product Analytics¶
- View Tracking: Monitor product page visits
- Search Frequency: Track search queries
- Category Performance: Popular product categories
Market Insights¶
- Location Trends: Popular shopping areas
- Category Demand: Most searched categories
- Price Analysis: Price distribution by category
Error Handling¶
Common Error Responses¶
Store Slug Conflict:
Invalid Slug Format:
{
"slug": [
"Enter a valid store handle consisting of letters, numbers, underscores, or hyphens."
]
}
Permission Denied:
Price Validation Error:
Store Not Found:
Location Sync Error:
HTTP Status Codes¶
200 OK: Successful operation201 Created: Resource created successfully400 Bad Request: Validation errors401 Unauthorized: Authentication required403 Forbidden: Permission denied404 Not Found: Resource not found500 Internal Server Error: Server error