One e-commerce backend running two clothing stores — Ojuk Bujuk and Alfinur — directly on top of each client's ERP database in MSSQL, with Nuxt admin panels.
My role
Full-stack developer: backend, admin panels and deployment.
Stack
AdonisJS
TypeScript
MSSQL
Socket.IO
Nuxt
PM2
The problem
The stores' products, prices and discounts already lived in the client's ERP. A separate catalog would have meant entering data twice and showing stale prices.
Architecture
The API (AdonisJS 5, Lucid ORM) reads catalog data from the ERP's existing tables and owns only its own tables for users, orders, favorites and verification codes. A Socket.IO channel connects an Android phone that sends one-time codes and order alerts by SMS. Nuxt admin panels manage what the storefront shows. The same codebase is deployed for both stores.
Key decisions
01ERP tables as the catalog
Why
Reading products and prices directly from the ERP removes synchronization entirely — the store always shows what accounting has. The app only adds the tables it owns.
Trade-off
The API is coupled to the ERP schema, and catalog queries run against the accounting database.
02A phone as the SMS gateway
Why
Instead of an external SMS provider, an Android phone connected over Socket.IO sends codes and order alerts through the local mobile network.
Trade-off
Delivery depends on the phone staying online and connected.
03One codebase, several stores
Why
Both stores share the backend and the admin template; differences such as product attributes or nested categories are features of the same platform.
What I built
AdonisJS (TypeScript) API reading products, prices and discounts straight from ERP tables in MSSQL
Phone sign-up with one-time codes; SMS sent by a phone gateway connected over Socket.IO
JWT access and refresh tokens with separate guards for customers and admins
Orders created inside database transactions, including anonymous orders
Nuxt 2 + Vuetify admin panels; CI/CD with GitHub Actions, SSH deploy and PM2