Fluent Commerce Logo
Docs
Sign In

About Reference And Extension Modules

Essential knowledge

Author:

Marco Heuer

Changed on:

18 Feb 2025

Overview

Modules are the package structure used by Fluent Commerce to ship preconfigured features and functions. They are designed to be self-describing, isolated, but inter-dependent assets that can work together with other modules, or be extended by custom modules, all while remaining upgradeable.

Here we'll look at the different designations of Modules and describe the Module's Package Structure and Project Structure.

Key points

  • 3 types of Modules: Reference, Extension and Data
  • Reference Modules are authored and maintained by Fluent Commerce
  • Extension Modules are created and maintained by customers and partner's teams
  • Module Structure defines the contents of a Module Archive
  • Module Project describes all the Module Assets, source code for Rules or Components and is checked into Source Control
  • A build step assembles the Module Assets into the Module Structure and creates the Module Archive
  • Fluent CLI commands like
    `fluent module install`
    only operate on the Module Archive or Module Structure

About Modules

Modules are the package structure used by Fluent Commerce to ship preconfigured features and functions. They are designed to be self-describing, isolated, but inter-dependent artifacts that can work together with other modules, or be extended by custom modules, all while remaining upgradeable.

Reference Module

A Reference Module is a Fluent Commerce produced module, which contains preconfigured features and functionality in a particular subdomain of Fluent Order Management, for the purposes of reference, and as a starting point for any implementation. The full list of Reference Modules can be found here.

Reference Modules typically include a Rules plugin, Workflows, and Settings, together with a configuration template which should be configured prior to installation.

In future, they may also include Components, Manifests, and Translations.

Extension Module

An Extension Module is a module produced by anyone, which contains additional or changed features and functionality. These are typically created by partners for customer projects, partner packaged IP, or sample purposes.

Data Module

A Data Module is a module which typically holds a specific project’s data assets. This can include anything from Carriers, to Virtual Catalogues, Controls, Categories and Products.

While a module can contain both template based assets and data, it is typical to separate these, since the configuration assets can be data agnostic and reusable in a variety of applications and Fluent Accounts. For example, you would deploy a Data Module with products to a development or testing account, but not a production account as there would be a regular product feed from the product information management (PIM) system.

Module Lifecycle

So how do the different puzzle pieces fit together across a Module's lifecycle?

Consider this diagram from creating to deploying a Module:

No alt provided

A common lifecycle of a Module would look like this:

  • Create the module from a template
  • Create or copy in the assets, eg workflows, settings, 
  • Build the Module Project and create the Module Archive
  • Test the module on a suitable Development Account
  • Commit the module structure to source control
  • Use the CI/CD to coordinate the promotion to UAT and Production Accounts

Module Configuration

A Fluent Module includes a

`module.config.json`
file, which serves as a template for the configuration of a Module.

Each time you install a Module, you should generate a configuration file, and populate it using the specific values, as per your specific project design.

Module configuration files are intended to be managed as part of your project resources, and it is advised to include them in source control.

Configuration files use a scope-based prefix and placeholder key, which is used to replace placeholders in asset template files inside the target module. For example, the Order Click & Collect workflow template may contain a placeholder with key

`network.ref`
. These are wrapped in double squares braces inside the asset file
`[[network.ref]]`

Consider the workflow below:

1{     
2  "name": "[[account.id]].order.SendEventToUpdateInventoryQuantity",
3  "props": {
4    "eventName": "UpdateInventoryQty",
5    "operation": "RESERVE",
6    "inventoryCatalogueRef": "[[inventory.catalogue.ref]]",
7    "retailerId": "[[inventory.retailer.id]]"
8  }   
9},    

Language: plain_text

Name: Order Workflow Fragment

Description:

[Warning: empty required content area]

In the fragment above you find 3 tokens. First, the

`[[account.id]]`
which defines the name space of the plugin with the order domain rules, by default the account id. Then the
`[[inventory.catalogue.ref]]`
which is the identifier for the inventory catalog. And lastly, the
`[[inventory.retailer.id]]`
describing in which retailer the inventory catalog can be found.

With the exception of the

`account.id`
, all other tokens need to have values supplied in the configuration file since they are specific to each account. 

Find below an example for these values from the Sample B2C Retailer setup:

1{
2   "default:inventory.catalogue.ref": "DEFAULT:1",
3   "default:inventory.retailer.id": "1",
4}

