Skip to content

Architecture

Wenex Platform is a distributed monorepo: one API gateway routes all external traffic to 15 domain microservices via gRPC. Workers consume events from Kafka and coordinate via BullMQ. All components share a common library (libs/common) for DTOs, guards, interceptors, and schemas.


System Context


Request Flow

A standard REST request traverses a fixed 16-stage pipeline inside the Platform Gateway before reaching any microservice, then passes through a 5-stage response pipeline on the way back.

Platform Gateway Pipeline Stages

Request side (in order)

GroupStagesPurpose
HTTP headersXRequestId, XPoweredBy, ETag, NamingConventionReqAdd trace ID, response headers, HTTP caching, convert snake_case → camelCase on input
SecurityAuthGuard, ScopeGuard, PolicyGuardValidate JWT/APT, check required scopes, evaluate ABAC policy
Rate & cacheCache, RateLimitReturn cached response if fresh; enforce per-collection request limits
Context & dataMetadata, Sentry, Authority, Field, Validation, Ownership, ValidationPipeExtract auth context, instrument errors, apply zone/ownership filter, strip disallowed fields, validate DTO shape, enforce ownership rules

Response side (in order)

StagePurpose
SerializerTransform entity → response shape, hide secret fields, apply projection
AuditLogRecord write operations for the audit trail
FilterApply post-query field filtering
NamingConventionResConvert camelCase → snake_case on output
NoApiResponseSuppress NestJS default wrapper when not needed

Client Gateway Pipeline Stages

Client applications that mirror the Platform pattern use a simpler pipeline:

StagePurpose
AuthGuardValidate the token
PolicyGuardABAC policy evaluation
Metadata InterceptorExtract auth context
Sentry InterceptorError tracking
Validation PipeDTO validation
→ ServicesBusiness logic
SerializerOutput transformation

Monorepo Structure


Gateway Internals

The gateway is the sole entry point for external traffic. It hosts three protocol surfaces simultaneously:


Service Architecture

Every domain service follows an identical internal structure:


Worker Architecture

Workers are event-driven: they consume Kafka topics and dispatch BullMQ jobs.


Data Layer

Soft Delete vs Hard Delete

All entities in MongoDB use soft-delete by default. The deleted_at timestamp is set instead of removing the document. Three lifecycle operations exist:

OperationHTTPEffect
deleteOne / deleteByIdDELETE /:idSets deleted_at — document hidden from queries
restoreOne / restoreByIdPUT /:id/restoreClears deleted_at — document visible again
destroyOne / destroyByIdDELETE /:id/destroyPermanently removes document from MongoDB

Hard delete (destroy) requires Manage scope, not just Write.


Authentication & Authorization Architecture


Metadata — The Auth Context Object

Every service method receives a Metadata object extracted from the request headers and JWT payload. It propagates through every gRPC call:

FieldSourcePurpose
tokenJWT payloadDecoded token claims
domainx-domain header or tokenTenant / domain scoping
clientx-client-id header or tokenOAuth client context
usertoken subAuthenticated user ID

Communication Topology


Key Design Principles

  1. Observable-first: All service methods return Observable<T> (RxJS), never Promises. Controllers and resolvers subscribe; gRPC streams are bridged automatically.

  2. Metadata is pervasive: Every operation carries auth context, enabling ownership checks, soft-delete filtering, and audit logging without manual threading.

  3. Consistent CRUD surface: All 15 services expose the same 14 operations (count, create, createBulk, find, cursor, findOne, findById, updateOne, updateBulk, updateById, deleteOne, deleteById, restoreOne, destroyOne). There are no service-specific exceptions.

  4. Three-layer authorization: AuthGuard (token validity) → ScopeGuard (required scopes) → PolicyGuard (ABAC rules). A request must pass all three.

  5. Cache coherence: Read operations use @Cache(COLL_PATH, 'fill') to populate Redis cache. Write operations use @Cache(COLL_PATH, 'flush') to invalidate it.