This document explains the full website flow from the smallest shared features to the biggest end-to-end flows. It also shows how the frontend, backend, database, email service, and deployment/cloud operations connect.
The project is a MERN-style app:
- Frontend: React/Vite inside
views/ - Backend: Express app from
app.js - Database: MongoDB Atlas through Mongoose models
- Email: Nodemailer SMTP through Brevo
- API prefix: every backend endpoint starts with
/api - Frontend API calls: frontend services call
/api/..., and Vite/backend deployment route those requests to Express
Flow:
User browser
-> React page/component
-> React context or frontend service
-> fetch/HTTP request to /api/...
-> Express route
-> Controller
-> Service
-> Mongoose model
-> MongoDB Atlas
-> response back to React
-> UI updatesBackend starts from app.js.
npm run dev
-> nodemon app.js
-> dotenv loads .env
-> Express app is created
-> helmet/cors/json/cookie/morgan middleware are applied
-> /api/health route is mounted
-> /api routes/index.js is mounted
-> errorHandler is mounted last
-> connectDB() connects to MongoDB Atlas
-> app.listen(PORT)Important backend files:
app.js: app startup and middlewareconfig/db.js: MongoDB connectionconfig/env.js: environment variablesconfig/cors.js: allowed frontend originsroutes/index.js: combines all route filesmiddleware/errorHandler.js: final error response handler
The project does not use utils/apiResponse.js.
Controllers return normal Express JSON responses:
res.status(statusCode).json({
success: true,
message,
data,
})For errors:
res.status(statusCode).json({
success: false,
message,
})Why:
- It is simpler for the team to explain.
- Every controller is easy to read.
- We do not depend on a custom response helper.
Dev 5 owns the backend foundation because this is the base that all other backend work depends on.
Owns:
app.js.env.env.examplepackage.jsonconfig/db.jsconfig/env.jsconfig/cors.jsroutes/index.js- base middleware setup
- MongoDB connection
- route mounting
- backend startup
- CORS setup
- email environment setup base
Dev 5 also owns advanced backend features:
- Configurator backend
- Email sending through Brevo/Nodemailer
- Chatbot backend
- Admin dashboard backend
Dev 1 owns all authentication.
Owns:
models/User.jsmodels/PasswordToken.jsservices/authService.jscontrollers/authController.jsroutes/authRoutes.js- auth middleware support with Dev 5 foundation
Authentication features:
- Register
- Login
- Logout
- Get current user
- Forgot password
- Reset password
- JWT/token handling
- protected user access
Dev 2 owns:
- Brands
- Collections
- Watches
- Public catalog APIs
- Watch filters/sorting/search
- Admin watch CRUD backend
Dev 3 owns:
- Cart backend
- Orders backend
- Payment handling inside checkout/order creation
- Shipping backend
- Checkout order creation
- Cart persistence in MongoDB
Dev 4 owns:
- User profile backend
- Profile update
- Wishlist backend
- Reviews backend
- Review admin routes
Frontend experience features are split across the team:
- Translation: shared frontend feature using
LanguageContextandtranslations.json - Dark/light mode: shared frontend feature using
ThemeContext - Currency switcher: shared frontend feature using
CurrencyContext
These are frontend UI-state features, not backend modules.
If we want to save user preferences across devices later, then backend can add:
PATCH /api/users/profile
body: { preferences: { lang, theme, currency } }Frontend starts from views/src/main.jsx.
npm run dev inside views/
-> Vite starts React
-> main.jsx renders the app
-> providers wrap the routes
-> React Router loads route components
-> route loaders call frontend services
-> services call backend /api endpointsImportant frontend folders:
views/src/pages: page screensviews/src/components: reusable UIviews/src/context: global state like auth, cart, wishlist, language, currency, themeviews/src/services: API calls to backendviews/src/routes: React Router route mapviews/src/data/translations.json: English/Arabic translations
Frontend flow:
Theme switch button
-> ThemeContext updates theme state
-> theme is saved/restored
-> document/CSS classes or variables change
-> all components receive new colors through CSS variablesWhy it matters:
- It is a pure frontend feature.
- It should not save to MongoDB unless you want each logged-in user to keep their theme across devices.
Optional backend improvement:
PATCH /api/users/profile
body: { preferences: { theme: "dark" } }Frontend flow:
LanguageSwitcher
-> LanguageContext.setLang("en" or "ar")
-> localStorage saves selected language
-> <html lang="..."> and dir="ltr/rtl" update
-> components call t("translation.key")
-> UI text changesImportant files:
views/src/context/LanguageContext.jsxviews/src/data/translations.jsonviews/src/components/features/LanguageSwitcher.jsx
Dynamic data note:
Watch names, collection names, collection descriptions, testimonials, and some admin data come from MongoDB or JSON data. To translate those fully, the data itself needs fields like:
name: { en: "Heritage", ar: "التراث" }
description: { en: "...", ar: "..." }Frontend flow:
Currency selector
-> CurrencyContext changes currency
-> formatPrice(price) converts/displays price
-> product cards, cart, checkout, wishlist updateCurrent behavior is frontend display logic. If real exchange rates are needed, add a backend or external rates service.
Pages:
/login/register/account/forgot-password/reset-password
Backend routes:
authRoutes.jsuserRoutes.js
Models:
User.jsPasswordToken.js
Login flow:
User fills login form
-> LoginPage calls AuthContext.login()
-> authService sends POST /api/auth/login
-> backend validates credentials
-> backend creates token/session
-> frontend stores user state
-> user redirects to previous page or accountRegister flow:
User fills register form
-> RegisterPage calls AuthContext.register()
-> POST /api/auth/register
-> backend creates User document
-> frontend receives logged-in user
-> redirect to /accountProfile edit flow:
User edits profile in AccountPage
-> AuthContext.updateProfile()
-> frontend service sends profile update
-> backend user controller/service validates fields
-> User document updates in MongoDB
-> frontend user state refreshesBackend routes:
brandRoutes.jscollectionRoutes.jswatchRoutes.js
Models:
Brand.jsCollection.jsWatch.js
Shop flow:
User opens /shop
-> React Router loader calls watchService.getAll(filters)
-> GET /api/watches?filters...
-> backend watch route/controller/service
-> MongoDB Watch query with filters/sort/search
-> frontend receives watches
-> ProductGrid renders ProductCard listProduct detail flow:
User opens /watch/:id
-> route loader calls watchService.getById(id)
-> GET /api/watches/:id
-> backend fetches Watch
-> ProductDetailPage renders detailsCollections flow:
User opens /collections
-> collectionService.getAll()
-> GET /api/collections
-> MongoDB Collection list
-> CollectionsPage renders cards
User opens /collections/:slug
-> collectionService.getBySlug(slug)
-> watchService.getAll()
-> CollectionDetailPage renders collection and related watchesFrontend flow:
User opens search overlay
-> SearchOverlay fetches all watches once
-> user types query
-> frontend filters watches by name/brand/category
-> grouped results display
-> clicking item navigates to product pageCurrent search is mostly frontend filtering. For very large catalogs, move search to backend:
GET /api/watches?search=rolexBackend route:
cartRoutes.js
Model:
Cart.js
Frontend files:
CartContext.jsxCartPage.jsx
Logged-in cart flow:
User clicks Add to Cart
-> CartContext dispatch/add
-> cartService sends request to /api/cart
-> backend updates Cart document in MongoDB
-> frontend normalizes backend cart items
-> cart UI updatesWhy this matters:
- Cart is saved in MongoDB for logged-in users.
- If user opens another laptop after pull/deploy, cart appears because backend data persists.
Guest cart flow:
Guest adds product
-> CartContext stores locally
-> no MongoDB writeBackend route:
wishlistRoutes.js
Model:
Wishlist.js
Frontend files:
WishlistContext.jsxWishlistPage.jsx
Flow:
User clicks wishlist heart
-> WishlistContext add/remove
-> wishlistService sends request to /api/wishlist
-> backend updates Wishlist document
-> frontend receives normalized wishlist
-> UI updatesBackend routes:
orderRoutes.jsshippingRoutes.js
Model:
Order.js
Frontend files:
CheckoutPage.jsxShippingForm.jsxPaymentForm.jsxOrderReview.jsxCheckoutSteps.jsx
Checkout flow:
User opens /checkout
-> CheckoutPage checks CartContext
-> Step 1: ShippingForm collects address
-> Step 2: PaymentForm collects card or cash on delivery
-> Step 3: OrderReview confirms data
-> Place Order calls orderService.create()
-> POST /api/orders
-> backend creates Order document in MongoDB
-> cart clears
-> success message shownOrder history flow:
User opens /orders
-> route loader calls orderService.getMyOrders()
-> GET /api/orders/my
-> backend returns user orders
-> OrderHistoryPage renders tableAdmin order flow:
Admin opens /admin/orders
-> frontend loader calls orderService.getAll()
-> backend checks admin role
-> returns all orders
-> admin can review/update statusesBackend route:
configuratorRoutes.js
Model:
ConfigurationRequest.js
Email utility:
utils/emailService.js
Frontend page:
ConfiguratorPage.jsx
Flow:
User selects model/case/bezel/dial/strap
-> React state updates preview and price
-> user fills name/email/notes
-> configuratorService.submit()
-> POST /api/configurator
-> backend saves ConfigurationRequest in MongoDB
-> backend sends email to admin
-> backend sends confirmation email to user
-> frontend shows success messageEmail env:
EMAIL_HOST=smtp-relay.brevo.com
EMAIL_PORT=587
EMAIL_USER=your-brevo-login
EMAIL_PASS=your-brevo-smtp-password
EMAIL_FROM=Van Der Linde <verified-sender-email>
ADMIN_EMAIL=real-admin-emailImportant:
EMAIL_FROMmust be a verified sender in Brevo.ADMIN_EMAILis who receives the order/request details.- User email comes from the configurator form.
Backend routes:
reviewRoutes.jsadminReviewRoutes.js
Model:
Review.js
Flow:
User submits review
-> frontend sends review data
-> backend validates user/product
-> Review document saved
-> product rating can be recalculated/displayedAdmin review flow can approve, reject, or manage reviews depending on current route/controller logic.
Backend route:
chatbotRoutes.js
Environment:
GEN_AI_KEY
Flow:
User sends chatbot message
-> frontend sends prompt to /api/chatbot
-> backend calls AI service using GEN_AI_KEY
-> response returns to frontend
-> chat UI displays answerAdmin pages:
/admin/admin/watches/admin/orders
Backend routes:
adminRoutes.js- protected routes use auth/admin middleware
Flow:
Admin logs in
-> AuthContext stores user
-> AdminRoute checks user.role
-> admin page loads dashboard data
-> admin actions call protected backend endpoints
-> backend middleware verifies token and admin role
-> database updates happenAdmin watches flow:
Admin creates/edits/deletes watch
-> ManageProducts form
-> watchService create/update/delete
-> backend watch controller/service
-> Watch document changes in MongoDB
-> frontend list refreshesAdmin orders flow:
Admin updates order status
-> ManageOrders action
-> orderService update
-> backend updates Order document
-> customer order history reflects new statusBackend:
npm install
npm run dev
http://localhost:5000
GET /api/healthFrontend:
cd views
npm install
npm run dev
http://localhost:5173Backend .env:
PORT=5000
NODE_ENV=development
MONGODB_URI=...
JWT_SECRET=...
JWT_EXPIRE=7d
FRONTEND_URL=http://localhost:5173
GEN_AI_KEY=...
ADMIN_EMAIL=...
EMAIL_HOST=...
EMAIL_PORT=587
EMAIL_USER=...
EMAIL_PASS=...
EMAIL_FROM=...Frontend .env if needed:
VITE_API_URL=/apiRecommended simple split:
Frontend -> Vercel
Backend -> Render/Railway/Fly.io
Database -> MongoDB Atlas
Email -> Brevo SMTPCloud deployment flow:
Developer commits code
-> GitHub receives commit
-> Vercel builds frontend from views/
-> backend host builds Express app from root
-> backend environment variables are set in host dashboard
-> MongoDB Atlas allows backend IP/network access
-> frontend VITE_API_URL points to backend /api URL
-> backend CORS FRONTEND_URL allows deployed frontend domainProduction CORS must include deployed frontend:
FRONTEND_URL=https://your-vercel-domain.vercel.appProduction API examples:
GET https://your-backend-domain.com/api/health
GET https://your-backend-domain.com/api/watches
POST https://your-backend-domain.com/api/auth/loginVisitor lands on Home
-> switches language/theme/currency
-> searches or opens Shop
-> filters watches
-> opens Product Detail
-> adds to Cart/Wishlist
-> logs in/registers
-> checkout shipping/payment/review
-> order saved in MongoDB
-> user checks Order HistoryVisitor opens Configurator
-> selects model/case/bezel/dial/strap
-> sees updated preview and price
-> fills quote form
-> backend saves request
-> admin receives email
-> customer receives confirmation email
-> request appears in MongoDBAdmin logs in
-> opens Admin Dashboard
-> checks summary cards and activity
-> manages catalog watches
-> manages orders
-> watches/orders update in MongoDB
-> customer-facing pages reflect changesRun these after each feature change:
Backend:
GET http://localhost:5000/api/health
GET http://localhost:5000/api/brands
GET http://localhost:5000/api/collections
GET http://localhost:5000/api/watches
Frontend:
cd views
npm run buildManual frontend tests:
- Language switch: English -> Arabic -> English
- Theme switch: dark -> light -> dark
- Search overlay
- Shop filters
- Product detail
- Add/remove cart
- Add/remove wishlist
- Login/register/profile edit
- Checkout order creation
- Configurator email submission
- Admin dashboard/products/orders
Already translated in the current working tree:
- Navigation pieces
- Footer
- Search overlay
- Home
- Shop all / men / women
- Filters
- Product cards/details
- Cart and checkout flow
- Login/register/account/wishlist/orders
- Configurator
- Quiz
- Contact
- Collections
- Gift Registry
- Size Guide
- Not Found
Still needs a final translation/content pass:
- Long static About page content
- FAQ page
- Services page
- Gifting flow/page
- Privacy Policy page
- Terms page
- Forgot/reset password pages
- Admin pages
- Validation error messages in
utils/validators.js - Database-driven watch/collection/testimonial content
Do not call translation 100% complete until the remaining list is finished.