Skip to main content
Products are the physical items you stock and sell. Each product has a name, a unique SKU for identification, a price, and a current quantity on hand. Products are the foundation of the inventory system — every inventory record and stock movement is linked to a product.
Products are automatically scoped to your tenant. You will only ever see products that belong to your account.

Product data model

The Product model in the database schema:
model Product {
  id        String   @id @default(uuid())
  name      String
  sku       String
  price     Float
  tenantId  String
  tenant    Tenant   @relation(fields: [tenantId], references: [id], onDelete: Cascade)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  inventory Inventory?
  movements StockMovement[]
}
Each product has an optional one-to-one Inventory record and can have many StockMovement records over its lifetime.

Product interface

The frontend represents a product with the following TypeScript interface, sourced from app/products/page.tsx:
interface Product {
  id: string
  name: string
  sku: string
  price: number
  quantity: number
}

Viewing products

Navigate to Products in the sidebar. The page loads your full product list in a table with columns for Product Name, SKU, Price, Quantity, and Actions. Products are fetched from the API on page load:
const response = await fetch("/api/products", {
  headers: { Authorization: `Bearer ${token}` },
})
The JWT token is read from localStorage and sent in the Authorization header on every request. The backend filters results by tenantId extracted from the token.

Adding a product

1

Open the add product form

Click the Add Product button in the top-right corner of the Products page. A form appears above the product table.
2

Fill in the product details

Complete the required fields:
  • Product Name — a descriptive name for the item
  • SKU — a unique stock-keeping unit identifier
  • Price — the unit price as a decimal number
3

Save the product

Click Save Product. The form submits a POST request to /api/products with a JSON body containing name, sku, and price. On success, the form closes and the product list refreshes.

Deleting a product

In the Actions column of the product table, click Delete next to the product you want to remove. This sends a DELETE request to /api/products/:id. The product list refreshes automatically after deletion.
Deleting a product also deletes its associated inventory record and stock movements due to the onDelete: Cascade constraint in the database schema.

API reference

MethodEndpointDescription
GET/api/productsList all products for your tenant
POST/api/productsCreate a new product
PUT/api/products/:idUpdate an existing product
DELETE/api/products/:idDelete a product
All endpoints require a valid JWT in the Authorization: Bearer <token> header.

Build docs developers (and LLMs) love