The shelf price is the order.
What did this project ship?
Reycona sells kitchen knives and prep tools in rupees. The store is one document. The order is priced from the product row, and each account can read only its own bag.
- Row price
- One tax base
- Atomic checkout
- Own orders
- Sold out
- Document head

- Industry
- Kitchen tools
- Country
- India
- Scope
- Web store
01
One document, one price, one account
Reycona is the store at reycona.in. Knives, sets, boards, shears, and sharpeners sit in one products table. The first response is a single HTML document. The bag, the wishlist, and the receipt still have to describe one account and the price on the product row.
02
Engineering challenges
The bag is the tax base. The screen can name a price the row does not. The order and the empty bag can commit apart. The receipt has an address on it, and that row has to belong to one account.
- 01A second line changes the tax
Add to bag inserts a cart_items row. A second tap on the same knife, or a second tab, inserts another row for the same account and product. The subtotal, and the tax computed from it, are wrong before checkout_cart runs, and the receipt follows them.
- 02The screen is holding an old rupee
The catalog query can stay stale after products.price changes, and the German Black hero prints ₹167 in the component for reycona-3pc-german-black-set. A checkout that stores either figure writes an order the shelf will not match.
- 03Two requests, one purchase
The order insert and the cart delete are separate requests. The insert can succeed and the delete can fail. The knives stay in the bag, the next place-order writes a second order for the same goods, and both receipts look valid.
- 04A bag with no user id
cart_items, wishlist_items, and checkout need a user id. A heart tap or a checkout tap with no session has nowhere to write. If login does not return to the product URL, the cook also loses the page they were pricing.
- 05Another account's address
Orders store the name, the phone, the address, and the price on each line. A select with no policy returns every account's receipts to whoever is signed in.
- 06Add still lit on a sold-out knife
products.in_stock is on the row. A card that still offers Add writes that knife into cart_items after the shelf has marked it sold out, and the order that follows is for stock the catalog already refused.
03
How we solved them
One cart line, so the tax base is the quantity on that row. checkout_cart prices from products.price and clears the bag in the same function. The policy is on the account tables. The card reads in_stock.
- One row per knife
cart_items is unique on the account and the product. Adding the same knife again upserts the quantity on that row. The quantity has to be greater than zero.
- The function prices the order
checkout_cart sums the product price times the quantity on the cart row. The browser total stays on the screen. Each order line stores the price from that sum, and a later catalog change leaves the stored line in place.
- One function, then an empty cart
The function inserts the order, copies the lines, and deletes that account's cart rows before it returns. A later call finds an empty cart and stops.
- Sign in, then the same page
Add to bag, the wishlist, the cart, and checkout go through the sign-in gate. A signed-out click opens login and returns to the page they left. The bag then loads from that account's cart rows.
- The policy is on the row
Products are readable by anyone. The bag, the wishlist, and orders allow only that account. Order lines are readable when the parent order belongs to them. Signup inserts a profile with the full name, username, and email.
- The card stops
The product card disables add when the row is out of stock and shows Sold out.
04
System design
One product row is the price. The store is one HTML document, so the head and the catalog query have to carry the shop until a product route renders.
- 01The document, then the row
index.html carries one title, one description, the Open Graph image, and a preload of the German Black webp. /product/:id renders after the bundle and loads the row by slug or by id. The catalog read is select *, newest first, capped, then filtered in the browser by category, price, rating, in stock, and tags. Search is ilike on name, description, and category.
- 02The cart is a quantity
The screen total is the sum of price times quantity. checkout_cart ignores that total and reads the product rows again when it writes the order.
- 03checkout_cart is the write
It requires a signed-in user and a non-blank name, phone, address, city, state, and PIN. Tax is the subtotal times the rate the checkout call sends. The storefront sends 8%. Shipping on that write is 0. Payment is cash on delivery. The order starts as pending.
- 04Who can read what
Row-level security is on profiles, products, the bag, orders, order lines, and the wishlist. A profile update is limited to that account's row. Trending reads the trending flag, highest rating first. The recommended flag sorts the shop.
- 05Search hits three columns
Search matches the name, the description, and the category, then orders by rating. A product page opens by slug or by id. Home trending asks for a shorter list than the trending page. Home featured is the highest-rated products.
- 06The account outlives the visit
The profile page can change the full name, username, and email. Orders list newest first, with the address, the tax, the shipping amount, and the price stored on each line. Status moves through pending, shipped, delivered, and cancelled.
05
What a purchase includes
The shop as a cook moves through it: the document, the search, a saved knife, the bag, cash on delivery, then the receipt.
- 01The front door
Home, shop, and trending. The hero links to the German Black 3-piece. Shop by need covers chef knives, sets, prep tools, cleavers, garden pruners, and hand tools. The home line states free delivery over ₹499, a 7-day return, and a 1-year warranty.
- 02Find a knife
Search from the header. The shop can switch between a grid and a list. The product page shows the catalog photo, a compare-at discount when that column is set, and Sold out when the row is out of stock.
- 03Save it
The heart writes one wishlist row for that account and that product. The wishlist page is private.
- 04The bag
Add, change the quantity, or remove. The cart is private. It shows the subtotal, the tax, shipping, and the total.
- 05Checkout
A mobile number, a PIN code, a state from the Indian list, and an optional note. Place order confirms cash on delivery and opens the profile on that account's orders.
- 06After the order
The profile shows the status, the address, and the price stored on each line. Shipped is shown as in transit. The same page can edit the name, username, and email.
06
What we built
We shipped the Reycona storefront: one document for the shop, a capped catalog query, the bag, the wishlist, and cash-on-delivery checkout. checkout_cart writes the order, the line prices, and the empty bag together. Each account reads only its own rows.
07
Runtime
Caps from the Reycona shop and checkout.
Products loaded, newest first
Knives on the trending page
Trending knives on the front
Highest-rated products beside them
Before a product query is stale
Before that query is dropped
Attempt after a failed product query
Digits required on the mobile field
Digits required on the PIN field
States and union territories in the list
08
What we delivered
- Reycona storefront at reycona.in
- Home page with the German Black set, shop-by-need, trending knives, and care notes
- Shop with filters, and a grid or a list
- Search by name, description, and category
- Trending page
- Product page by slug or id, with catalog photos and a sold-out state
- Sign-up and sign-in, with a profile row created on signup
- Wishlist, one row per account and product
- Cart, one line per account and product
- Cash-on-delivery checkout with an Indian address
- Orders on the profile, with status, address, and the price stored on each line
- Profile editing for name, username, and email
- Row-level security on the account tables
- checkout_cart
09
Technology
- React
- TypeScript
- Supabase
- PostgreSQL
- Vite

Live product
In production.
The store is live at reycona.in.