پلتفرم

Catalogue

A catalogue shaped like the shelf, not like the database

Real stock does not arrive in tidy one-price, one-barcode units. A pharmacy buys boxes of twelve strips and sells both. A clothing shop sells the same shirt in five sizes and three colours, each with its own cost. A shop that has been trading for eleven years has a spreadsheet, not a schema. Akkad's item model is built around those facts rather than around them.

An item in Akkad is one row that knows how it is identified, how it is priced, how it is counted and how it is shown. Those four concerns are kept separate on purpose, because merchants change them at different rates — a price moves weekly, a barcode never, a photograph twice a year.

Two identifiers are enforced by the database rather than by the interface. A SKU is unique across your organisation, and so is a barcode. Item SKUs are additionally checked against variant SKUs, so a code can never mean two different things depending on which table you happen to be looking at. There is a live check endpoint behind the create form, so a clash surfaces while you are typing rather than when you press save.

What an item carries

Grouped by what each field is for. Everything here is per item — and, where noted, per variant as well.

GroupFieldsNotes
IdentityItem name, SKU, barcode, slug, brandSKU and barcode are unique per organisation and enforced in the database. Barcodes are capped at 32 characters.
PriceSale price, regular price, cost priceSale price is what you charge today; regular price is the compare-at figure a storefront strikes through. Cost price feeds margin, and margin-based discounting.
CountingManage stock, stock, low stock threshold, item unit, item weightManage stock is per item, so a service or a made-to-order dish can live in the same catalogue without ever being decremented. Item unit is free text and defaults to pcs.
PlacementCategory, subcategory, is published, is featuredA category is required; a subcategory is optional. Category filters match either level.
DescriptionShort description, description, main image, additional imagesOne main image plus up to nine more, reorderable. If no main image exists, the first additional upload is promoted automatically.
StructureItem type, attribute title, variant title, has pack sizes, batch trackingAttribute and variant titles are yours to rename — Colour and Size, or Flavour and Jar, or whatever your trade calls them.
Trade-specificDosage, active ingredient, is taxable, rating average, rating countDosage and active ingredient serve the pharmacy build. Ratings are denormalised from storefront reviews.

Every image uploaded anywhere in the catalogue goes through the same conversion: WebP, with a quality ladder that starts at 88 and walks down toward a floor of 55, and only then reduces dimensions, until the file lands under its size target. The point is that a merchant photographing stock on a phone in a shop should not have to think about any of this, and the storefront should still load quickly on a slow connection.

Three shapes an item can take

Most catalogues need all three, and mixing them freely is normal. The shape decides how stock is counted, not just how the product is displayed.

One row

Simple

One product, one price, one stock number. A bag of rice, a phone charger, a service. Pack sizes can still be layered on top of a simple item.

One axis

Variable

One product with a set of variants along a single axis — sizes, weights, capacities. Each variant carries its own price, cost, barcode and stock.

Two levels

Configurable

An attribute owns a set of values: Red owns S, M and L; Blue owns its own S, M and L. Attributes carry their own image and sort order, so the storefront can show swatches.

Variants, and what each one owns

A variant in Akkad is not a label attached to a parent price. It is a full commercial object, because that is how it behaves in practice — the extra-large costs more to buy and sells for more, and it has its own barcode printed on its own polybag.

Everything commercial is per variant

Image, SKU, barcode, stock, sale price, regular price, cost price — and its own pack sizes. A variant can be sold by the box while its sibling is not.

Parent stock is derived, never written

The stock shown on the parent item is the sum of its variants. There is no separate parent number to fall out of step, because there is no separate parent number at all.

Codes are unique across the whole organisation

A variant SKU or barcode collides with nothing else you own — not another variant, not another item. Duplicate combinations of item, attribute and value are refused outright.

Two hundred variants, fifty attributes

The ceilings are enforced identically on create, on update and on bulk import, so a spreadsheet cannot smuggle in a shape the interface would have refused.

Sizes sort the way people say them

Numeric values sort numerically. Clothing sizes follow a built-in ladder from XXS through 6XL, so Medium never lands between Large and Small. Everything else sorts alphabetically, and configurable items order by attribute first.

Sell the box and sell the single

A pharmacy buys a box of twelve strips and sells both the box and the strip. In most systems this becomes two products, and from that moment the two drift: stock is right on one and wrong on the other, a price rise lands on one and not the other, and nobody can tell you how many strips are actually in the building.

Akkad models it as one item with one stock pool, sold at more than one granularity. A pack size is a small row — name, how many base units it holds, the price of the whole pack, its own barcode, and a sort order — attached to the item or to one specific variant. Box of 12. Carton of 48. Strip.

  • One shared stock budget. Selling one box of twelve and twelve singles against a stock of twelve is refused, because it is the same twelve.
  • On an order line, quantity is always base units; the pack count and units-per-pack are recorded alongside it, so history stays readable years later.
  • Batch costs are always per base unit, and the system converts at the pack boundary — on sales and on purchase-order receipt alike.
  • Discount rules count base pieces; shipping rules count packs. A box of twelve is twelve pieces toward a volume discount and one thing to carry toward a delivery bracket, and those are genuinely different questions.
Shared stock pool144 base units
Single tablet strip1 unit1,000628…041
Box of 1212 units10,000628…058
Carton of 144144 units110,000628…065
You can sell one carton, or 144 singles, or twelve boxes — but not two of those at once. Every row spends the same 144 units.
One item, one stock pool, three sellable granularities — each with its own barcode and its own price.

