Разделы документации
ОбзорБыстрый стартРедакции и возможностиМодели и поляРедактор контентаМедиатекаЛокализацияПубликация и работа командыAPI, SDK и генерация типовРасширения и инструментыРабочие проектыЗадания, вебхуки и наблюдаемостьАудит и управление даннымиСоветники и доверие к плагинамКорпоративный входПространства, квоты и масштабированиеCommerce и PortalПрава и безопасностьРазвёртывание и обновленияЛицензии и установка пакетовТекущие ограниченияПомощь и диагностикаДанные в кабинетеCore CMSDeveloper PlatformProduction UseWorkflowOperationsComplianceAI AssistantsPlugin TrustEnterprise IdentityEnterprise ScaleEnterprise DeploymentCommerce BundlePortal BundleNotty CMS DocumentationAuth & SecurityContent ModelingDeploymentEcosystem & Packaging ConventionsEditions and First-party ModulesExtensibilityGetting StartedMedia ManagementModule Extraction PathDraft & PublishUpgrade GuideWebhooks & IntegrationsCookbook: Blog with Next.jsCookbook: Custom PluginCookbook: Multilingual SiteOperations DocsBackup AutomationDeployment BlueprintsRunbook — Восстановление БД из бэкапаRunbook — Плановый деплойRunbook — Реакция на инцидентRunbook — Откат релизаRunbook — Горизонтальное масштабированиеRunbook — Ротация секретовRunbook — Major upgradeSecrets ManagementNotty CMS — Capability MapNotty Configuration ModelGenerated App ContractComponents and Dynamic ZonesMiddleware SystemPerformance & Scaling ToolkitDisaster Recovery PlaybookDistribution Model
Документация / Технический справочник

Editions and First-party Modules

Техническое руководство из исходного проекта Notty. Примеры, параметры и эксплуатационные ограничения.

Все редакцииОбновлено 2026-09-30

Notty uses a layered packaging model:

  1. Core: the base CMS engine and developer extension surface.
  2. First-party modules: commercial product modules owned and supported by Notty.
  3. Editions: license bundles that enable a set of first-party modules.
  4. Add-ons: optional vertical bundles, such as commerce or portal modules.

The implementation is a modular runtime hosted by @notty/server with explicit workspace package boundaries for module contracts and first-party module manifests:

  • @notty/module-api owns the stable manifest and registry API.
  • Extracted module packages own their manifests and route/scope gates.
  • @notty/modules owns the static first-party manifest catalog without installing commercial module packages.
  • @notty/edition-* packages install the physical module packages for each sellable edition.
  • @notty/server remains the runtime host that resolves licenses, checks installed module packages, enforces gates and serves APIs.

Each manifest is registered through a runtime module registry. The registry validates duplicate module keys, duplicate feature keys, unknown dependencies and load order before capabilities are resolved.

Editions

Tier Edition Intended use Included modules
0 Community Free self-hosted development, evaluation and non-production use Core CMS, developer platform
1 Pro Commercial production sites and small teams Community plus production-use controls
2 Business Teams that need editorial process and operations Pro plus workflow, operations, compliance, AI and plugin trust
3 Enterprise Corporate deployments Business plus SSO, SCIM, multi-tenancy, scale and deployment controls

Community remains useful enough to evaluate and build with Notty. Commercial production use is modeled as a Pro-level capability so we can avoid relying on support-only monetization. The legacy developer edition value is accepted as a deprecated alias for community in environment and project config.

Installation Packages

New projects should install exactly one edition package:

pnpm create notty my-project --edition community
pnpm create notty my-project --edition pro
pnpm create notty my-project --edition business
pnpm create notty my-project --edition enterprise

The generated project depends on @notty/server, @notty/core and the selected @notty/edition-* package. Edition packages then pull only their allowed first-party modules:

Edition package Installs
@notty/edition-community @notty/module-cms, @notty/module-developer
@notty/edition-pro Community plus @notty/module-production
@notty/edition-business Pro plus workflow, operations, compliance, AI and plugin trust modules
@notty/edition-enterprise Business plus enterprise auth, scale and deployment modules

@notty/server does not directly depend on commercial module packages. If a module is requested by edition, license or override but the matching package is not installed, the module is reported as blocked and its features remain disabled. This lets us ship cheaper distributions that do not contain higher-tier commercial module packages at all.

Production Distribution

Community packages publish publicly. Paid edition packages and commercial module packages publish as restricted packages and are distributed through private registry access, edition-specific portable tarball distributions or private Docker images.

The production release flow builds package-level boundaries first, then creates physical distributions:

