How abdelrahman-aboalkhair/full-stack-e-commerce-platform works
1. This is a monorepo with two primary runtime boundaries: src/client is the Next.js storefront/admin UI, and src/server is the Express API. The shared top-level files, Docker Compose, and Postman collections support local integration, but the application architecture is split cleanly into frontend, backend, and infrastructure.
2. The client is organized around Next.js App Router with route groups for public, auth, private, and dashboard experiences. Public pages cover catalog browsing, product detail, cart, and success screens; private pages cover user orders, profile, payment result screens, support, and real-time chat; dashboard pages cover admin operations such as products, inventory, attributes, analytics, reports, logs, users, transactions, and chats.
3. The UI layer is heavily componentized into atoms, molecules, organisms, templates, layout components, and feature-specific screens. This matters architecturally because the dashboard and storefront share generic building blocks, while each domain page composes its own localized feature components rather than relying on a single monolithic app shell.
4. Client-side data access is split between Redux Toolkit state and RTK Query API slices under src/client/app/store/apis. Those slices map to the server’s functional domains such as auth, products, cart, orders, checkout, analytics, logs, reports, chats, and users. There is also an Apollo client and GraphQL query layer for parts of the product/dashboard experience that use GraphQL instead of REST.
5. A notable frontend boundary is demo mode. When NEXT_PUBLIC_DEMO_MODE=true, the app can run fully in-browser without the backend, using mock catalog/session/store logic under src/client/app/lib/demo. The hosted demo uses this path, which means browse, auth, cart, checkout, orders, and even dashboard interactions can be simulated without network dependencies. If the API is unavailable and demo mode is off, the client can still fall back to static catalog data for browse-only pages.
6. The backend is a modular Express application built as feature folders under src/server/src/modules. Most domains follow the same internal shape: controller, service, repository, factory, routes, DTOs, and types. That pattern is repeated across auth, product, category, cart, order, payment, checkout, user, review, shipment, logs, reports, analytics, attributes, chat, section, variant, webhook, and address.
7. The server exposes both REST and GraphQL. REST is organized under versioned route trees (/api/v1, /api/v2) and includes the majority of CRUD and workflow endpoints. GraphQL is used selectively for product, transaction, and analytics subdomains, with a dedicated analytics GraphQL schema/resolver set for dashboard reporting.
8. Data persistence is centered on Prisma and PostgreSQL. Prisma schema and a long migration history define the evolving commerce model, including products, variants, attributes, orders, transactions, inventory/restock, and user relationships. This database is the main system of record for the store, admin, and analytics features.
9. Redis is a second backend dependency and is used for short-lived state and auth-related support. The presence of Redis utilities, token helpers, and a Redis infra layer suggests it acts as a cache/session/token store rather than a primary datastore. This makes Redis a supporting boundary for authentication and realtime-adjacent workflows, not the source of truth.
10. Real-time chat is a distinct subsystem spanning both client and server. The server has Socket.IO infrastructure plus a chat module, while the client has chat-specific hooks, container components, message rendering, audio/call UI, and socket connection hooks. This creates a separate event-driven data flow from the normal request/response API: browser socket events → server socket handlers → persisted or relayed chat data.
11. Checkout and payments are integrated through Stripe. The checkout module initiates payment flows, the payment module tracks outcomes, and the webhook module handles asynchronous provider callbacks. That means payment completion is not determined only by the browser redirect; the backend webhook is the authoritative confirmation path.
12. Analytics, reporting, and exports form another server-side read-heavy subsystem. Analytics has both REST and GraphQL layers plus shared aggregation utilities, while reports and transaction domains expose business summaries for the dashboard. Export utilities can produce CSV, PDF, and XLSX outputs, so reporting is designed as a downstream consumer of transactional and analytic data rather than a separate store.
13. Cross-cutting concerns are centralized in shared middleware, errors, logging, and utility layers on the server. Authentication/authorization, role hierarchy checks, DTO validation, upload handling, request logging, and error normalization sit outside domain modules. On the client, similar concerns are centralized through providers, guards, hooks, and layout templates.
14. Operationally, the repo is built for local self-hosting with Docker Compose, seeded data, and environment starter files. Swagger is exposed at /api-docs, Postman collections exist for each domain, and the client/server each have Dockerfiles. That makes the architecture suitable for diagramming as a locally runnable full-stack commerce system with external integrations for Stripe, Cloudinary, Redis, and optional OAuth/auth providers.
Main entry points: modules Domain modules · app Next app · app.ts Express app · demo Demo mode
Components 21
Client
Next.js storefront, auth, private account flows, and admin dashboard.
- Next app · App Router entrypoint with route groups for public, auth, private, and dashboard experiences.
src/client/app - Storefront · Catalog browsing, product detail, cart, and success pages.
src/client/app/(public) - Private area · User orders, profile, payment outcomes, support, and chat.
src/client/app/(private) - Dashboard · Admin workflows for products, inventory, attributes, analytics, reports, logs, users, transactions, and chats.
src/client/app/(private)/dashboard - UI kit · Reusable atoms, molecules, organisms, templates, layout, and auth guard components.
src/client/app/components - Client state · Redux Toolkit slices and API slices for auth, catalog, cart, orders, analytics, logs, reports, chats, and users.
src/client/app/store - GraphQL client · Apollo client plus GraphQL query definitions for selected product and dashboard reads.
src/client/app/lib/apolloClient.ts - Demo mode · In-browser mock catalog, session, and store logic that can run without the backend.
src/client/app/lib/demo
Server
Express API with REST, GraphQL, realtime chat, and data persistence.
- Express app · Server bootstrap, route composition, and request lifecycle setup.
src/server/src/app.ts - REST routes · Versioned REST route trees and health endpoints.
src/server/src/routes - Domain modules · Feature modules with controller, service, repository, factory, routes, DTOs, and types.
src/server/src/modules - GraphQL API · Selective GraphQL surface for product, transaction, and analytics domains.
src/server/src/graphql - Realtime chat · Socket-based chat handling and persisted chat domain logic.
src/server/src/infra/socket/socket.ts - Prisma data · Prisma schema, migrations, and the commerce system of record.
src/server/prisma/schema.prisma - Redis cache · Short-lived auth and supporting state for cache/session/token flows.
src/server/src/infra/cache/redis.ts - Stripe gateway · Checkout payment integration and asynchronous webhook confirmation.
src/server/src/infra/payment/stripe.ts - Cloudinary · Image and asset upload integration used by product and admin workflows.
src/server/src/infra/cloudinary/config.ts - Ops layer · Authentication, authorization, validation, request logging, errors, swagger docs, and output formatting.
src/server/src/shared/middlewares
Infra
Local dev, deployment, seed data, and external service wiring.
- Compose · Docker Compose orchestration for local self-hosted integration.
src/docker-compose.yml - Postman sets · Shared collections for exercising REST and GraphQL domains.
collections - Seed data · Seed scripts and seed images for local commerce data initialization.
src/server/seeds/seed.ts
Connections 29
- Compose → Next app: runs · Compose brings up the storefront/admin UI.
- Compose → Express app: runs · Compose brings up the API server.
- Seed data → Prisma data: loads · Seed scripts populate the PostgreSQL-backed domain model.
- Postman sets → REST routes: exercises · Collections cover REST endpoints and GraphQL operations.
- Next app → Storefront: routes · App Router public experience.
- Next app → Private area: routes · App Router private/account experience.
- Next app → Dashboard: routes · App Router admin experience.
- Next app → UI kit: composes · Pages are built from shared UI primitives and shells.
- Next app → Client state: uses · Client data and local app state flow through Redux and RTK Query.
- Next app → GraphQL client: queries · Selected screens use Apollo/GraphQL instead of REST.
- Next app → Demo mode: falls back · Demo mode can bypass backend dependencies for in-browser operation.
- Demo mode → Client state: mocks · Demo logic substitutes for store/session state.
- Demo mode → GraphQL client: fixtures · Demo GraphQL link serves fixture-backed results.
- Client state → Domain modules: calls · RTK Query slices target server functional domains.
- GraphQL client → GraphQL API: queries · Apollo client consumes the server GraphQL surface.
- Private area → Realtime chat: streams · Private chat UI connects to realtime socket events.
- Dashboard → Domain modules: admin APIs · Dashboard workflows use the same domain endpoints as the server modules.
- Express app → REST routes: mounts · Application bootstrap mounts versioned route trees.
- Express app → Domain modules: delegates · Core business logic is implemented inside feature modules.
- Express app → GraphQL API: exposes · GraphQL schemas are attached to the server.
- Express app → Realtime chat: attaches · Socket infrastructure is initialized alongside HTTP handling.
- Domain modules → Prisma data: persists · Domain repositories read and write the primary database.
- Domain modules → Redis cache: supports · Auth and transient flows rely on Redis utilities.
- Domain modules → Stripe gateway: charges · Checkout and payment modules integrate with Stripe.
- Domain modules → Cloudinary: uploads · Product/admin flows send assets through Cloudinary.
- Domain modules → Ops layer: wrapped by · Domains share middleware, validation, error handling, and logging.
- GraphQL API → Domain modules: reads from · GraphQL resolvers project data from product, transaction, and analytics domains.
- Realtime chat → Domain modules: persists · Realtime events can be stored or reconciled through the chat domain.
- Stripe gateway → Domain modules: confirms · Stripe webhooks finalize checkout/payment outcomes.