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:
| Part | Responsibility |
|---|---|
forRoot() | The single entry point. Returns a DynamicModule, accepts the host’s authGuard and adapter bindings. |
| Controllers | HTTP routes, annotated with Swagger decorators so they appear in the engine’s /docs. |
| Services / use-cases | Domain logic. |
| Models | Sequelize models, exported as a <PKG>_MODELS array the engine aggregates. |
| Ports | DI tokens (@Inject(...)) for capabilities the package does not own. |
| Migrations | Bundled 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
- Package contract — the seven rules every package must satisfy.
- Package catalog — all
@withpotter/*packages by domain and tier.