
E-commerce · Backend Migration
Reniom.com — Live Backend Migration
Replaced a live e-commerce site's Next.js/Prisma backend with a separate Django REST Framework service over live traffic — storefront, checkout, auth, and the entire admin panel now run on the new API, with zero visual change for shoppers. Live at reniom.vercel.app, now including an in-store AI shopping assistant.
Tech stack
The migration
Reniom originally ran on a Next.js/Prisma backend. It was fully replaced with a separate Django + Django REST Framework service on its own Railway Postgres database — storefront browsing, guest checkout, OTP login, the account page, and the entire admin panel now all go through the new API. Prisma was removed from the frontend entirely (no dependency, no schema, no client); the Next.js app on Vercel became a pure API client with no visual change for shoppers. It happened in phases over live traffic: scaffold and model recreation, storefront reads, cart and checkout, real OTP auth (replacing a temporary token stub), staff-only image upload to a Railway Volume (replacing Vercel Blob), a one-shot idempotent data migration from the old Prisma database, cutting the storefront over, staff-only CRUD, and finally guest checkout/contact/profile — at which point Prisma was dropped completely.
What made the cutover safe
A few decisions made the cutover actually work over live traffic: every model uses a UUID primary key (matching Prisma's opaque cuid() strings, so the ID shape a client sees never changed); guest checkout takes product slugs instead of database IDs, since carts saved in a visitor's browser before the cutover held old Prisma IDs that resolve to nothing under the new scheme; the PENDING order status was deliberately repurposed to mean "this is the customer's live cart" rather than "a placed order" (the old meaning), with the one-shot migration remapping old-meaning PENDING rows to CONFIRMED so order history stays correct; and admin auth was rebuilt on Django's own user system with an explicit is_staff check, so a customer's OTP session can never authenticate into an admin session.
What the store sells
Beyond the backend, Reniom itself is a direct-import retail store: authentic goods bought in Italy and Turkey and brought into an Iranian warehouse, cutting out the usual reseller middlemen. The catalogue spans four categories — cosmetics and personal care, apparel and footwear, pet supplies, and a grocery/household category — all sold at Toman prices out of local stock.
دستیار خرید رنیوم — the shopping assistant
"Reniom Shopping Assistant" is an in-store conversational assistant behind a floating widget: a shopper describes what they want in plain Persian — "a moisturizer for dry skin" is literally the assistant's own example prompt — and it recommends matching products from the real catalogue. Behind it is an LLM (Anthropic's Claude) that can run its own follow-up searches rather than answering off a single fixed guess, and is only allowed to recommend products it actually found. First-time users get a row of suggested starter prompts so the widget doesn't open to a blank input.
Commerce operations, modelled deliberately
Special (custom-import) orders move through a tracked 5-stage lifecycle — request submitted, deposit paid, purchased, arrived at warehouse, shipped; regular orders are pay-after-confirmation, with no online prepayment step yet; returns and exchanges have a 7-working-day window from delivery; and a product review can only be left by a customer who actually ordered and received that exact item — a database-enforced gate, not a storefront-only rule.

