Skip to main content
Version: 2.4

Customization Patterns

tSM is designed to be extended and customized at multiple levels. Depending on the complexity of the requirement, you can choose from five progressively deeper customization strategies — from pure configuration to building entirely new domain services on top of the tSM base microservice.

LevelNameTypical ActorDeployment Impact
ConfigurationConfigurator / Business AnalystNone — runtime configuration only
IntegrationConfigurator / DeveloperNone to minimal — external services or workers
UI CustomizationFrontend DeveloperFrontend build / deploy
ExtendBackend DeveloperReplaces a core microservice with a custom build
SpecializationBackend Developer / ArchitectAdds a new independently deployed microservice

1 — Configuration

The most common and recommended starting point. tSM core entities (Customer, Ticket, Order, …) are designed to be configured, not modified. No custom code is required.

What you can configure

MechanismDescriptionDocumentation
EntityTypesCreate domain-specific subtypes of a core entity. For example, define CustomerType: Retail, B2B, Wholesale — each with its own Configuration Profile (characteristics, forms, comments, attachments).Entities & Characteristics
CharacteristicsAdd dynamic attributes to any entity type using JSON Schema-based forms. E.g., add a Billing Address or SLA Level attribute to a specific Customer type without changing the core data model.Form Designer
FormsDesign entity-specific UI forms (detail screens, create dialogs, etc.) visually in the Form Designer.Form Designer
Scripts (SpEL)Write tSM Expression Language scripts that react to platform events (CustomerCreated, TicketStateChanged, …), perform validations, compute derived values, or invoke other services.tSM Expression Language
ProcessesModel business workflows visually in the Process Engine — define tasks, deadlines, SLA tracking, approvals, and automated steps.Process Engine
Lookup TablesDefine status dictionaries, lifecycle states, transitions, and other enumeration values for each entity type.Entity Type
ListingsConfigure data listings with custom filters, columns, sorting, and export.Listings
Output ManagementConfigure document templates (HTML, PDF, Word) with placeholder-driven generation.Output Management
NotificationsDefine notification rules — when to send, which template, which channel (email, SMS, push).Notifications

Example: Configuring a new Customer type

To support a new B2B customer segment, a configurator can:

  1. Create an EntityType CustomerType: B2B
  2. Define a Configuration Profile with B2B-specific characteristics (e.g., Company Registration Number, Tax ID, Contract SLA)
  3. Design a Form for the B2B customer detail screen
  4. Define a Process for B2B customer onboarding with approval steps
  5. Write a SpEL script that listens to CustomerCreated and automatically creates a default Account

All of this happens at runtime through the tSM administration UI — no build, no deployment.


2 — Integration

When you need to connect tSM with external systems or orchestrate more complex logic that goes beyond configuration scripts.

Integration mechanisms

MechanismDescriptionDirection
Integration ConnectorsPre-built connectors for common external systems (Jira, Google Chat, MS Teams, network management, public registers, …). See Integration Connectors for the full catalog.tSM ↔ External
Connection WorkerA process activity that calls an external HTTP endpoint (REST/SOAP). Configured within the Process Engine — supports request/response mapping, error handling, and retries.tSM → External
REST / SOAP Script BindingsCall external HTTP endpoints directly from SpEL scripts using the built-in REST and SOAP client bindings — no process step required. Useful for lightweight, synchronous integrations within event handlers or validation scripts.tSM → External
External TaskA process activity whose execution is handled by an external worker (a standalone service that polls for pending tasks, executes custom logic, and reports completion). Ideal for long-running or complex integrations.tSM ↔ External
Custom MicroserviceBuild a standalone microservice (in any technology — Java, Python, Node.js, …) that uses the tSM Public API and/or Kafka events to implement custom business logic. This is the most flexible integration option — it can combine multiple mechanisms (REST calls, Kafka consumption, own database) and is deployed and scaled independently from tSM.Both
Kafka ConsumerDeploy a custom service that consumes tSM events from Kafka topics (e.g., customer, order, ticket) and performs external processing.tSM → External
tSM Public APIExternal systems call tSM's RESTful API to create, read, update, or query tSM entities. Authentication via API keys or OAuth.External → tSM
MCP BindingstSM provides Model Context Protocol (MCP) bindings, allowing AI agents and LLM-based tools to interact with tSM services, query data, and execute operations programmatically.External → tSM

