App
A named application: a set of modules + per-app defaults.
The app is the unit a wire (HTTP, queue, CLI) instantiates. One repo can declare multiple apps that share modules — that's how a monolith becomes a set of services without code changes.
Shape
ts
import { defineApp } from "@nwire/forge";
export const learnflowApp = defineApp("learnflow", {
description: "Adaptive learning loop for AMIT students and teachers.",
modules: [submissionsModule, enrollmentsModule, masteryModule, lessonsModule],
tenantModel: "per-org", // 'single' | 'per-org' | 'per-account' | 'per-workspace'
tenantKey: "schoolId", // the field in payloads carrying tenant id
defaults: {
/* runtime options applied unless wire overrides */
},
});
// Other apps in the same repo can re-use the modules differently:
export const lmsApp = defineApp("lms", { modules: [enrollmentsModule, rosterModule] });
export const lxApp = defineApp("lx", { modules: [submissionsModule, lessonsModule] });
export const competencyApp = defineApp("competency", { modules: [masteryModule] });Instantiation
A wire (HTTP / queue / CLI / cron) instantiates the app via defineApp.create():
ts
const app = learnflowApp.create({
actorStore: new MongoActorStore(client),
projectionStore: new MongoProjectionStore(client),
bus: new NatsEventBus({ ... }),
});
await app.start();In practice you don't call .create() directly — the topology composer (next page) reads a manifest and instantiates apps with the right provider stack for that deployment shape.
Multi-tenancy
tenantModel declares the partitioning strategy; Studio uses it to surface the right tenant picker per view. tenantKey declares the field name in payloads (and HTTP x-tenant-id header) the runtime reads.
tenantModel | When to use |
|---|---|
'single' | One tenant per process — the process itself is the boundary |
'per-org' | School / company / institution-level partition (AMIT, ecw) |
'per-account' | Each end-user is a tenant (B2C) |
'per-workspace' | Multi-tenant per workspace inside an org (Slack-shaped) |
Apps vs modules
| Modules | Apps |
|---|---|
| Bounded context | Deployment unit |
defineModule("submissions", { actions, actors, … }) | defineApp("learnflow", { modules }) |
| Reused across apps | Tied to a specific topology slice |