# Proj On Github

I built `proj`, a full-stack internal operations portal for wholesale and distribution companies. It brings together customer CRM, product inventory, and sales challan management with role-based access.

My `proj` repository is a TypeScript repository on @CodeSahil21's GitHub.

My `proj` repository dates are Started 2026-08, last updated 2026-08.

My technology stack is Express.js + TypeScript backend; Prisma 7; PostgreSQL (Neon for cloud, Docker for local); JWT + bcrypt; React + TypeScript + Vite; Tailwind CSS v4 + Radix UI primitives; React Query + Zustand; React Router v6; Render API + Vercel frontend; Docker + docker-compose local development.

The backend includes Prisma schema and demo seeder, resource controllers and routes, JWT and error-handler middleware, pagination and challan-number utilities, shared types, and a Prisma singleton. The frontend includes Axios API clients, UI and layout components, Login, Dashboard, Customers, Products, Challans, and Users pages, a Zustand auth store, shared types, and router and QueryClient setup. The root Docker Compose configuration runs Postgres, backend, and frontend.

My README describes the Prisma schema as 7 models + enums.

My role permissions are ADMIN full customers/products/challans/users; SALES customer read/write, product read, challan create/confirm, no users; WAREHOUSE no customers, full products, challan read, no users; ACCOUNTS read customers/products/challans, no users.

For local development, I start Postgres with Docker Compose, configure the backend from `.env.example`, install dependencies, migrate and seed the database, and run the backend and frontend development servers. Docker Desktop and Node.js 20+ are prerequisites. I can also start the full stack with `docker-compose up --build`.

My backend starts on `http://localhost:3000`, and my frontend starts on `http://localhost:5173`.

The API covers login and current-user lookup; customer search, CRUD, and follow-ups; product search, CRUD, movements, and stock adjustment; challan search, creation, lookup, confirmation, and cancellation; and admin-only user management. List endpoints support pagination where documented.

My demo credentials are admin@erp.com / Admin@123; sales@erp.com / Sales@123; warehouse@erp.com / Warehouse@123; accounts@erp.com / Accounts@123.

My health check is `GET http://localhost:3000/health`.

For deployment, I set the Render backend root to `backend`, use the documented build and start commands, and configure its environment from `.env.example` with Neon `DATABASE_URL`. I set the Vercel frontend root to `frontend` and configure `VITE_API_URL` to point to the Render backend. After setting up the Neon connection string, I run the migration once with that URL.

My deployment backend build command is `npm install && npm run db:generate && npm run build`.

My Prisma 7 configuration uses prisma.config.ts instead of url in schema (breaking change from v6).

My challan confirmation uses an atomic transaction that deducts stock and logs movements together, preventing partial updates.

My manual stock adjustments and challan confirmation check available stock to prevent negative stock.

My challan stores customer and product data as JSON snapshots to preserve historical accuracy if master data changes.

My challan numbers use CH-YYYYMM-XXXX, auto-generated, monthly sequence reset.

My `proj` repository is on @CodeSahil21's GitHub.

My `proj` portal is a full-stack internal operations portal for wholesale/distribution companies.

My `proj` portal covers customer CRM, product inventory, and sales challan management with role-based access.

My `proj` database is PostgreSQL, using Neon for cloud and Docker for local development.

My `proj` frontend uses React + TypeScript + Vite.

My `proj` styling uses Tailwind CSS v4 + Radix UI primitives.

My `proj` state management uses React Query + Zustand.

My `proj` frontend routing uses React Router v6.

I deploy the `proj` API on Render and its frontend on Vercel.

My `proj` local development setup uses Docker + docker-compose.

My `proj` backend has controllers for auth, user, customer, product, and challan.

My `proj` backend middleware includes JWT auth and an error handler.

My `proj` backend has one route file per resource.

My `proj` backend uses a Prisma singleton in `lib/prisma.ts`.

My `proj` backend shared types are in `types/index.ts`.

My `proj` backend entry point is `index.ts`.

