Internal tool

Foto Skladstock and sales for a camera shop

A shop that sells cameras on Ozon, Yandex Market and in person needs to know what is physically on the shelf, what each piece cost, and what it actually earned. Foto Sklad answers those three questions.

Role
Sole developer
Built
November 2026
Stack
Next.js 16, React 19, Supabase, Vercel
Source
Private repository
The app
43-second walkthrough of the real app, with demo data. Interface in Russian and English.
The problem

A listing is not a camera on the shelf

A shop can advertise five Sony A7 IV on Ozon and own none of them. Marketplace numbers say what is for sale, not what is in the warehouse.

Two bodies of the same model are not interchangeable either. Each was bought on a different day, at a different price, with its own serial number. Averaging them hides which sale made money.

The rule

Physical stock is the only truth

Every camera, lens and accessory is its own record with an internal ID (INV-000001, assigned by the database), serial number, purchase price and intake date. The catalog groups them for reading (Sony A7 IV, 3 in stock) and opens up to the individual units. Profit on a sale is that unit's sale price minus that unit's purchase price.

Daily work

Built for the counter, not the back office

Find anything
One search box matches every word of a query against brand, model, model code and serial number, from any screen with ⌘K.
Take stock in
Brand and model autocomplete from what the shop already has, quick chips for recent models, and several units at once, each with its own serial.
Catch mistakes
Intake is refused if a serial number already belongs to a unit that is in stock.
Sell
Search, pick the unit, choose Ozon, Yandex Market or offline, see the profit before confirming.
Look back
Every purchase, sale, return and adjustment is kept in a movements log. Monthly reports split spend, revenue and profit by channel.
Engineering

Correct when two people sell at once

  • A sale runs as one database function that locks the unit row (SELECT … FOR UPDATE), checks it is still in stock, marks it sold and writes the movement, or does nothing at all. The same camera can't be sold twice.
  • Supabase Auth and row-level security keep the data to signed-in staff. Shared stock links are revocable tokens, and the public view returns only a minimal set of fields through a dedicated function.
  • A built-in demo store with realistic camera data runs without any database, so the whole app can be tried in seconds.

The repository is private. I'm happy to walk through the code.