|
1 | | -# AWR Store – Full-Stack E-Commerce Project |
2 | | -[Kindly Watch this video before](https://www.loom.com/share/e6824c3ce6c54d828a443f56cce48eee) |
3 | | - |
4 | | - |
5 | | -A full-stack e-commerce application built as part of a technical take-home challenge. |
6 | | -I did build the app only to follow instructions but also to demonstrate expertise on solving problems, tooling (trade offs), intuitiveness, engineering best practices and creativity. |
7 | | -- I spined up the entire project on Docker to run on a single command. |
8 | | -- I added Github actions to run the test cases, lint and format on PR for both ends. |
9 | | -- I followed best practices on github by utilizing the PR system, Branching system, pr readable and purposeful naming convention system (Would have included versioning in real life for more robust systems if it was deployed) |
10 | | -- I also used a Monorepo and introduced a shared directory where BE and FE had something in common that did not need to be repeated by this applied the principle of DRY. |
11 | | -- I applied engineering principles like YAGNI by removing all files and codes that were not necessary most especially from the vite+react boilerplate. |
12 | | -- I applied principles like KISS by not over-engineering, for instance, I also used only native react tooling for everything |
13 | | - - API Consumption, I used fetch API and not any library |
14 | | - - State management, I used useContext API and not libraries like Redux, Mobx, Zustand etc. |
15 | | - - I utilized the power of inline css, Not libraries for component frameworks or styled libraries like Tailwindcss, Mui, AndDesign, Bootstrap, Scss etc |
16 | | - - I spined up my monorepo with npm instead of pnpm because in this project scale, it was not needed even though it is the most suitable choice for Monorepos. |
17 | | - - I used native javascript (alert) instead of building a component for the purpose or a library. |
18 | | -- I worked with every preexisting setups and tools on the BE to demonstrate not scared about new techs and the ability to pick and learn tools fast. That also hits on the engineering principle fail fast, learn quick. |
19 | | -- I did a couple of modularization which rings the bell on the software engineering principle SOC. |
20 | | -- I made sure all modules had a Single source of truth for easy readability by mostly adding index.ts files in almost each module. This also helps not just for readability but also makes extensibility easy and encourages the Open/Close Principle to be adhered to. |
21 | | -- I added some business logic test cases based on the functional requirement of the task to encourage functions integrity. |
22 | | -- I did not put down so many comments in the code base as I assumed most part of it would be easily readable and understandable. |
23 | | -- I handled validations, errors, states (loading, error, ) on both ends |
24 | | - |
25 | | - |
26 | | -This monorepo contains: |
27 | | - |
28 | | -- A **NestJS backend** with PostgreSQL + Prisma |
29 | | -- A **React + Vite + Typescript frontend** |
30 | | -- A **Shared workspace** for TypeScript interfaces (also with room for future extensions) |
31 | | -- A **Docker-based development environment** that runs the entire stack with one command |
32 | | - |
33 | | ---- |
34 | | - |
35 | | -## ✨ Features Implemented |
36 | | - |
37 | | -### Backend (NestJS + Prisma + PostgreSQL) |
38 | | -- REST API for: |
39 | | - - Products (CRUD) |
40 | | - - Orders & Relational Modeling (CRUD) |
41 | | -- Prisma schema with migrations |
42 | | -- PostgreSQL container with health checks |
43 | | -- Shared types imported from `/shared` |
44 | | -- Input validation, DTOs, modular architecture based on Monorepo |
45 | | -- Error handling with clean responses returned to FE |
46 | | -- Test cases for important business logics |
47 | | -- Clean, modular codes, Robust validation & error handling, Safe transactions (Data integrity) as per instructions |
48 | | - |
49 | | -### Frontend (React + Vite) |
50 | | -- Admin Dashboard Page |
51 | | -- Product listing page (Shop page) |
52 | | -- Create Product form Page |
53 | | -- Page not found page |
54 | | -- Order Confirmation page |
55 | | -- Add-to-cart experience |
56 | | -- Cart management |
57 | | -- Checkout flow connected to BE |
58 | | -- Shared TypeScript types from `/shared` |
59 | | -- Simple/clean styling (per instructions) |
60 | | - |
61 | | -### Monorepo Structure (npm workspaces) |
| 1 | +# Shop Cart — Full-Stack E‑Commerce (Pet Project) |
| 2 | + |
| 3 | +Shop Cart is a personal full‑stack e‑commerce project built to showcase end‑to‑end user sign-up, product, cart, and ordering workflows with a modern React frontend and a NestJS + Prisma backend. It is intentionally small, clean, and production‑ready in structure so features can evolve quickly. |
| 4 | + |
| 5 | +## Highlights |
| 6 | +- Monorepo with shared TypeScript schemas |
| 7 | +- NestJS backend with Prisma + PostgreSQL |
| 8 | +- React + Vite frontend with Tailwind CSS |
| 9 | +- Authentication with JWT and admin‑only product creation |
| 10 | +- Docker Compose for local development |
| 11 | + |
| 12 | +## Architecture |
| 13 | +- FE: React, Vite, Tailwind, Typescript |
| 14 | +- BE: NestJS, Prisma, PostgreSQL, Typescript |
| 15 | +- shared: shared Zod schemas and types |
| 16 | + |
| 17 | +## Project Structure |
62 | 18 | ``` |
63 | | -awr-store-project/ |
| 19 | +shop-cart-project/ |
64 | 20 | ├── BE/ # Backend (NestJS) |
65 | 21 | ├── FE/ # Frontend (Vite + React) |
66 | | -├── shared/ # Shared types |
67 | | -├── package.json # Scripts and workspace definitions |
| 22 | +├── shared/ # Shared types/schemas |
| 23 | +├── package.json |
68 | 24 | └── docker-compose.yml |
69 | | -
|
70 | 25 | ``` |
71 | 26 |
|
72 | | ---- |
73 | | - |
74 | | -## 🐳 Running the Project (Docker) |
| 27 | +## Running Locally (Docker) |
| 28 | +### Prerequisites |
| 29 | +- Docker and Docker Compose |
75 | 30 |
|
76 | | -### Requirements (Make sure already have) |
77 | | -- Docker |
78 | | -- Docker Compose |
79 | | -- .env inside the BE directory (check BE/.env.example for what to provide) |
80 | | - |
81 | | -### Start the entire stack (from the root) |
82 | | -```bash |
| 31 | +### Start the stack |
| 32 | +``` |
83 | 33 | npm run dev |
84 | 34 | ``` |
85 | 35 |
|
86 | | -This brings up: |
| 36 | +Services: |
| 37 | +- Frontend: http://localhost:5173 |
| 38 | +- Backend: http://localhost:3000 |
| 39 | +- Postgres: localhost:5432 |
87 | 40 |
|
88 | | -| Service | URL | |
89 | | -|--------|-----| |
90 | | -| Frontend | http://localhost:5173 | |
91 | | -| Backend API | http://localhost:3000 | |
92 | | -| PostgreSQL | localhost:5432 | |
93 | | - |
94 | | -### Rebuild containers if needed |
95 | | -```bash |
96 | | -npm run dev:build |
| 41 | +### Stop containers |
97 | 42 | ``` |
98 | | - |
99 | | -### Stop all containers |
100 | | -```bash |
101 | 43 | npm run dev:down |
102 | 44 | ``` |
103 | 45 |
|
104 | | ---- |
105 | | - |
106 | | -## 🛠 Tech Stack |
107 | | - |
108 | | -### Backend |
109 | | -- NestJS |
110 | | -- Prisma ORM |
111 | | -- PostgreSQL |
112 | | -- TypeScript |
113 | | -- Docker |
114 | | - |
115 | | -### Frontend |
116 | | -- React |
117 | | -- Vite |
118 | | -- TypeScript |
119 | | -- Docker |
120 | | - |
121 | | -### Dev Tools |
122 | | -- Biome (format + lint) |
123 | | -- npm workspaces |
124 | | -- Docker Compose |
125 | | -- Tests Cases (frontend and backend) |
126 | | -- CI Pipeline (Github Actions: runs lint, format and tests) |
127 | | - |
128 | | ---- |
129 | | - |
130 | | -## 🧱 Development Details |
131 | | - |
132 | | -### Backend Startup Flow |
133 | | -The backend container runs: |
134 | | - |
135 | | -``` |
136 | | -npm run build --workspace=shared |
137 | | -cd BE && |
138 | | -npx prisma generate && |
139 | | -npx prisma migrate deploy && |
140 | | -npm run start:dev --workspace=BE |
141 | | -``` |
142 | | - |
143 | | -### Frontend Startup Flow |
144 | | -``` |
145 | | -npm install |
146 | | -npm run dev --workspace=FE |
| 46 | +## Environment Variables |
| 47 | +Create BE/.env with: |
147 | 48 | ``` |
148 | | - |
149 | | ---- |
150 | | - |
151 | | -## 🧪 Tests |
152 | | - |
153 | | -``` |
154 | | -npm run test:be |
155 | | -npm run test:fe |
| 49 | +DATABASE_URL=postgresql://user:password@shop-cart-pg:5432/shop-cart?schema=public |
| 50 | +JWT_SECRET=your_jwt_secret |
| 51 | +ADMIN_CREATION_SECRET=your_admin_secret |
156 | 52 | ``` |
157 | 53 |
|
158 | | ---- |
| 54 | +## Auth & Admin Flow |
| 55 | +- Register/login via /auth/register and /auth/login |
| 56 | +- To create an admin account, pass the header x-admin-secret with ADMIN_CREATION_SECRET when registering |
| 57 | +- Only admins can create products |
159 | 58 |
|
160 | | -## 📦 Scripts |
| 59 | +## Scripts |
| 60 | +- npm run dev — start full stack with Docker |
| 61 | +- npm run dev:build — rebuild and start |
| 62 | +- npm run dev:down — stop containers |
| 63 | +- npm run test:be — backend tests |
| 64 | +- npm run test:fe — frontend tests |
161 | 65 |
|
162 | | -| Script | Description | |
163 | | -|--------|-------------| |
164 | | -| npm run dev | Start full stack with Docker | |
165 | | -| npm run dev:build | Rebuild & restart everything | |
166 | | -| npm run dev:down | Stop all containers | |
167 | | -| npm run test:be | Backend tests | |
168 | | -| npm run test:fe | Frontend tests | |
169 | | -| npm run biome:format | Auto-format codebase | |
170 | | -| npm run biome:lint | Lint entire monorepo | |
171 | | -| npm run biome:fix | Auto-fix lint issues | |
| 66 | +## CI Pipeline (GitHub Actions) |
| 67 | +On pull requests, the CI workflow runs: |
| 68 | +- Lint and format checks (Biome) |
| 69 | +- Backend tests |
| 70 | +- Frontend tests |
172 | 71 |
|
173 | | ---- |
174 | 72 |
|
175 | | -## 📝 Environment Variables |
| 73 | +## API Documentation |
| 74 | +Swagger UI is available when the backend is running: |
| 75 | +- http://localhost:3000/api |
176 | 76 |
|
177 | | -``` |
178 | | -DATABASE_URL="postgresql://user:password@awr-pg:5432/awr?schema=public" //SN: Of course, in reality I will not expose |
179 | | -
|
180 | | -``` |
| 77 | +### Auth |
| 78 | +- POST /auth/register |
| 79 | +- POST /auth/login |
181 | 80 |
|
182 | | ---- |
183 | | -## Constraints - What I did not do |
184 | | -- Like stated initially, I did not really use libraries on my FE except for routing |
185 | | -- I did not deploy my codes as it was not really necessary for the task, I should have been able to do something on Netlify, Vercel or AWS amplify for the FE and AWS, Heroku or Hetzner for the BE |
186 | | -- I did not consider Observability and monitoring on any end as it was not necessary although health was set on Docker. |
187 | | -- I did not consider SEO Optimization Accessibility, Localization on the FE although I considered responsiveness. |
188 | | -- I did not consider adding query and params to my backend for filtration and sorting, but on course for a system that is meant to grow in real life, it would be important to add that |
| 81 | +### Products |
| 82 | +- GET /products |
| 83 | +- POST /products (admin only) |
189 | 84 |
|
190 | | -## 🤝 Submission |
| 85 | +### Orders |
| 86 | +- POST /orders |
| 87 | +- GET /orders/:id |
191 | 88 |
|
192 | | -This repository contains my complete submission for the Full-Stack E-Commerce Take-Home Challenge. |
| 89 | +## Notes |
| 90 | +This is a pet project intended for learning and showcasing best‑practice structure. It is not production‑deployed and favors clarity over scale. |
0 commit comments