./scripts/local-publish.sh
pnpm release:verify:editions
pnpm release:dist -- --edition=all
pnpm release:dist:smoke -- --edition=community --manifest-only
pnpm release:docker -- community

pnpm release:dist -- --edition=<edition> creates dist/editions/notty-<edition>-<version>/ with only the packages required by that edition. This is the distribution to give to customers who need a portable self-hosted install without exposing higher-tier commercial packages.

Runtime Configuration

Environment variables have priority over notty.config.ts.

NOTTY_EDITION=business
NOTTY_LICENSE_KEY=notty_license_v1...
NOTTY_LICENSE_ENFORCEMENT=strict
NOTTY_ENABLED_MODULES=commerce.bundle
NOTTY_DISABLED_MODULES=business.ai

NOTTY_LICENSE_PUBLIC_KEY is not a production activation setting. Production strict mode verifies licenses with the built-in trusted Notty public keys shipped in @notty/server. A custom public key is accepted only for local development/testing when NOTTY_LICENSE_TRUST_MODE=dev and NODE_ENV !== production.

Equivalent project config:

import { defineConfig } from '@notty/core/config';

export default defineConfig({
  database: { url: process.env.DATABASE_URL ?? 'sqlite://./data/notty.db' },
  edition: 'business',
  license: {
    key: process.env.NOTTY_LICENSE_KEY,
    enforcement: 'strict',
    enabledModules: ['commerce.bundle'],
    disabledModules: ['business.ai'],
  },
  modules: {
    'business.ai': { enabled: false },
    'commerce.bundle': { enabled: true },
  },
});

Development and test environments default to observe: disabled features are reported with an observation header while calls remain available. Production always enforces strict, including Community with installed commercial modules; setting observe cannot unlock paid features. Disabled commercial features return HTTP 402. Production commercial deployments must explicitly configure strict and a signed notty_license_v1 license. Unsigned keys and licenses signed by custom keys are rejected.

Offline License Format

Strict self-hosted installs can use a signed offline license:

notty_license_v1.<base64url-json-claims>.<base64url-signature>

The signed claims include licenseId, edition, optional modules, optional customerName, customerId, domains, seats, installationId, offlineGraceDays, issuedAt, notBefore and expiresAt. The server verifies the payload with built-in trusted Notty public keys and checks edition/module grants, validity dates and installation binding. domains, seats and offlineGraceDays are currently metadata; runtime enforcement of those limits is not implemented.

Notty team members issue licenses from the private NottyPortal repository. The issuer private key and license generation scripts are intentionally outside the product repository and must not be bundled with @notty/server or customer distributions:

cd /secure/NottyPortal
NOTTY_LICENSE_ISSUER_PRIVATE_KEY_FILE=/secure/notty-license-root.key \
  pnpm --silent license:issue -- --edition=business --customer="Acme Corp" --expires=2027-05-25T00:00:00.000Z

For local development of the licensing flow only:

NOTTY_LICENSE_TRUST_MODE=dev
NOTTY_LICENSE_PUBLIC_KEY=<local-test-public-key>

Admin Capability Endpoint

Authenticated admin clients can read the active edition, license state, modules and features:

GET /api/admin/platform/capabilities

The response uses the shared EditionCapabilities type from @notty/types. The raw license key is never returned. Admin clients receive sanitized license status, module activation state, enabled features, locked features and module load order.

Feature Gates

Server code should use the gate helpers when a route or operation becomes edition-specific:

import { requireFeature, requireModule, checkCapabilities } from '~/lib/editions';

await requireFeature('enterprise.sso', event);
await requireModule('business.workflow', event);

const result = await checkCapabilities({
  modules: ['business.operations'],
  features: ['operations.webhooks'],
});

Use gates at route or service boundaries. Do not hide security basics behind commercial gates: base RBAC, password auth, safe defaults and critical patch paths belong to Core. Enterprise identity features such as SSO and SCIM can be commercial modules.

Module Manifests

First-party modules are declared as manifests:

export const enterpriseAuthModule = defineNottyModuleManifest({
  module: {
    key: 'enterprise.auth',
    displayName: 'Enterprise Identity',
    commercial: true,
    firstParty: true,
    addOn: false,
    requiredModules: ['pro.production'],
    packageName: '@notty/module-enterprise-auth',
    configKey: 'enterpriseAuth',
    description: 'SSO and SCIM automation.',
  },
  features: [
    { key: 'enterprise.sso', owningModule: 'enterprise.auth', commercial: true, ... },
    { key: 'enterprise.scim', owningModule: 'enterprise.auth', commercial: true, ... },
  ],
  adminRouteGates: {
    'admin:sso:providers:list': 'enterprise.sso',
  },
});

