Step 2: Create your first module
With the base app running, add a custom inventory package that the generators can pick up.
1. Scaffold the package
mkdir -p packages/inventory/src/modules/inventory
touch packages/inventory/src/modules/inventory/{index.ts,acl.ts,di.ts}
Populate the metadata in index.ts so the module shows up in registries:
import type { ModuleInfo } from '@open-mercato/shared/modules/registry';
export const metadata: ModuleInfo = {
id: 'inventory',
title: 'Inventory',
version: '0.1.0',
description: 'Track stock levels for sellable items.',
};
Declare the RBAC features you plan to enforce:
export const features = [
'inventory.view',
'inventory.create',
'inventory.edit',
'inventory.delete',
];
Create an Awilix registrar even if you do not wire services yet—the file keeps the structure predictable:
import type { AppContainer } from '@open-mercato/shared/lib/di/container';
export function register(_: AppContainer) {
// Register services when you introduce business logic.
}
2. Enable the module
Open src/modules.ts and reference the new package:
import { defineModules } from '@open-mercato/shared/modules';
export default defineModules([
{ id: 'auth', from: '@open-mercato/core' },
{ id: 'directory', from: '@open-mercato/core' },
{ id: 'entities', from: '@open-mercato/core' },
{ id: 'inventory', from: '@open-mercato/inventory' }, // 👈 new module
]);
Run the generators so the new module is included in the registry:
yarn modules:prepare
3. Add the first page
Create the backend page directory and metadata:
mkdir -p packages/inventory/src/modules/inventory/backend/inventory
touch packages/inventory/src/modules/inventory/backend/inventory/page.tsx
touch packages/inventory/src/modules/inventory/backend/inventory/page.meta.ts
const InventoryLanding = () => {
return (
<div className="container">
<h1 className="margin-bottom--md">Inventory</h1>
<p>Welcome! You will add data grids and forms in the next steps.</p>
</div>
);
};
export default InventoryLanding;
import type { PageMetadata } from '@open-mercato/shared/modules/registry';
export const metadata: PageMetadata = {
title: 'Inventory',
group: 'Operations',
order: 20,
requireAuth: true,
requireFeatures: ['inventory.view'],
};
Restart the dev server (or wait for hot reload) and open /backend. You should now see an Inventory link in the sidebar that leads to the placeholder page.
ℹ️ Override packaged pages by creating a file under
src/modules/<module>/backend. Because your inventory module lives in a package you control, you can edit it directly. Core modules from@open-mercato/corecan be replaced by adding files undersrc/modules/auth,src/modules/directory, etc.