Case study 03 / 26
Kinamna
A multi-vendor marketplace for Nepal: storefront, seller portal and superadmin console on one 183-endpoint API, with tamper-proof Khalti, eSewa and Fonepay payments.
- Status
- Deployed
- Domain
- web · cloud · security
- Source of claims
- Private repository README (reviewed). Source and deployment are not public.
Customers shop, sellers run their own catalogue, stock and orders, and platform staff oversee every business — three portals on one FastAPI backend whose boundaries are enforced in the API, not the browser. The backend was migrated from Express + Prisma to FastAPI + SQLAlchemy without changing the schema, URLs, JSON shapes or issued tokens.
01/The problem
A marketplace handles other people's money and other businesses' data. A seller must never see a competitor's orders, a customer must never be able to set their own price, and a payment callback replayed or tampered with must never confirm an order twice — or at all.
02/The system
Customers shop, sellers run their own catalogue, stock and orders, and platform staff oversee every business — three portals on one FastAPI backend whose boundaries are enforced in the API, not the browser. The backend was migrated from Express + Prisma to FastAPI + SQLAlchemy without changing the schema, URLs, JSON shapes or issued tokens.
03/Scope
- 01Three portals — storefront, business portal and superadmin console — on one API of 183 endpoints with generated OpenAPI docs.
- 02Roles for customers, store managers, support and admins; business and superadmin guards re-read the account on every request, so suspension takes effect immediately.
- 03Khalti, eSewa, Fonepay, card and cash-on-delivery payments, plus superadmin refunds recorded only after the gateway confirms them.
- 04Business approval lifecycle (pending → approved → suspended…) and an audit log of status changes and refunds.
- 05Catalogue with variants and options, carts, wishlists, waitlists, reviews with seller replies, sales and promotions; direct-to-R2 uploads via presigned URLs.
- 06Running on Kubernetes with Neon Postgres behind an nginx ingress; non-root containers, health probes and graceful drain.
04/Engineering
The browser never sets the price
Amounts are recomputed from stored line items and cross-checked against the order total; the browser's payment status is ignored and a server-side gateway lookup is the only source of truth. A short payment is never accepted as success.
Settle exactly once
Settlement is a single conditional update behind a state machine that rejects backwards transitions, so duplicate and replayed callbacks are no-ops — no double stock decrement, no second confirmation email.
Isolation resolved from the database
Every business query filters on a store id the guard resolved from the authenticated user — never one from the URL or body — and another store's product answers 404, so ids can't be probed.
A backend swap nobody noticed
The Express + Prisma API was replaced with FastAPI + SQLAlchemy against the same schema, URLs, JSON and JWTs; Alembic autogenerate against the live schema produces an empty migration.
05/Interface
Interface screenshots of this commercial product are not public. The visual above is an abstract representation of its modules — not the product itself.
06/Tech stack
- FastAPI
- Python 3.13
- SQLAlchemy
- Alembic
- Next.js 14
- React 18
- TanStack Query
- PostgreSQL (Neon)
- Redis
- Kubernetes
- Cloudflare R2
07/Result
Verified outcomes
- Running in production on Kubernetes with Neon PostgreSQL.
- 126 tests against a real PostgreSQL schema covering payments, replays, refunds, RBAC, business isolation and customer flows.
08/Links
Private commercial codebase — no public links.
Next case study
DataUdaan →