@notty/server derives the edition capability response from the @notty/modules manifest catalog and then checks whether the matching physical module package is installed. This keeps the commercial contract stable while allowing distributions to omit higher-tier commercial packages.

Module activation has four states:

  • active: module is enabled and all required dependencies are active.
  • locked: module is not available for the active edition/license.
  • disabled: module was explicitly disabled by config or environment.
  • blocked: module was requested, but a required module is not active or the matching package is not installed.

Admin route gates are enforced after admin authentication and scope checks through requireAdminRouteScope. Non-admin-route APIs use service/scope boundaries, for example SCIM is gated by enterprise.scim, webhooks are gated by operations.webhooks, and platform tenant access is gated by enterprise.multi-tenancy.

Module Ownership Catalog

The first-party manifest catalog owns the mapping from product modules to routes, scopes and admin surfaces. Route implementation can stay in @notty/server, but ownership and licensing policy must live next to the module manifest.

Module Admin routes / APIs Scope gates Admin surfaces
core.cms Content, schemas, components, media, settings Core content/schema scopes Content, Media, Schemas, Components
core.developer Admin extensions Extension runtime Devtools, plugin navigation
pro.production Backups, preview tokens admin:backups:*, preview:* Backups, Preview
business.workflow Releases, assignments releases:read, releases:write My Work, Releases
business.operations Jobs, scheduled jobs, alerts, delivery observability webhooks:*, jobs:*, scheduled-jobs:*, alerts Jobs, Webhooks, Incidents, Delivery
business.compliance Audit logs, activity, governance, retention, legal holds audit-logs:read, activity:read Activity, Audit Logs, Compliance
business.ai AI advisors and governed AI actions admin:ai:read, admin:ai:write AI Audit, AI Scaffolding
business.plugin-trust Plugin trust policy Plugin trust service gates Platform / plugin settings
enterprise.auth SSO providers, SCIM admin:scim:read, admin:scim:write SSO, identity automation
enterprise.scale Workspaces, tenant/platform admin guards admin:workspaces:read, admin:workspaces:write Workspaces
enterprise.deployment HA/deployment controls Deployment service gates Platform operations
commerce.bundle Commerce domain add-on Add-on service gates Commerce-specific extensions
portal.bundle Portal/member-area add-on Add-on service gates Portal-specific extensions

Package Boundary

First-party modules now have stable module keys, config keys, package names and a physical manifest package boundary:

Package Responsibility
@notty/module-api Module manifest type, defineNottyModuleManifest, registry checks
@notty/module-cms Core CMS manifest and base feature ownership
@notty/module-developer Core developer platform manifest and admin-extension gate
@notty/module-production Pro production-use manifest, route/scope gates and extracted preview-token/backup services
@notty/module-workflow Business workflow manifest and gates
@notty/module-operations Business operations manifest and gates
@notty/module-compliance Business compliance manifest and gates
@notty/module-ai Business AI manifest and gates
@notty/module-plugin-trust Business plugin-trust manifest
@notty/module-enterprise-auth Enterprise SSO/SCIM manifest and gates
@notty/module-enterprise-scale Enterprise tenant/workspace/quotas manifest and gates
@notty/module-enterprise-deployment Enterprise deployment manifest
@notty/module-commerce Commerce add-on manifest
@notty/module-portal Portal add-on manifest
@notty/edition-community Community install bundle
@notty/edition-pro Pro install bundle
@notty/edition-business Business install bundle
@notty/edition-enterprise Enterprise install bundle
@notty/modules Static first-party manifest catalog grouped by Core/Pro/Business/etc.
@notty/server Runtime host, license resolver, feature gates, API shell and host adapters

This is the safe extraction path: first move contracts and manifests out of the server and catalog, then migrate module implementation code behind those package keys one product domain at a time. The catalog package no longer imports commercial module packages, so installing @notty/server alone does not install higher-tier commercial packages. The first runtime extractions use a host-adapter boundary: @notty/module-production owns preview-token and backup business logic while @notty/server supplies database, import/export, audit, alert and cron-validation helpers and keeps the HTTP routes stable. The stable keys are pro.production, enterprise.auth, business.workflow, business.operations, business.ai, and vertical add-ons such as commerce.bundle or portal.bundle.

See docs/guide/module-extraction.md for the physical extraction workflow and docs/guide/commercial-release-checklist.md for the pre-release commercial gate.

Источник: docs/guide/editions-modules.md. Снимок документации исходного проекта. Технический справочник сохраняет язык оригинала.