Grazed by Irna

Technical Architecture Specification — Full-Stack Web Platform

React 19 TypeScript Node.js MySQL Drizzle
🌐
💻Desktop Browser
Chrome / Firefox / Safari / Edge
Min viewport: 1024px
Full admin dashboard access
📱Mobile Browser
Responsive layout ≤ 768px
Touch-optimized UI
Hamburger nav, stacked cards
📟Tablet
Hybrid layout 768–1024px
Side-by-side product grid
Swipe gestures supported
HTTPS / TLS 1.3
⚛️
🏠Home Page
Hero banner with CTA
Featured products carousel
Business story section
Footer with social links
🛍️Products Page
Grid/list toggle view
Search bar (debounced)
Category filter sidebar
Pagination / infinite scroll
📄Product Detail
Image gallery / lightbox
Description & pricing
Related products
Enquire / Order CTA
🛒Cart & Checkout
Cart Context + localStorage
Quantity stepper controls
Running total calculation
Checkout: name + email only
✉️Contact / Order
Minimal order form (no account)
Client-side validation
Stock validated server-side
Confirmation email via Resend
🔐Admin Login
Email + password form
JWT stored in httpOnly cookie
Redirect to dashboard
📊Admin Dashboard
Product & category CRUD
Order management + status flow
Analytics charts (Recharts)
Image upload, stock editing
🛡️Auth Guard
PrivateRoute wrapper
Token refresh logic
401 → redirect to login
Role-based access
React 19 TypeScript React Router SCSS Modules Cart Context Recharts Vite 5
REST API (JSON)
🔧
📡Route Handlers
/api/products — CRUD
/api/categories — browse & manage
/api/orders — submit (public)
/api/admin/orders — manage & status
/api/auth — login, verify, logout
/api/admin/analytics — summary
⚙️Controllers
productController.ts
categoryController.ts
orderController.ts
authController.ts
analyticsController.ts
🗂️Models / ORM
Drizzle ORM (type-safe, zero overhead)
Product + Category models
Order + OrderItem models
Admin + EmailLog models
🛡️Middleware Stack
cors() — origin whitelist
helmet() — security headers
express-rate-limit
authMiddleware — JWT verify
multer — image uploads
express-validator — input
📧Email Service
Resend transactional email
Pre-built HTML templates
Order confirmation → customer
Status update → customer
All emails logged to email_logs
📁File Upload
Multer middleware
Image resize (Sharp)
Static /uploads directory
Max 5MB per file
📝Logger
Winston / Morgan
Request logging
Error tracking
Log rotation
Node.js Express Drizzle ORM MySQL JWT bcrypt Resend Multer
TCP/IP :3306
🗄️
📋 products
🔑 idINT AI
🔗 category_idINT
nameVARCHAR(255)
slugVARCHAR(255)
priceDECIMAL(10,2)
stock_quantityINT
image_urlVARCHAR(500)
is_activeBOOLEAN
📋 categories
🔑 idINT AI
nameVARCHAR(100)
slugVARCHAR(100)
sort_orderINT
📋 orders
🔑 idINT AI
customer_nameVARCHAR(255)
customer_emailVARCHAR(255)
messageTEXT
statusENUM
totalDECIMAL(10,2)
created_atTIMESTAMP
📋 order_items
🔑 idINT AI
🔗 order_idINT
🔗 product_idINT
quantityINT
priceDECIMAL(10,2)
📋 admins
🔑 idINT AI
emailVARCHAR(255)
password_hashVARCHAR(255)
nameVARCHAR(100)
📋 email_logs
🔑 idINT AI
🔗 order_idINT
typeVARCHAR(50)
to_emailVARCHAR(255)
statusENUM
Relationships: products.category_id → categories.id (FK) · order_items.order_id → orders.id (FK) · order_items.product_id → products.id (FK) · email_logs.order_id → orders.id (FK)
☁️
🖥️Contabo VPS
Single VPS hosting all services
Ubuntu 22.04 LTS
Nginx reverse proxy
Custom domain + Let's Encrypt SSL
⚙️Server Stack
Nginx → static frontend files
PM2 → Node.js process manager
MySQL 8.0 local instance
UFW firewall (80, 443, 22)
💾Database
MySQL 8.0 on same VPS
Local storage on VPS disk
Connection via localhost:3306
CLI / Sequelize for management
🔄Version Control
Git & GitHub repository
Manual deploy via SSH
Environment variables in .env
PM2 process management
📡
GET/api/healthHealth check
GET/api/productsList products (paginated, filterable by category/search)
GET/api/products/:slugSingle product detail (by ID or slug)
GET/api/products/search?q=Search by name/description
GET/api/admin/products🔐 List all products (with category join)
POST/api/admin/products🔐 Create product + image upload
PUT/api/admin/products/:id🔐 Update product (incl. stock, category)
DELETE/api/admin/products/:id🔐 Delete product
🛒
POST/api/ordersCreate order (validates stock, decrements, sends confirmation email)
📦
GET/api/admin/orders🔐 List all orders
GET/api/admin/orders/:id🔐 Order detail with items
PUT/api/admin/orders/:id/status🔐 Update status (triggers customer email)
🔐
POST/api/auth/loginAdmin login → JWT token
POST/api/auth/logoutClear auth cookie
GET/api/auth/verifyVerify current token
POST/api/auth/refreshRefresh expired token
PUT/api/auth/password🔐 Change admin password
📊
GET/api/admin/analytics/summary🔐 Total orders, revenue, popular products
🗂️
GET/api/categoriesList all categories (public)
GET/api/categories/:slugCategory detail + filtered products
GET/api/admin/categories🔐 List categories (with product count)
POST/api/admin/categories🔐 Create category
PUT/api/admin/categories/:id🔐 Update category
DELETE/api/admin/categories/:id🔐 Delete category (blocked if has products)
🔐 = Requires JWT auth header All responses: { success, data, message, pagination? } Errors: { success: false, error, statusCode }
📋 products
🔑 idINT AUTO_INCREMENT
🔗 category_idINT
nameVARCHAR(255) NOT NULL
slugVARCHAR(255) UNIQUE
descriptionTEXT
priceDECIMAL(10,2)
image_urlVARCHAR(500)
stock_quantityINT DEFAULT 0
is_activeBOOLEAN DEFAULT 1
created_atTIMESTAMP
📋 categories
🔑 idINT AUTO_INCREMENT
nameVARCHAR(100) NOT NULL
slugVARCHAR(100) UNIQUE
descriptionTEXT
image_urlVARCHAR(500)
sort_orderINT DEFAULT 0
created_atTIMESTAMP
📋 orders
🔑 idINT AUTO_INCREMENT
customer_nameVARCHAR(255) NOT NULL
customer_emailVARCHAR(255) NOT NULL
messageTEXT
statusENUM('new','confirmed','processing','shipped','delivered')
totalDECIMAL(10,2)
created_atTIMESTAMP
📋 order_items
🔑 idINT AUTO_INCREMENT
🔗 order_idINT
🔗 product_idINT
quantityINT
priceDECIMAL(10,2)
📋 admins
🔑 idINT AUTO_INCREMENT
emailVARCHAR(255) UNIQUE
password_hashVARCHAR(255) NOT NULL
nameVARCHAR(100)
created_atTIMESTAMP
📋 email_logs
🔑 idINT AUTO_INCREMENT
🔗 order_idINT
typeVARCHAR(50)
to_emailVARCHAR(255)
statusENUM('sent','failed')
sent_atTIMESTAMP
🔗
FK: products.category_id → categories.id ON DELETE SET NULL
FK: order_items.order_id → orders.id ON DELETE CASCADE
FK: order_items.product_id → products.id ON DELETE SET NULL
FK: email_logs.order_id → orders.id ON DELETE CASCADE
IDX: products(slug) UNIQUE — SEO-friendly URLs
IDX: products(category_id, is_active) — product listing queries
IDX: orders(status, created_at) — admin order filtering
IDX: orders(customer_email) — order lookup by customer
IDX: categories(slug) UNIQUE — URL-friendly category lookup
📁
src/ ├── components/ │ ├── common/ # Button, Input, Modal, Loader, Toast, Navbar, Footer │ ├── products/ # ProductCard, ProductGrid, ProductFilter, SearchBar │ ├── cart/ # CartItem, CartSummary, QuantityStepper, CartBadge │ ├── forms/ # OrderForm, LoginForm │ ├── admin/ # ProductTable, OrderList, AnalyticsChart, Sidebar │ └── layout/ # PublicLayout, AdminLayout, PrivateRoute ├── pages/ │ ├── HomePage.tsx │ ├── ProductsPage.tsx │ ├── ProductDetailPage.tsx │ ├── CartPage.tsx # Cart review, quantity editing, checkout form │ ├── admin/ │ │ ├── DashboardPage.tsx │ │ ├── ManageProductsPage.tsx │ │ ├── OrdersPage.tsx # Order list, status management │ │ └── AnalyticsPage.tsx │ └── LoginPage.tsx ├── context/ │ ├── AuthContext.tsx # JWT state, login/logout actions │ └── CartContext.tsx # Cart state, add/remove/update, localStorage sync ├── hooks/ │ ├── useProducts.ts # Fetch, filter, search products │ ├── useCart.ts # Cart operations, total calculation │ └── useAuth.ts # Auth state & token management ├── services/ │ ├── api.ts # Axios instance with interceptors │ ├── productService.ts # Product API calls │ ├── orderService.ts # Order submission API │ └── authService.ts # Auth API calls ├── utils/ │ ├── validators.ts # Form validation rules │ ├── formatters.ts # Date, price, text formatting │ └── constants.ts # API URL, categories, statuses ├── styles/ # SCSS Modules, variables, animations ├── App.tsx # Router setup └── main.tsx # Entry point
🗺️
/HomePageLanding with hero & featured
/productsProductsPageBrowse all products
/products/:slugProductDetailPageSingle product view
/cartCartPageReview cart, adjust quantities, checkout
/loginLoginPageAdmin authentication
/adminDashboardPageAUTHAnalytics overview
/admin/productsManageProductsPageAUTHProduct CRUD
/admin/ordersOrdersPageAUTHOrder management & status updates
/admin/analyticsAnalyticsPageAUTHDetailed analytics
🔄
🛒CartContext
items: CartItem[] (localStorage)
addToCart(product, qty)
updateQuantity(id, qty)
removeFromCart(id)
clearCart()
cartTotal: computed decimal
cartCount: badge number
🔑AuthContext
user: object | null
token: string (httpOnly)
login(email, pass) → JWT
logout() → clear state
isAuthenticated: boolean
📦Product State (hooks)
products: array
loading / error states
filters: { category, search, sort }
pagination: { page, total }
CRUD mutations (admin)
📦Order State (admin)
orders: array
statusFilter: enum
updateStatus(id, status)
orderDetail: order + items
Status triggers customer email
🛡️
🔐Authentication
bcrypt (12 salt rounds) password hashing
JWT access tokens (15min TTL)
Refresh tokens (7d TTL, httpOnly cookie)
Token rotation on refresh
Brute force: 5 attempts / 15min lockout
Input Validation
express-validator on all inputs
XSS sanitization (DOMPurify)
SQL injection: parameterized queries
File upload: type + size checks
CSRF protection via SameSite cookies
🌐Transport Security
HTTPS enforced (HSTS header)
TLS 1.2+ minimum
CORS: whitelist frontend origin only
Helmet.js security headers
Content-Security-Policy header
📋Data Protection
No plaintext passwords stored
Sensitive data in env variables
DB credentials never in codebase
Rate limiting on public endpoints
IP logging for abuse prevention
☁️
GitHub Repository
main branch (production)
feature/* branches
Version control & history
Code collaboration
git pull via SSH
Contabo VPS
npm install & build
Nginx → static + reverse proxy
PM2 → Node.js backend
MySQL 8.0 → local DB
Let's Encrypt → HTTPS
📊
Performance Targets
First Contentful Paint < 1.5s
Lighthouse score > 90
API response < 200ms avg
50 concurrent users supported
Image lazy loading + WebP
📈Monitoring
Winston error logging
Uptime monitoring (UptimeRobot)
Database query performance
API response time tracking
Email delivery status logs
🔄Maintenance
apt update / upgrade schedule
PM2 auto-restart on crash
Nginx log rotation
MySQL query optimization
Let's Encrypt auto-renewal