For the complete documentation index, see llms.txt. This page is also available as Markdown.

Develop a new package

Voyzu business functionality is delivered through packages. A package has its own identity, installation assets and public exports, and contains one or more modules. Each module owns a coherent set of page routes, API routes and supporting business functionality.

This guide uses the @voyzu/ice-creams reference package as its example. Ice Creams is a self-contained CRUD package with reference data, application pages, REST APIs, a report, auditing, sample data and tests.

Before starting, create a Voyzu development environment by following Development setup.

Create the package directory

Create the package beneath the development workspace using its npm scope and package name:

npm run voyzu:create-package -- "@acme/customer orders"

The command creates packages/@acme/customer-orders from the Ice Creams reference package and links it into the development runtime. It replaces spaces with dashes and derives display labels, code identifiers, file and directory names, and SQL table names from the customer-orders package segment. You can instead create the structure manually as shown below.

# Development workspace root
packages/
└─ @voyzu/
   └─ ice-creams/

Every Voyzu package name must have the form @publisher/package-name. The directory and the name in package.json must agree exactly. For example, packages/@voyzu/ice-creams must declare "name": "@voyzu/ice-creams".

Create the package structure

The Ice Creams package separates package-level configuration from the modules that implement its functionality:

# packages/@voyzu/ice-creams
├─ install/
│  └─ db/
│     ├─ seed/
│     └─ sql/
├─ docs/
│  └─ public/
│     └─ example-help.md
├─ modules/
│  ├─ audit/
│  ├─ ice-creams/
│  ├─ reports/
│  └─ types/
├─ navigation/
├─ public-assets/
├─ scripts/
├─ package.json
├─ README.md
└─ voyzu.package.ts

The package must conform to the package contract. Every module registered by the package must conform to the module contract.

Define the package metadata

Create package.json at the package root. The voyzu.voyzu-package flag marks the directory as a Voyzu package, while voyzu.allowInstall controls whether Voyzu permits it to be installed. Runtime visibility is managed by Package Management after installation.

Declare packages required at runtime in dependencies or peerDependencies.

Add database installation

Packages that own database objects place their ordered, repeatable SQL beneath install/db. Ice Creams creates a reference table and a business table:

The schema uses a foreign key from ice_cream to ice_cream_flavor, stable business codes, status constraints and the standard Voyzu audit columns. Database constraints protect structural integrity even when data is written outside the user interface.

Seed data belongs under install/db/seed.

Create a module

The primary Ice Creams module owns the CRUD interface and APIs:

The module's module.ts is the authoritative registry of its application pages and REST endpoints. This abbreviated excerpt shows one API route:

Page paths are relative to the application root. API paths are relative to Voyzu's /api base path and must follow REST principles. Route IDs must be stable and unique across the composed Voyzu instance.

Implement the module layers

The Ice Creams module follows the standard Voyzu implementation layers:

Location
Responsibility

client

Forms, lists, details and client-side interaction

domain

Pure operation policies shared by client and server

server/api

HTTP input extraction and response mapping

server/db

SQL access and persisted row mapping

server/lib

Validation, business rules and orchestration

server/pages

Server-side page data loading

tests

Domain, service, validation and integration tests

Business rules must be enforced in the server service layer. Client-side use of the same policy may improve feedback, but it must not replace server-side enforcement.

For more information see Validation layers

Register the modules

A package may contain multiple modules. Ice Creams registers its CRUD, report and audit modules in voyzu.package.ts. This file is authoritative; Voyzu does not discover modules by scanning the modules directory.

Every package must register at least one module. The install, uninstall, and scripts sections are optional.

Add navigation

Navigation is optional. A package with user-interface pages may export a top navigation item, a left navigation definition, both, or neither. Navigation refers to page route IDs rather than duplicating URL paths.

Expose each navigation definition that the package provides through package.json:

Expose public functionality

Use the exports map in package.json to define the only entry points that other packages may import. Consumers must not reach into private source files.

A consuming package can then use the public package name:

Add public assets

Place package-owned static files in an optional package-root public-assets directory. Composition publishes them beneath the full package name in the Next.js public directory. For example, @acme/warehousing/public-assets/logo.svg is served at /@acme/warehousing/logo.svg.

Packages must use their own scoped public path and must not write directly to the platform's apps/web/public directory. Composition replaces published assets on update and removes them on uninstall.

Link the local package into the development runtime:

The command installs a physical package copy beneath .run/packages, applies its database installation, installs workspace dependencies and composes its modules into Voyzu. The command name is retained for compatibility.

Start the development server:

While development is running, Voyzu watches the editable source beneath packages and mirrors additions, changes, renames and deletions into the runtime copy for hot reload. Run composition again after changing package exports, module registrations, routes or navigation:

Add tests and documentation

Test domain rules, request and response validation, and exposed service behaviour at the narrowest useful boundary. Keep tests with the module they exercise and use fixtures for database-backed service tests.

Keep the package overview in its root README.md. Place all other package documentation under the package-root docs directory. Public-facing documentation and online-help source belong under docs/public.

Page routes may define a helpPath that Voyzu resolves against the package's voyzu.settings.helpBaseUrl setting.

Documentation may be published through GitBook or another provider. See Documentation and help for the complete pattern.

Reference package

The complete Ice Creams implementation conforms to the package and module contracts and demonstrates the patterns described in this guide.

View the Ice Creams reference package on GitHub

Last updated