Skip to content
All work
28E-commerce platform2026

Glossy Store

A full-stack storefront where every admin and superadmin login requires OTP — 28 Sequelize models, role-separated dashboards, and support chat with private attachment handling.

28
Sequelize models
30
Frontend pages
22
Migrations
100%
Staff logins with OTP
Role
Author
Year
2026
Status
Private
Type
E-commerce platform

01Overview

Glossy Store is a React and Vite storefront over an Express and Sequelize backend on MySQL: catalogue, categories, cart, checkout, wishlist and orders, with separate admin and superadmin dashboards behind role-based access.

Twenty-eight Sequelize models, thirteen controllers, thirty frontend pages, twenty-two migrations. The database bootstraps itself on backend startup, so a fresh clone runs without a manual migration step.

The decision that shapes the security posture is small and unusual: OTP is mandatory on every admin and superadmin login attempt, not just on unrecognised devices.

02The problem

Storefront admin accounts are the real target. A customer account buys something; an admin account edits prices, reads every order, and exports a customer list. Most e-commerce builds protect both with the same password form.

Optional two-factor solves this only for the people who opt in, which is never the account that gets compromised. Risk-based prompts help, but they fail exactly when an attacker logs in from a plausible device.

Support is the other soft edge. A support thread carries order details and often an attachment, and serving those from a public uploads directory means a guessable URL is a data leak.

03Architecture

  1. 01

    Mandatory OTP for privileged roles

    Every admin and superadmin login goes through a dedicated /otp page with resend support. Customers get a normal login; anyone who can change a price does not.

  2. 02

    Two admin tiers

    Admin and superadmin are separate roles with separate dashboards rather than one dashboard with hidden buttons. Authorisation is enforced on the route, not on the render.

  3. 03

    Commerce core

    Products, categories, cart, checkout, wishlist and orders across 28 models — enough relational structure that the migrations and associations earn their keep.

  4. 04

    Support chat with private attachments

    Attachments in support threads are access-checked rather than served statically, so a file's URL is not its authorisation.

  5. 05

    Self-bootstrapping database

    The backend provisions its own schema on startup. For a project handed between machines, a clone that runs is worth more than a clone that documents how to make it run.

04Key decisions

Decision 01

OTP always, for staff

Mandatory second factor adds friction to a login that happens a few times a day for a handful of people, and removes the single-credential compromise that would expose every customer record. The friction is real and the trade is obvious.

Decision 02

Sequelize with real migrations

Twenty-two migrations against 28 models — a schema history that can move forward on a live database, rather than a sync that is only safe on an empty one.

Decision 03

Roles as routes, not as UI

Superadmin capability is separated at the API. Hiding a button is a presentation choice; refusing the request is an access control.

05Stack

  • React
  • Vite
  • TypeScript
  • Node.js
  • Express
  • Sequelize
  • MySQL