Search

The scan that skips every other query

When a scanner fires, the code is almost always exact. Treating that scan as a search — running fuzzy matching, ranking, and text similarity over a catalogue of tens of thousands of rows — is how a counter starts feeling slow. Akkad probes for an exact match first, in a strict order, and on a hit every remaining query is skipped entirely.

Five probes, in order

Item barcode, then variant barcode, then pack-size barcode, then item SKU, then variant SKU. One indexed lookup. A pack-barcode hit does not just find the product — it tells the app which pack was scanned, so the box is already selected.

Typing is forgiven; scanning is not guessed at

When nothing matches exactly, a single consolidated query runs the fuzzy path, with typo rescue at word level. When a correction produced the result, the response says so, so the interface can show what it actually searched for rather than silently substituting.

Arabic-Indic and Latin digits are the same digits

٥ and 5 are folded to each other during search. In a market where the same product code is written both ways depending on who typed it, this is the difference between finding an item and re-creating it as a duplicate.

Built to stay fast as you grow

Eight composite indexes plus full-text indexes over item name, SKU and description, and over variant SKUs. Variant matching uses a correlated existence check rather than a join, so a product with sixty variants never multiplies into sixty result rows.

Working with a large catalogue

The operations that stop mattering at fifty items and start mattering at five thousand.

Filters that understand stock

Filter by category — matching either the category or the subcategory — by featured, by on-sale, by price range, and by stock status. Low stock means what a merchant means by it: stock tracking is on, a threshold is set, and the count is above zero but at or below that threshold.

Eight sort modes, all deterministic

Every sort carries a defined tiebreak, so paging through a list never shows you the same row twice or skips one because two items happened to share a price.

Duplicate, properly

Duplicating an item deep-copies its attributes, variants, pack sizes and images — real copies of the image files, not shared references, so editing one never changes the other. A free SKU is derived automatically. Barcode and slug are deliberately not copied, because those must stay unique, and featured status resets.

Resolve four hundred codes at once

The batch lookup endpoint takes up to 400 SKUs or barcodes per request and answers with four bulk queries rather than four hundred round trips. It is rate-limited to 25 calls a day per organisation, which is generous for reconciliation and hostile to scraping.

One main image, nine more

Additional images are reorderable, and the first one uploaded is promoted to main automatically when none exists — so an item is never left looking empty because of the order someone happened to upload in.

Check a SKU before you save

A dedicated validation call means the create form can tell you a code is taken while you are still in the field, instead of losing a half-typed item to a save error.

Categories that never orphan history

Categories are the axis your pricing rules, delivery rules and reports all measure against, so they are treated as structure rather than as tags.

Two levels, and real nesting

A category can carry a parent. Items hold a required category and an optional subcategory, and any category filter matches either level — so filtering by a parent still returns everything filed beneath it.

Images, through the same pipeline

Categories carry their own image, converted exactly like item images, which is what makes image-led storefront layouts possible without a separate asset workflow.

Names and slugs are policed

Slugs are validated to lowercase words joined by hyphens and are unique per organisation. Names are checked for duplicates case-insensitively, so Drinks and drinks cannot quietly coexist.

Deleting one never breaks the past

There is a system Uncategorised category that is created automatically and cannot be deleted. Deleting any other category moves its items there, clears the subcategory reference on items pointing at it, and repoints historical order lines. Last year's orders keep reporting correctly.

Questions

Does Akkad support multiple warehouses or branches?

No. Stock is a single figure per item or variant — or per batch when batch tracking is on — scoped to one organisation. There is no location model and no stock-transfer feature. If you need per-branch stock today, Akkad is not the right fit, and we would rather say so than sell you a workaround.

Are SKUs or barcodes generated for me?

No, with one exception. Codes are yours to control, because they usually already exist on the packaging or in a supplier's system. The exception is duplicating an item, where a free SKU is derived by adding a copy suffix — and the barcode is pointedly not copied at all.

Can one variant be sold by the box while another is not?

Yes. Pack sizes attach to an item or to one specific variant, and each variant carries its own pack-size flag. A 500ml bottle can have a case of twenty-four while the 2-litre has none.

What happens to old orders if I delete a category?

Nothing breaks. Items move to the system Uncategorised category, subcategory references pointing at the deleted category are cleared, and historical order lines are repointed. Reporting on last year stays accurate.

Can I re-import a file I exported from Akkad?

Yes, and this is specifically designed for. Exported pack sizes come back as continuation rows, the importer scans the file twice so their order does not matter, and continuation rows are excluded from the row limit so a legitimate round trip is not rejected as oversized.

Is item history readable by staff who do not speak my language?

Yes. Log entries are stored as structured events rather than as sentences and are translated when they are read, so each person sees the same history in their own language.

Stock and batches

Where the numbers on these items come from — expiry-first deduction, weighted-average costing and purchase orders.

Pricing rules

Categories, pieces and margins are what the discount engine measures. This is how it measures them.

Online store

How this catalogue renders for shoppers — variants, pack sizes, categories and images on the storefront.

آن را روی فهرست کالاهای خودتان ببینید

با بستهٔ مناسب شروع کنید، کالاهایتان را از یک فایل اکسل وارد کنید، و همان روز فروشگاه، صندوق و دفتر سفارشِ فعال داشته باشید.

بستهٔ رایگان موجود است. برای امتحان به کارت نیاز نیست. ورود اطلاعات، فهرست کالاهای فعلی شما را همراهتان می‌آورد.