This repository contains:
backend— NestJS + TypeScript API using CQRS, TypeORM, PostgreSQL, Stripe, JWT authfrontend— Vite + React landing page with Stripe Elements checkout and account page
- Frontend loads plans from backend (
name,description,price,stripePriceId). - User selects a plan, enters email, and fills card details.
- On Buy:
- Frontend calls backend to create Stripe PaymentIntent.
- Frontend confirms card payment with Stripe Elements.
- Frontend calls backend to create subscription using
paymentMethodId + email + planId.
- Backend subscription creation flow:
- Finds/creates Stripe customer.
- Attaches payment method to customer and sets default payment method.
- Creates Stripe subscription.
- Creates local user (if missing) with generated password and logs password in backend console.
- Creates local subscription record.
- Frontend then renders login screen.
- After login, account page exposes one button: Get VPN configuration.
- On first request, backend assigns one available VPN config to user and persists it.
- NestJS 11
- CQRS (
@nestjs/cqrs) - TypeORM + PostgreSQL
- Stripe SDK
- JWT auth (email/password)
- Swagger docs (
/api/docs)
- Vite + React + TypeScript
- Stripe Elements (
@stripe/react-stripe-js,@stripe/stripe-js) - Axios
backend/src/modules/plans— plans query endpointbackend/src/modules/payments— create payment intentbackend/src/modules/subscriptions— create subscription orchestrationbackend/src/modules/auth— login endpoint + JWT strategybackend/src/modules/vpn-configs— get/assign user VPN configurationbackend/src/seed.ts— seeds plans and up to 1000 VPN configurationsfrontend/src/App.tsx— landing + checkout + login + account screens
- Node.js 20+
- npm 10+
- Docker (for local PostgreSQL)
- Stripe test account and API keys
- Copy root environment template:
cp .env.example .env- Copy service-level environment templates:
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env- Fill required Stripe values:
STRIPE_SECRET_KEYVITE_STRIPE_PUBLISHABLE_KEYSTRIPE_PRICE_ID_STARTERSTRIPE_PRICE_ID_PROSTRIPE_PRICE_ID_ULTIMATE
docker compose up -dcd backend
npm install
npm run seed
npm run start:devBackend runs on http://localhost:3000
Swagger: http://localhost:3000/api/docs
cd frontend
npm install
npm run devFrontend runs on http://localhost:5173
cd backend
npm test
npm run buildcd frontend
npm run buildGET /plansPOST /payments/create-intentPOST /subscriptions/createPOST /auth/loginGET /vpn-configs/me(JWT)POST /vpn-configs/assign(JWT)
- This implementation intentionally uses
synchronize: truefor speed of setup in interview context. - Generated user password is logged in backend console after first successful subscription.
- 1000 VPN configurations are pre-generated via seed command.