Architecture
Unchained Engine is built using a layered architecture that separates concerns and enables customization at every level.
Layered Approach
| Layer | Description |
|---|---|
| App | Your project-specific code |
| Platform | Orchestration, GraphQL API, configuration |
| Service Gateway | Cross-module workflows (checkout, pricing) |
| Core Modules | Business logic and database abstractions |
App Layer
The user-land app is where your project-specific code lives. Unchained Engine is loaded as a framework into a Node.js project.
import { startPlatform } from '@unchainedshop/platform';
// Your app boots the platform
const engine = await startPlatform({
modules: { /* custom modules */ },
services: { /* custom services */ },
options: { /* configuration */ },
});
Platform Layer
The platform layer (@unchainedshop/platform and @unchainedshop/api) handles:
- Loading all default core modules
- Defining the GraphQL schema and resolvers
- Starting the API server (Express or Fastify)
- Managing the work queue for background jobs
- Orchestrating module configuration
- Email templates and messaging
- Authentication and session management
In rare cases, you might skip this layer to directly access core modules for:
- Federated microservices
- Custom non-GraphQL APIs
- Batch processing scripts
Service Gateway Layer
The service gateway composes functions from multiple modules to enable complex workflows:
| Service | Description |
|---|---|
orders | Checkout workflow, order pricing sheets |
products | Product pricing calculations |
users | User-related operations |
files | File operations with storage adapters |
You can modify services by:
- Using existing plugins
- Writing custom plugins
- Adding functions to
startPlatformoptions
await startPlatform({
services: {
orders: {
// Custom order service methods
},
},
});
Core Modules Layer
Core modules contain business logic and database abstractions. Each module is responsible for a specific domain:
| Module | Package | Description |
|---|---|---|
| Products | @unchainedshop/core-products | Product catalog management |
| Orders | @unchainedshop/core-orders | Order lifecycle and cart |
| Users | @unchainedshop/core-users | User accounts and auth |
| Payment | @unchainedshop/core-payment | Payment providers |
| Delivery | @unchainedshop/core-delivery | Shipping providers |
| Assortments | @unchainedshop/core-assortments | Categories and collections |
| Filters | @unchainedshop/core-filters | Product search and filtering |
| Warehousing | @unchainedshop/core-warehousing | Inventory management |
| Enrollments | @unchainedshop/core-enrollments | Subscriptions |
| Quotations | @unchainedshop/core-quotations | Request for quote (RFQ) |
| Bookmarks | @unchainedshop/core-bookmarks | Wishlists |
| Worker | @unchainedshop/core-worker | Background jobs |
| Files | @unchainedshop/core-files | File metadata |
| Events | @unchainedshop/core-events | Event history |
You can modify modules through:
- Configuration options at startup
- Plugins (Director/Adapter pattern)
- Custom module implementations
Infrastructure Layer
Foundation utilities used across all layers:
| Package | Description |
|---|---|
@unchainedshop/mongodb | Database lifecycle, queries, migrations |
@unchainedshop/events | Event emitter with pluggable backends |
@unchainedshop/logger | High-performance logging |
@unchainedshop/utils | Common utilities and base classes |
@unchainedshop/roles | Role-based access control (RBAC) |
@unchainedshop/file-upload | File storage adapters |
API Design Principles
- Stateless: All data stored in MongoDB, no server-side sessions
- Guest Users: Anonymous users use
loginAsGuestmutation for cart operations - Server-side Logic: All business logic remains server-side for omni-channel support
Implications
Carts as Open Orders
- Carts are stored server-side as orders with
status: null - Users can add items on one device and checkout on another
- After checkout, the cart becomes an immutable order
User Conversion
- Anonymous users can register without losing order history
- Carts merge when a user logs in during purchase
- Bookmarks and preferences are preserved
Package Dependency Graph
Next Steps
- Learn about the Director/Adapter Pattern for extending functionality
- Understand the Order Lifecycle for checkout implementation
- Explore the Pricing System for custom pricing logic