How tayebbb/valore-parfums works
1. The repository is a two-app monorepo split by responsibility. frontend/ is the customer-facing storefront plus admin UI, deployed on Netlify. backend/ is an API-only Next.js app deployed on Render. The frontend does not talk to Firestore directly; it forwards all /api/* traffic to the backend.
2. The main runtime boundary is “browser → frontend → backend → Firebase/third parties.” The frontend serves SSR/ISR pages, while the backend owns all mutable business operations: authentication, product CRUD, orders, pricing, finance, uploads, and notifications. This separation is central to any architecture diagram.
3. Firestore is the primary system of record, accessed only through the Firebase Admin SDK on the backend. Client Firestore rules deny all reads/writes. Collections are organized around commerce and operations: perfumes, orders, users, settings, decantSizes, bottles, vouchers, notifications, requests, stockRequests, wishlists, ownerAccounts, profitTransactions, auditLogs, and others.
4. Authentication is custom session-based. Email/password signup and login are handled server-side with PBKDF2 hashing and an HMAC-signed cookie (vp-session). Google sign-in uses Firebase client SDK on the frontend to obtain an ID token, which the backend verifies before creating the same session cookie. Admin access is enforced both in API routes and in the admin layout redirect logic.
5. The storefront is a classic commerce flow: browse homepage/shop/category/brand pages, view SEO-optimized product details, add items to a client-side cart, and check out. The cart lives in Zustand/localStorage on the frontend, but order creation is server-side, where the backend validates the cart, calculates pricing, deducts stock, stores the order snapshot, and triggers email plus admin alert hooks.
6. Pricing and finance are a separate subsystem, not embedded in the UI. Selling prices are derived from market price per ml, tier-based margin rules, bottle cost, and packaging cost, then rounded psychologically. Orders store immutable financial snapshots in minor units, and item-level profit is computed separately. This enables reporting, owner balance tracking, and later reconciliation.
7. Fulfillment supports two business paths: customer orders and sourcing requests. Standard orders can be delivery or pickup, with manual payment methods for bKash/bank transfer or COD. Separate request flows capture customer sourcing requests and full-bottle leads. Admin-created stock requests can also become sourcing-driven order records.
8. The admin panel is a second major UI surface, protected by role checks. It manages the catalogue, stock, bottle inventory, decant sizes, vouchers, pickup locations, notifications, store settings, requests, orders, exports, and reports. Dashboard charts and KPIs are fed by backend aggregates, including owner balances and low-stock signals.
9. Media and messaging are handled by external services. Product and QR images upload to Cloudinary, then their URLs are stored in Firestore. Emails are sent via Nodemailer over Gmail SMTP, with different templates for order confirmation, payment confirmation, dispatch, delivery, cancellation, and pickup events.
10. The frontend has a substantial SEO/content subsystem. It renders product pages with canonical URLs, JSON-LD schema, sitemap generation, robots directives, blog content, and six programmatic landing pages. There is also a Google Shopping-style merchant feed exposed from the backend, though it is not a primary user-facing path.
11. Cross-cutting concerns are implemented in shared server libraries: input validation, rate limiting, audit logging, order status configuration, image helpers, and cached reads for high-traffic endpoints. Some caches are in-memory per process, so they are not shared across instances; that matters for any deployment diagram showing horizontal scaling.
12. There are also maintenance and operational scripts in backend/scripts/ and duplicated in frontend/scripts/. These are one-off data repair and audit tools for stock, margins, decant sizes, perfumes, and finances. They are not runtime components, but they reflect that the backend is the authoritative place where operational data corrections happen.
Main entry points: api Backend API · firebase-admin.ts Firebase Admin · app Frontend shell · email.ts Media & email
Components 19
Frontend app
Netlify-hosted customer storefront and admin UI
- Frontend shell · SSR/ISR storefront, admin UI, SEO pages, and edge proxy
frontend/src/app - Storefront · Browse, product, cart, checkout, wishlist, and request flows
frontend/src/app/(store) - Admin panel · Protected back-office for catalogue, orders, inventory, reports, and settings
frontend/src/app/admin - SEO content · Canonical pages, JSON-LD, sitemap, robots, blog, and landing pages
frontend/src/app - API proxy · Forwards frontend /api traffic to the backend service
frontend/src/app/api/[...path]/route.ts - Browser state · Cart and other local UI state in Zustand/localStorage
frontend/src/store/cart.ts
Backend app
Render-hosted API-only Next.js service and authoritative business logic
- Backend API · Authoritative server for auth, commerce, pricing, inventory, and admin operations
backend/src/app/api - Auth service · Email/password signup and login, Google token verification, session cookie issuance
backend/src/lib/auth.ts - Commerce ops · Products, carts, orders, requests, vouchers, wishlist, pickup, and fulfillment
backend/src/app/api/orders - Pricing & finance · Margin rules, price derivation, financial snapshots, owner balances, and reporting aggregates
backend/src/lib/finance.ts - Admin aggregates · Dashboard KPIs, low-stock signals, exports, and operational summaries
backend/src/app/api/dashboard - Media & email · Cloudinary uploads and SMTP email templates for order and fulfillment events
backend/src/lib/email.ts
Data layer
Primary storage and external integrations
- Firebase Admin · Server-side Firestore access with admin credentials
backend/src/lib/firebase-admin.ts - Firestore · System of record for commerce, inventory, users, settings, notifications, and logs
backend/firestore.rules - Client rules · Client Firestore reads and writes are denied
frontend/firestore.rules - Cloudinary · Stores product and QR images referenced from Firestore
- Gmail SMTP · Outbound email delivery via Nodemailer
Operations
One-off maintenance scripts
- Repair scripts · One-off data fixes and audits for stock, margins, bottles, decants, and finances
backend/scripts
Other components
- Browser · Customer and admin users interact here
Connections 21
- Browser → Frontend shell: use UI · Users interact with storefront and admin surfaces
- Frontend shell → API proxy: forward /api · Frontend routes delegate API traffic to the backend
- Storefront → Browser state: cart state · Cart is kept client-side in local storage/state
- Admin panel → Backend API: admin calls · Protected admin operations are executed server-side
- Frontend shell → SEO content: render SEO · Frontend renders programmatic content and search pages
- API proxy → Backend API: proxy request · All frontend API traffic is forwarded to the backend
- Backend API → Auth service: auth flows · Login, signup, Google sign-in, logout, and session checks
- Backend API → Commerce ops: mutations · Product, order, request, voucher, wishlist, and fulfillment endpoints
- Backend API → Pricing & finance: price/finance · Pricing calculations and financial snapshots are computed server-side
- Backend API → Admin aggregates: dashboards · Dashboard and export endpoints read aggregate reporting data
- Backend API → Media & email: uploads/email · Uploads and notification emails are issued from backend handlers
- Auth service → Firebase Admin: verify token · Server auth verifies IDs and manages session state using admin access
- Commerce ops → Firebase Admin: read/write · Business operations use the Firebase Admin SDK
- Pricing & finance → Firebase Admin: store snapshots · Financial and owner balance data is persisted through admin access
- Admin aggregates → Firebase Admin: aggregate reads · Dashboard metrics and exports are derived from Firestore data
- Firebase Admin → Firestore: access data · Admin SDK is the only write-capable Firestore path
- Client rules → Firestore: deny client access · Client rules block direct reads and writes
- Media & email → Cloudinary: upload media · Product and QR images are stored externally
- Media & email → Gmail SMTP: send mail · Transactional emails are delivered through Gmail SMTP
- Repair scripts → Firestore: repair data · Maintenance scripts correct operational records and balances
- Browser → Browser state: local state · Client-side state supports cart and UI persistence