Skip to content
DheesoftDheesoft home
Back to work
Case study · E-commerce platform

Enayamart

A live e-commerce platform — multi-tenant storefront, thirteen-module admin and a per-variant cost ledger.

  • Live
  • enayamart.com
  • 30+ products
Enayamart storefront hero

By the numbers

Visitors
5K+
Sales
20K+
Products
30+
Admin modules
13

01The problem

Enayamart needed a real storefront and an admin built around how the team actually runs the business — not a generic Shopify clone. Each product has multiple variants (size, colour, pack); each variant has its own cost, so margin needs to be measured per SKU, not per product. Staff record offline sales by hand. Discounts have redemption limits. The admin needs more than one role, and admin users should not be able to invite themselves. The catalogue and the interface both have to work in EN + বাংলা.

02What we built

  1. 01

    A complete customer storefront — home, shop with search and filters, product detail at slugged URLs, cart, checkout, order confirmation, and an account hub with orders, wishlist, addresses and settings.

  2. 02

    A thirteen-module admin at /admin — products, variants, categories, orders, customers, sales channels, manual (offline) sales, discounts, costs (categories + items + entries + per-variant breakdown), roles, users with invitation flow, analytics and settings.

  3. 03

    A deterministic variant matrix engine — attribute and value records generate a cartesian product of SKUs in a fixed sort order, with slug-safe naming and a jsonb attribute map per variant. Unit-tested.

  4. 04

    A per-variant cost ledger — productId + variantId + costItemId joins, so true cost of goods is calculated per SKU rather than per parent product. Categories, items and entries support a BOM-style breakdown.

  5. 05

    A five-role RBAC layer (super_admin > admin > manager > staff > customer) with permission arrays per role, an invitation flow for admin onboarding, and Better Auth for sessions (email/password + Google + Facebook).

  6. 06

    Multi-tenant from day one — every table carries a tenantId and queries scope through a single helper. The platform ships as single-tenant in production but lifts to multi-tenant with no schema change.

  7. 07

    EN + বাংলা i18n contract-tested in CI — a dedicated test fails the suite if either message catalogue drifts from the other. Bilingual content lives in the DB too, with name/name_bn fields on products.

03Stack

Storefront

  • Next.js 16
  • React 19
  • Tailwind 4
  • next-intl
  • next-themes
  • Zustand
  • framer-motion
  • shadcn/ui

Admin + auth

  • Better Auth
  • 5-role RBAC
  • next-intl
  • react-hook-form
  • zod
  • recharts
  • nodemailer
  • Invitation flow

Data + commerce

  • Drizzle ORM
  • PostgreSQL
  • 26 tables
  • Multi-tenant schema
  • Variant matrix
  • Cost breakdown
  • Discount usage
  • Manual sales

04Screenshots

05The hard part

The hardest part wasn't the storefront — it was making the variant matrix and the cost ledger talk to each other. A product can have any combination of attributes (size, colour, material…), each combination produces a deterministic SKU, and the cost engine has to attribute parts of the bill of materials to specific SKUs (not just the parent product), so margin shows up per SKU.

That meant a stable iteration order across product attributes so the SKU is the same whether you create it on day one or day two hundred, slug-safe value names, and a productId + variantId + costItemId junction table. Both attribute order and i18n completeness are guarded by unit tests so a careless change to one place doesn't silently break per-SKU costs or drift the Bengali catalogue.

Your move

Want one built around your operation?

We take on a small number of custom engagements per year. If this looks close to a problem you have, tell us about it.