When to choose which

  • Connection Worker — simple request/response calls to external APIs within a process flow
  • External Task — the external logic is complex, long-running, or maintained by another team
  • Kafka Consumer — event-driven, asynchronous reaction to tSM domain events
  • Public API — the external system needs to push data into tSM or query tSM data
  • Custom Microservice — the recommended choice when the integration logic is non-trivial, combines multiple data sources, or needs its own persistence. A custom microservice can consume Kafka events, call the tSM Public API, expose its own API, and be built in any technology stack

3 — UI Customization

When the standard tSM UI components do not cover a specific requirement, custom frontend widgets can be integrated into the tSM Portal.

Supported approaches

ApproachTechnologyDescription
Custom WidgetAngular / React / Web ComponentA custom component registered in the tSM Form Designer, usable like any native tSM widget. Communicates with the host via tSM Form Runtime.
IframeAny web technologyEmbed any external web application into a tSM screen via iframe. Supports optional two-way communication via postMessage.
Menu / FrameAny web technologyRegister an external application as a dedicated menu entry in the tSM Portal (full-page frame).

Custom widgets can access the tSM context (current entity, user session, JWT token) and interact with tSM APIs. For details, see UI Integration.


4 — Extend a tSM Microservice

When configuration and integration are not sufficient — typically because you need custom business logic that must run inside the same transaction as the core entity operations, you need maximum performance (no extra network hops), or when the equivalent configuration would be too complex and a proper codebase with unit tests, compilation checks, and code review brings more maintainability.

Deep Knowledge Required

Extending a tSM microservice requires deep knowledge of the tSM internal architecture and Spring framework. Consult your tSM Implementation Team before choosing this approach.

How it works

Instead of deploying the standard core microservice (e.g., tsm-customer), you build a custom variant (e.g., my-customer) that:

  1. Includes the core tSM module as a library dependency
  2. Adds custom Spring services, event handlers, and additional logic
  3. Can override core service implementations where necessary (e.g., replace the default validation logic)

The resulting microservice is deployed in place of the original — same database, same API, same Kafka topics.

What you can do

  • Add custom Spring @Service / @Component classes with additional business logic
  • Register event handlers that react to entity lifecycle events (e.g., @EventListener(CustomerCreated.class))
  • Override a core service bean to change default behavior (e.g., custom enrichment before save)
  • Add new REST endpoints alongside the core API
  • Add new database entities and tables with relationships (links) to the core entities

Benefits

  • Performance — custom logic runs in-process, no network overhead
  • Transactional consistency — custom logic participates in the same database transaction as the core operation
  • Full access to core internals (services, repositories, domain events)

Trade-offs

  • Requires a custom build and deployment pipeline for the affected microservice
  • Upgrading to a new tSM version requires recompilation and regression testing of custom code
  • The custom code is tightly coupled to the core module's internal API

When to use

Use Extend when:

  • You need custom logic that must execute within the same transaction as core entity operations
  • You need the lowest possible latency (no extra HTTP/Kafka round-trips)
  • You want to add new entities with links to the base entities (e.g., a custom Contract entity linked to Customer)
  • The equivalent SpEL / process configuration would be too complex to maintain — a proper codebase with unit tests and compilation checks is more appropriate

5 — Specialize a tSM Base Microservice

When you want to reuse an existing tSM business module for a second, parallel domain that must be independently deployed, scaled, and evolved — sharing the same core implementation but running with its own entity types, lookup tables, Kafka topics, and database.

You Probably Don't Need This

Most projects never require Specialization. The typical scenario where it applies is when you already have a highly tuned and heavily customized module (e.g., Retail Customer handling with complex workflows, performance optimizations, and a large configuration base) and a separate business unit or implementation team now needs support for a fundamentally different domain variant (e.g., Wholesale Customers) with its own specialized requirements, release cadence, and performance profile — and they must not interfere with the core business. If a simple EntityType distinction (e.g., CustomerType: Retail vs. CustomerType: Wholesale) within the same service is sufficient, prefer Configuration instead.

Not Universally Available

This pattern is intended for business domain microservices (Customer, Order, Ticket, Inventory, …). Infrastructure and platform microservices do not support it. Not all business modules support overriding EntityType names and topic prefixes — consult the tSM Core Team to verify your use case.

