Clarity Platform Architecture  /  Plugins

Plugin System & Catalog

The Clarity platform uses a modular plugin architecture where every feature—from payment processing to ERP connectors—is an isolated, composable plugin. Plugins register their own database entities, API endpoints, pipelines, and frontend code through a unified interface.

extension

Plugin System

Every plugin implements the IPlugin interface, which defines the contract between the plugin and the Phoenix.Core host. This interface provides lifecycle hooks for service registration, database model configuration, and application startup.

code IPlugin Interface
public interface IPlugin {
    string Name { get; }
    string Schema { get; }
    void RegisterServices(WebApplicationBuilder builder);
    void OnStartup(WebApplication app);
    void OnModelCreating(ModelBuilder builder);
    Type[] GetAdditionalDatabaseTypes();
}

A PluginBase abstract class provides sensible defaults for optional members, so most plugins only need to override the methods they actually use.

description

.csproj Project File

Defines the C# project, NuGet dependencies, and references to Phoenix.Core. Each plugin is a standalone .NET class library.

terminal

Plugin Class (C#)

The backend implementation: IPlugin interface, database entities, pipelines, hooks, API endpoints, and service registrations.

data_object

plugin.json (Frontend)

Declares frontend routes, components, extension points, and assets that the Remix UI should load for this plugin.

Each plugin specifies its own database entities, API endpoints, pipelines, and frontend code. This isolation means plugins can be developed, tested, and deployed independently without modifying core platform code.

cycle

Plugin Lifecycle

Plugins are registered in a specific order within Startup.cs using the fluent .AddPhoenixPlugin<>() chain. Registration order determines initialization sequence and can affect dependency resolution.

code Startup.cs Registration
builder
    .AddPhoenixPlugin<SitePlugin>()
    .AddPhoenixPlugin<ConnectCorePlugin>()
    .AddPhoenixPlugin<PaymentsPlugin>()
    .AddPhoenixPlugin<InvoicingPlugin>()
    .AddPhoenixPlugin<SalesPlugin>()
    .AddPhoenixPlugin<ProductsPlugin>()
    .AddPhoenixPlugin<NetSuitePlugin>()
    .AddPhoenixPlugin<NuveiPlugin>();

Initialization Sequence

1

RegisterServices

Called during application build. Each plugin registers its DI services, repositories, pipeline handlers, and configuration options into the shared service collection.

2

OnModelCreating

Called when Entity Framework builds the database model. Each plugin configures its own entity mappings, indexes, relationships, and schema isolation.

3

OnStartup

Called after the application is built. Plugins can map endpoints, register middleware, seed data, or perform any startup initialization.

Workflow Taxonomy

Connector plugins use WorkflowVendor and WorkflowProduct properties to categorize their pipelines within the workflow engine. This taxonomy enables the platform to route workflows to the correct connector implementation.

info Example: NetSuite Connector
WorkflowVendor
"NetSuite"
WorkflowProduct
"ERP"
device_hub

Submodules & Git

Plugins are managed as Git submodules within the host project. Understanding Git fundamentals is essential to working with this architecture, so let us walk through the key concepts.

Git Basics: Commits

A Git repository is fundamentally a sequence of commits. Each commit is a snapshot of your project at a point in time, identified by a unique hash (SHA). Commits form a chain, where each commit points back to its parent.

Git commits forming a chain, each with a unique hash

Branch References

A branch is simply a pointer (reference) to a specific commit. The HEAD pointer indicates which branch you currently have checked out.

Branch reference pointing to a commit

Creating Commits

When you create a new commit, Git creates a new snapshot and moves the current branch pointer forward. The branch always points to the latest commit on that line of development.

Creating a new commit - step 1
Creating a new commit - step 2

Creating Branches

Creating a branch simply adds a new pointer to the current commit. You can then switch to it and start making independent changes without affecting the original branch.

Creating a new branch

Branch Divergence

When commits are made on different branches, the branches diverge. Each branch has its own line of history, and they can later be merged back together.

Branches diverging with independent commits

What Are Submodules?

A Git submodule is a reference to another Git repository embedded within your project. Rather than copying code, the parent repository stores a pointer to a specific commit in the submodule's repository. This means the submodule's code lives in its own repository with its own history, branches, and pull requests—but it appears as a folder in your project.

lightbulb Why Submodules?
  • check_circle Shared bug fixes: Fix a bug in the plugin once, and every project using that plugin gets the fix when they update their submodule reference.
  • check_circle No manual cherry-picking: Without submodules, you would need to manually copy changes between projects or maintain complex cherry-pick workflows.
  • check_circle Shared code stays live: The plugin code in your project is not a snapshot—it is a live link to the plugin repository, making collaboration seamless.

Submodule Status

When a submodule has changes or is pointing to a different commit than what the parent expects, git status will show the submodule as modified. The status shows the submodule folder with a special notation indicating the commit reference has changed.

Git status showing submodule changes

Working with Submodules

terminal Initialize submodules after cloning
git submodule update --init
terminal Run a command in every submodule
git submodule foreach git pull origin develop
warning Detached HEAD State

When you enter a submodule directory, you are typically in a detached HEAD state. This means HEAD points directly to a commit rather than a branch. Before making changes inside a submodule, always check out a branch first (e.g., git checkout develop) to avoid losing commits.

add_circle

Adding a Plugin to a Project

Follow these steps to add a new plugin as a Git submodule and integrate it into both the backend and frontend.

1

Get the Clone URL from Azure Repos

Navigate to the plugin repository in Azure DevOps and click the Clone button to get the HTTPS URL.

Click the Clone button

Azure DevOps Clone button

Copy the HTTPS URL

Copy clone URL button
2

Add the Submodule

Run the submodule add command from the project root, targeting the /Plugins folder.

git submodule add <CLONE_URL> Plugins/Phoenix.YourPlugin
3

Fix .gitmodules

Verify the .gitmodules file has the correct path and URL for the new submodule entry. Ensure the path matches your intended directory structure.

4

Add to Visual Studio Solution

In Visual Studio, right-click the solution and select "Add Existing Project" to include the plugin's .csproj file.

Visual Studio - Add Existing Project
5

Add Project Reference

Add a project reference from the client/host project to the plugin project so it compiles and links correctly.

Visual Studio - Add Project Reference
6

Register in Startup.cs

Add the plugin to the registration chain in Startup.cs.

builder.AddPhoenixPlugin<YourPlugin>();
7

Configure Frontend

Add the plugin to the plugins array in the project's package.json so the Remix build system includes the plugin's frontend code.

{
  "plugins": [
    "phoenix-site",
    "phoenix-payments",
    "phoenix-your-plugin"
  ]
}

Updating Submodule References

When a plugin has been updated in its own repository, you need to update the submodule reference in the parent project. Navigate into the submodule directory, pull the latest changes, then go back to the parent and commit the updated reference.

Azure Repos showing submodule commits
merge PR Workflow

When your changes span both the plugin and the host project, create separate pull requests for each repository. In the host project's PR description, include a link to the plugin's PR so reviewers understand the full scope of changes. Merge the plugin PR first, then update the submodule reference and merge the host PR.

view_list

Plugin Catalog

Hundreds of plugins are available for the Clarity platform across five categories: Core, Feature, Connector, Provider, and Build. Below is a handful of the most common plugins; many more are available to review and discuss upon request.

Plugin Category Schema Description
Phoenix.ConnectCore Core Connect Connector infrastructure, EkDB, entity reference system
Phoenix.Payments Core Payments Payment processing hub, tokenization, provider abstraction
Phoenix.Invoicing Core Invoicing Invoice management, quick-pay tokens, surcharges, aging
Phoenix.Sales Core Sales Sales collections, fulfillment tracking
Phoenix.Site Core Site Tenant/site configuration, registration
Phoenix.Products Feature Products Product catalog, import, associations
Phoenix.CMS Feature CMS Content management, block editor
Phoenix.Reporting Feature Reporting Analytics, templates, aggregation
Phoenix.Currencies Feature Currencies Multi-currency support
Phoenix.Shipping Feature Shipping Fulfillment, shipping providers
Phoenix.Taxes.Base Feature Taxes Tax calculation framework
Phoenix.Functionality Feature Additional functionality base
Phoenix.ProductUpdate Feature Product data synchronization
Phoenix.Maestro Feature Maestro AI integration
Phoenix.Connector.Netsuite Connector NetSuite NetSuite ERP integration (OAuth 2.0, 15+ pipelines)
Phoenix.Payments.Providers.Mock Provider Reference/test payment provider
Phoenix.Payments.Providers.Nuvei Provider Production payment gateway (CC + ACH)
Phoenix.RootOverlay Build Build configuration overlay

Plugin Dependency Graph

The dependency structure radiates outward from Phoenix.Core. Core plugins have direct dependencies, while feature plugins, connectors, and providers depend on both Core and the relevant core plugins.

Outer Ring — Connectors, Providers, Features
NetSuite Mock Provider Nuvei CMS Products Reporting Shipping Taxes Currencies Maestro
Inner Ring — Core Plugins
ConnectCore Payments Sales Invoicing Site
Phoenix.Core
Foundation Layer
Core
Core Plugin
Feature
Connector
Provider