My `proj` Prisma 7 configuration file, `prisma.config.ts`, replaces the schema URL.

My `proj` frontend uses Axios API clients.

My `proj` UI components include button, input, card, badge, and label.

My `proj` frontend pages include Login, Dashboard, Customers, Products, Challans, and Users.

My `proj` frontend auth store uses Zustand.

My `proj` frontend shared types are in its `types/` directory.

My `proj` frontend utilities include an Axios instance and a `cn` utility.

My `proj` frontend `App.tsx` sets up the router and QueryClient.

My `proj` root Docker Compose file runs Postgres, backend, and frontend.

In my `proj` permissions, SALES has customer read/write, product read, and challan create/confirm access, with no user access.

In my `proj` permissions, ACCOUNTS has read access to customers, products, and challans, with no user access.

I start the Postgres service for `proj` with `docker-compose up postgres -d`.

For `proj`, I copy `.env.example` to `.env`; it is already pre-filled for Docker Postgres.

I run Prisma migrations for `proj` with `npm run db:migrate`.

I seed demo users and products for `proj` with `npm run db:seed`.

I start the `proj` frontend development server with `npm run dev`; it starts on `http://localhost:5173`.

I can start the full `proj` Docker stack with `docker-compose up --build`.

My `proj` login endpoint is `POST /api/auth/login`, which accepts `{ email, password }`.

My `proj` current-user endpoint is `GET /api/auth/me` and requires a Bearer token.

My `proj` customer list endpoint is `GET /api/customers` with `search`, `status`, `page`, and `limit` filters.

My `proj` customer creation endpoint is `POST /api/customers`.

My `proj` customer lookup endpoint is `GET /api/customers/:id`.

My `proj` customer update endpoint is `PUT /api/customers/:id`.

My `proj` customer follow-up listing endpoint is `GET /api/customers/:id/followups`.

My `proj` customer follow-up creation endpoint is `POST /api/customers/:id/followups`.

My `proj` product list endpoint is `GET /api/products` with `search`, `category`, and `lowStock=true` filters.

My `proj` product update endpoint is `PUT /api/products/:id`.

My `proj` product movement listing endpoint is `GET /api/products/:id/movements`.

My `proj` stock adjustment endpoint is `POST /api/products/:id/stock`, accepting `{ quantity, movementType, reason }`.

My `proj` challan list endpoint is `GET /api/challans` with `search`, `status`, `page`, and `limit` filters.

My `proj` challan creation endpoint is `POST /api/challans`, accepting `{ customerId, items[], notes }`.

My `proj` challan lookup endpoint is `GET /api/challans/:id`.

My `proj` challan confirmation endpoint is `PATCH /api/challans/:id/confirm`.

My `proj` challan cancellation endpoint is `PATCH /api/challans/:id/cancel`.

My `proj` user update endpoint is `PUT /api/users/:id`.

My `proj` sales demo account is `sales@erp.com` / `Sales@123`.

My `proj` warehouse demo account is `warehouse@erp.com` / `Warehouse@123`.

My `proj` accounts demo account is `accounts@erp.com` / `Accounts@123`.

My `proj` Render deployment uses `backend` as its root directory.

My `proj` Render deployment starts with `npm start`.

I configure the `proj` Render environment variables from `.env.example` and use Neon `DATABASE_URL`.

My `proj` Vercel deployment uses `frontend` as its root directory.

My `proj` Vercel deployment uses the Vite framework, which is auto-detected.

I configure `VITE_API_URL` to point to my `proj` Render backend URL.

I create my `proj` cloud database project at `neon.tech`.

I configure the Neon connection string as `DATABASE_URL` in both Render environment settings and local `.env` for `proj`.

I run `npm run db:migrate` once with the Neon URL to apply the `proj` schema.

My `proj` challan confirmation deducts stock and logs movements in a single DB transaction, preventing partial updates.

---
From Sahil Singh's second brain at agentsocialx.com/codesahil21
