Overview
Our API is designed around Business Intent rather than database tables. While the underlying schema is normalized, the API provides high-level abstractions to reduce "integration friction" for our users.
Our users are either:
- Clients (regular physical people)
- Owners (business/store/brand owner - have more privileges)
- Admins (system admins, devs, operational teams - have all privileges)
Main entities:
- Store: The physical unit with a brand identity, location, and operating schedule.
- Article: The brand-specific commercial definition of a product (Price, Currency, Brand).
- Stand: The bridge between an Article and a physical location (Edge) within a store.
- Offer: Promotional logic linked to articles or stores.
API Interaction Patterns
The Composite Pattern
To support a "one-click" onboarding experience for Owners, we provide Composite Operations.
Internal Automation: When a store registers a new Stand, the system automatically upserts the underlying Product and Article records if they do not already exist.
User Experience: Owners should not be forced to orchestrate three separate POST requests (Product -> Article -> Stand) to stock a shelf.
The Granular Pattern
To satisfy complex intents - such as de-listing an item from a shelf without deleting it from the brand catalog; we expose Lower-Level APIs.
Persistence: Articles and Products exist independently of Stands. Removing a Stand entry does not destroy the Article record, allowing it to be easily re-placed or utilized by other stores of the same brand.
Advanced Intent: Allows power users to pre-register inventory at the brand level before physical distribution.
Resource Encapsulation
We strictly enforce Domain Encapsulation to keep the API surface clean:
Brand & Program Management: Users should not interact with /brands/ or /operating/ directly. These are managed as sub-resources or nested attributes of a Store.
Example Workflows
Scenario A: Quick Onboarding (Composite)
Intent: "I want to put Alpro Almond Milk on Shelf A in Store #101."
Action: POST /stores/101/stands
Payload: Includes Product details (Vendor, Category), Price, and Location (edge_id).
Result: Backend creates/links Product, Article, and Stand in a single atomic transaction.
Scenario B: Inventory Management (Granular)
Intent: "I want to remove this milk from the shelf but keep it in my brand catalog for later."
Action: DELETE /stores/101/stands/{id}
Result: The Stand record is removed. The Article and Product remain in the system for future use.
Overview
Our API is designed around Business Intent rather than database tables. While the underlying schema is normalized, the API provides high-level abstractions to reduce "integration friction" for our users.
Our users are either:
Main entities:
API Interaction Patterns
The Composite Pattern
To support a "one-click" onboarding experience for Owners, we provide Composite Operations.
Internal Automation: When a store registers a new Stand, the system automatically upserts the underlying Product and Article records if they do not already exist.
User Experience: Owners should not be forced to orchestrate three separate POST requests (Product -> Article -> Stand) to stock a shelf.
The Granular Pattern
To satisfy complex intents - such as de-listing an item from a shelf without deleting it from the brand catalog; we expose Lower-Level APIs.
Persistence: Articles and Products exist independently of Stands. Removing a Stand entry does not destroy the Article record, allowing it to be easily re-placed or utilized by other stores of the same brand.
Advanced Intent: Allows power users to pre-register inventory at the brand level before physical distribution.
Resource Encapsulation
We strictly enforce Domain Encapsulation to keep the API surface clean:
Brand & Program Management: Users should not interact with
/brands/or/operating/directly. These are managed as sub-resources or nested attributes of a Store.Example Workflows
Scenario A: Quick Onboarding (Composite)
Intent: "I want to put Alpro Almond Milk on Shelf A in Store #101."
Action: POST /stores/101/stands
Payload: Includes Product details (Vendor, Category), Price, and Location (edge_id).
Result: Backend creates/links Product, Article, and Stand in a single atomic transaction.
Scenario B: Inventory Management (Granular)
Intent: "I want to remove this milk from the shelf but keep it in my brand catalog for later."
Action: DELETE /stores/101/stands/{id}
Result: The Stand record is removed. The Article and Product remain in the system for future use.