Language: plain_text

Name: Module Config fragment with tokens

Description:

[Warning: empty required content area]

For this example, these values will be used when replacing the tokens in the workflow when it's being uploaded to the retailer. You'll notice the prefix

`default`
in the values. Read on for more details on the scope prefixes.

The supported scope prefixes for workflows in the configuration files currently include:

  • `default`
  • `workflow`
  • `workflow:<root_entity>`
  • `workflow:<root_entity>:<subtype>`

The supported scope prefixes for settings in the configuration files currently include:

  • `default`
  • `setting`

Each of the above defines a granularity of scope for which the value should be used.

For example, if you only included a

`default:network.ref`
key and value, then all asset file templates containing the
`[[network.ref]]`
placeholder would be replaced with the value associated with the
`default:network.ref`
configuration key. 

If the configuration file declared a key of

`workflow:network.ref`
, then only
`workflow`
asset templates would use that key, while other assets would use the
`default:network.ref`
key.

Module Structure

The Module Structure defines the contents of a Module and includes all Module Assets.

A Module Archive is a simple zip file that is generated by a build and packaging step from a Module’s Project directory structure. 

The Module Archive contains the following structure:

1my-module-folder/
2  assets/
3  CHANGELOG.md
4  LICENSE.md
5  module.config.json
6  module.json
7  README.md  

Language: plain_text

Name: Example Module Structure

Description:

[Warning: empty required content area]

A Fluent Module must contain a

`module.json`
file which describes the Module's meta data, it’s dependencies, and contracts.

A Fluent Module must also contain a

`module.config.json`
file, which is a template file defining the configuration requirements for the module to be successfully installed. If there are no specific configuration settings, this file may be empty.

The

`assets`
folder can contain one or more subfolders for each of the assets included within the module.

Currently supported assets include:

  • `carriers`
  • `categories`
  • `control-groups`
  • `controls`
  • `inventory`
  • `inventory-catalogues`
  • `locations`
  • `networks`
  • `product-catalogues`
  • `products`
  • `roles`
  • `rules`
  • `settings`
  • `users`
  • `virtual-catalogues`
  • `workflows`

Additional asset types may be added in future, including, but not limited to:

  • `storage-areas`
  • `manifests`
  • `translations`
  • `components`
  • `connectors`
  • `customers`
  • `billing-accounts`
  • `orders`

Each asset folder can contain 1 or more files. Each Asset Type has a specific file schema.

Currently most asset files accept JSON, except for

`rules`
which expect
`.jar`
, and
`inventory`
, which expects
`.csv`
.

Module Project

This is where you’re working in day-to-day to create rules, workflows, etc and this is what is checked into source control.

An example of a Project Structure is as follows:

1<project_name>/
2  dist/
3    <dist_name>-<dist_semver>.zip
4    <dist_name>-<dist_semver>/
5      CHANGELOG.md
6      LICENSE.md
7      module.config.json
8      module.json
9      README.md
10      assets/
11        carriers/
12        networks/
13        locations/
14        storage-areas/
15        product-catalogues/
16        categories/
17        products/
18        inventory-catalogues/
19        inventory/
20        virtual-catalogues/
21        control-groups/
22        controls/
23        roles/
24        rules/
25          <plugins>
26        users/
27  components/
28    <bundle_name>/
29      package.json
30    package.json
31  connectors/
32    <connector_name>/
33      src/
34      pom.xml
35    pom.xml
36  resources/
37      CHANGELOG.md
38      LICENSE.md
39      README.md
40      module.config.json
41      module.json
42      README.md
43      carriers/
44      networks/
45      locations/
46      storage-areas/
47      product-catalogues/
48      categories/
49      products/
50      inventory-catalogues/
51      inventory/
52      virtual-catalogues/
53      control-groups/
54      controls/
55      roles/
56      users/
57  plugins/
58    pom.xml
59    rules/
60      pom.xml
61      <plugin_name>/
62        src/
63        pom.xml
64    types/
65      pom.xml
66      <types_name>/
67        src/
68        pom.xml
69    util/
70      pom.xml
71      <util_name>/
72        src/
73        pom.xml
74  scripts/
75      build-module.sh
76  .gitignore
77  CHANGELOG.md
78  LICENSE.md
79  README.md  

Language: plain_text

Name: Module Project Structure

Description:

[Warning: empty required content area]