PackagesOverview

Packages

Box’s capabilities live in roughly fifty @withpotter/* engine packages. Each is a self-contained NestJS module that owns one domain — products, orders, bookings, loyalty, and so on. A box installs only the packages its tier entitles and the engine composes them into one API.

Anatomy of an engine package

Every package follows the same shape:

PartResponsibility
forRoot()The single entry point. Returns a DynamicModule, accepts the host’s authGuard and adapter bindings.
ControllersHTTP routes, annotated with Swagger decorators so they appear in the engine’s /docs.
Services / use-casesDomain logic.
ModelsSequelize models, exported as a <PKG>_MODELS array the engine aggregates.
PortsDI tokens (@Inject(...)) for capabilities the package does not own.
MigrationsBundled SQL/JS migrations the engine globs and runs on boot.

How the engine consumes a package

The engine imports a package’s module via forRoot(), passing the shared authGuard and binding any adapters the package’s ports need:

ProductModule.forRoot({
  authGuard: AuthGuard,
  mediaCleanup: { provide: MEDIA_CLEANUP, useClass: PlatformMediaCleanupAdapter },
})

The package’s models join the engine-wide ENGINE_MODELS registry, and its migrations are picked up by the boot-time migration runner. See Engine.

The exhaustive, always-current reference for a package’s routes is the engine’s OpenAPI document at /docs. Because it is generated from the installed build, it reflects exactly the endpoints, request bodies, and responses a given box exposes. See Engine → OpenAPI.

Sections