How it works

Specialization combines the Extend pattern with dedicated deployment. You create a new microservice (e.g., tsm-wholesale-customer) that includes tsm-customer as a core library — exactly like in the Extend pattern — but instead of replacing the original, you deploy it alongside as a separate service with its own database and Kafka topics.

The separation between the core and specialized instance is largely driven by configuration — entity types, lookup tables, and Kafka topics are prefixed (e.g., wholesale-) to keep the two domains apart. In the simplest case you can deploy the same service image twice under different URLs with different configuration. However, because there is typically a strong business reason for the separation and the specialized domain is expected to diverge over time, we recommend combining this with the Extend pattern and building a dedicated microservice project (e.g., tsm-wholesale-customer) from the start — this gives you a place for custom logic, event handlers, and domain-specific code as the requirements grow.

What the specialized service gets from the core library

  • Base entity model (DTOs, JPA entities, mappings)
  • CRUD controller / service scaffolding
  • Validation, filtering, paging, sorting conventions
  • Security helpers, tracing, correlation
  • Shared infrastructure abstractions

What the specialized service defines on its own

  • New entity types (e.g., WholesaleCustomer, WholesaleAccount — separate from Customer, Account)
  • Own lookup tables — status dictionaries, lifecycle states, and other enumerations can evolve independently
  • Own Kafka topics — dedicated event streams (e.g., wholesale-customer)
  • Extended DTOs — e.g., WholesaleCustomerPublic extends CustomerPublic with domain-specific fields
  • Own database — complete data isolation
  • Own client library — e.g., tsm-wholesale-customer-client targeting the new service
  • Custom logic — additional Spring services, event handlers, and overrides (same as Extend)

Compatible API contract

The base API shape remains compatible — the specialized service exposes the same endpoints and base DTO structure. A WholesaleCustomerPublic is readable as a CustomerPublic (polymorphism). Domain-specific fields are additive.

Benefits

  • Complete runtime isolation — separate deployment, scaling, database, Kafka topics
  • Independent release cadence — the specialized service evolves without affecting the core module
  • Maximum reuse — the core library provides 80–90 % of the implementation, only domain-specific behavior is custom
  • Consistent APIs — clients interacting with either service see a compatible contract

Trade-offs

  • Operational overhead of managing an additional microservice
  • Core library version upgrades require recompilation (same as Extend)
  • Requires careful discipline to keep domain-specific logic out of the core library
  • Not all tSM modules support this pattern

When to use

Use Specialization when:

  • The customer requires strict runtime isolation between variants of the same domain (e.g., Retail Customers vs. Wholesale Customers, Product Orders vs. Service Orders)
  • The new domain is expected to diverge significantly in entity types, workflows, and statuses
  • You still want maximum code reuse and a consistent API across the variants

tSM UI compatibility

Because the specialized service exposes the same API contract as the core microservice, existing tSM UI widgets (listings, detail screens, form components) are compatible with the specialized variant out of the box.

The only adjustment needed is telling the widget which microservice to target. By default, a widget points to the global service (e.g., tsm-customer). For a specialized variant (e.g., tsm-wholesale-customer), the target can be configured in two ways:

  • Widget attribute — set the service base URL or service name directly on the widget instance in the Form Designer (e.g., serviceUrl: tsm-wholesale-customer)
  • Parent context derivation — the widget inherits the target service from the parent form context automatically (e.g., when a Wholesale Customer detail screen is opened, all child widgets resolve to tsm-wholesale-customer)

This means you do not need to rebuild or fork UI components — the same widget code works for both the core and specialized services.


Choosing the right level

General guidance:

If you need…Use
Custom entity types, attributes, forms, workflows, status dictionaries① Configuration
Connections to external systems (HTTP, Kafka, API)② Integration
Specialized frontend components or embedded external UIs③ UI Customization
Custom backend logic in the same transaction, or configuration is too complex④ Extend
A fully separate domain variant with own entities and database⑤ Specialization

Each level builds on the previous ones — an Extended microservice still uses Configuration (entity types, forms, processes) and can still leverage Integration mechanisms (Connection Workers, External Tasks). A Specialized service reuses the same UI widgets as the core module. The levels are not mutually exclusive.

Always start with Configuration — most business requirements can be covered without code. Escalate to higher levels only when the simpler approach is genuinely insufficient.