Selected work

SherryBerries E-Commerce Platform

Kaisora project

A full-stack e-commerce platform built for a Trinidad & Tobago body jewelry and piercing aftercare business, supporting product management, inventory, orders, payments and fulfillment workflows.

  • Next.js
  • TypeScript
  • PostgreSQL
  • Prisma
  • Neon
  • Resend
  • Vercel
The SherryBerries storefront homepage: the headline “Welcome home Sweet Berry” beside a photo of a model wearing the store’s jewelry, with nationwide delivery, Curepe pickup and secure payments listed below.

Overview

SherryBerries sells body jewelry, piercing aftercare and accessories in Trinidad & Tobago. The platform is the business’s complete online store: a customer-facing storefront, a checkout that handles local payment and delivery options, and an admin dashboard for running the shop day to day.

Kaisora designed and built it end to end — data model, API, storefront, admin tooling, payments, email and deployment.

The problem

A local jewelry business needs more than a product grid. Items come in several sizes — gauge, length or diameter — each with its own stock. Customers need to be able to pay by bank transfer as well as by card, and to choose between collecting an order and having it delivered.

Every one of those options creates operational work behind the scenes: transfers have to be checked by a person before an order is treated as paid, stock has to be held for orders that have not been paid yet, and the owner needs one place to see what is waiting on them.

The solution

A Next.js application backed by PostgreSQL, where the storefront and the admin dashboard share one data model and one set of API routes.

  • A product catalog with categories, tags and search.
  • Product variants with their own SKU, stock level and price adjustment, labelled by the size that applies to the product, plus a gauge sizing guide.
  • Checkout with WiPay card payments, bank transfer and cash on delivery, with each payment method offered only for the shipping methods it suits.
  • A bank-transfer workflow: the customer uploads a payment receipt, and an admin approves or rejects it with a reason.
  • Pickup, TTPost and courier delivery priced by city, plus digital products delivered by download.
  • Transactional email through Resend — account verification, password reset, order confirmation, receipt received, payment confirmed or rejected, and download ready.
  • An admin dashboard for products, inventory, orders, payment review and returns.

Architecture

  1. CustomerBrowser — storefront, account and checkout
  2. Next.js applicationApp Router pages, hosted on Vercel
  3. API route handlersCheckout, orders, payments and admin logic
  4. PrismaTyped data access and migrations
  5. PostgreSQL on NeonSeparate development and production databases

External services

Called from API route handlers

  • Auth.jsSign-in and sessions
  • WiPayCard payments
  • ResendTransactional email
  • Cloudflare R2Private receipt and file storage
  • Upstash RedisRate limiting
  • SentryError monitoring
Simplified. Every request from the storefront or the admin dashboard goes through the same API layer, which is the only part of the system that talks to the database or to third-party services.

Key engineering decisions

  • Payment and fulfilment are tracked separately

    An order carries a payment status and a fulfilment status as two independent fields, so “paid but not yet dispatched” and “dispatched on cash on delivery” are both representable. Payment status changes go through a single guarded transition function rather than being set freely.

  • Stock is reserved at checkout, not at payment

    Placing an order decrements stock immediately, and it is released again if a card payment fails or a bank-transfer window expires. Unpaid orders therefore can’t be oversold while a customer is still arranging payment.

  • Orders keep a snapshot of what was bought

    Each order item stores the price at the time of purchase and the order stores a copy of the shipping address, so later catalogue or profile edits never rewrite order history.

  • Separate development and production databases

    Development and production each have their own Neon database. A promotion script copies catalogue changes from development to production, matching records on natural keys and running as a dry run unless told otherwise.

Challenges

  • Two customers buying the last item

    Stock is decremented with a single conditional update — only if enough stock remains — inside the checkout transaction. If any line cannot be reserved, the whole order rolls back instead of leaving a partial one.

  • Replayed payment callbacks and double approvals

    The WiPay callback and the admin approval both change an order only if it is still in the state they expect, so a repeated callback or a second click is a no-op rather than a second state change. The download-ready email is guarded the same way and is sent once.

  • Card payment failures

    The WiPay payment page is requested before the order is committed, so a gateway failure leaves no order behind and no stock held.

  • Promo codes under concurrency

    Usage caps are enforced with a conditional increment, and a unique index on redemptions stops two simultaneous checkouts from both using a one-per-customer code.

  • Deleting an account without breaking order history

    Orders must keep a customer reference, so account deletion anonymises the user record instead of removing it.

Reliability & security

  • Authentication

    Email-and-password sign-in through Auth.js with bcrypt-hashed passwords, required email verification, short-lived sessions and an idle sign-out.

  • Authorization

    Customer, admin and super-admin roles. Account, checkout and admin routes require sign-in, and admin actions re-read the user’s role from the database rather than trusting the session alone.

  • Audit logging

    Admin changes to products, inventory, orders and payments are written to an audit log in the same transaction as the change itself, recording who did what, with no customer personal data and a 12-month retention period.

  • Validation and rate limiting

    Checkout re-validates everything on the server, uploaded receipts are validated before storage, and sign-in, search, contact and other sensitive endpoints are rate limited.

  • Payment integrity

    WiPay callbacks are verified with a hash check before an order is marked paid, and payment receipts are stored in a private bucket.

  • Monitoring, backups and headers

    Errors are reported to Sentry per environment, the database is dumped nightly to separate private storage with a documented restore procedure, and the site sends a strict Content Security Policy and HSTS.

Results & impact

  • The store is live at shopsherryberries.com, taking orders with the payment and delivery options that fit the business.
  • The owner runs the catalogue, stock, payment checks, orders and returns from one dashboard.
  • Every admin change is traceable, and the data model keeps order history intact as the catalogue changes.

Technologies

  • Next.js
  • React
  • TypeScript
  • PostgreSQL
  • Prisma
  • Neon
  • Auth.js
  • Resend
  • WiPay
  • Cloudflare R2
  • Upstash Redis
  • Sentry
  • Vitest
  • Vercel
Back to selected work

Start a project.

Tell us what you're trying to build, or what's slowing your business down. We'll reply with honest next steps: what it takes, what it costs to run, and whether it's worth building at all.

What helps us scope it

  1. What your business does, and who will use the system.
  2. The problem today: what's manual, slow or breaking.
  3. What already exists: tools, spreadsheets, data, systems.
  4. Your timeline, and any date that can't move.