Skip to main content

Modifications

Modifications allow one module to change data models that originate from another module without altering the original source. The ADITO Designer records such changes as dedicated modification entries in the modifying module. These entries are stored in a folder named modification. This folder is not shown in the Designer UI but exists on the file system.

danger

Modifications on existing elements are not stable extension interfaces. Refactorings in the source module (renames/removals) can break them, and value overrides may cause unintended or invalid states across versions. Prefer supported extension interfaces (Extension Points, Services) where possible, and review all modifications of your current package after each dependency update to ensure they remain valid and do not alter module logic unintentionally.

tip

Modifications are created automatically by the ADITO Designer when you change models from dependent modules. Nevertheless, basic familiarity with these files is useful, for example, to review them in version control or to perform careful manual adjustments when necessary.

Modification Pitfalls

Child elements such as Extension Points and Service Implementations are technically also modifications, but they behave differently.

  • Extension Points and Services are explicit, stable extension interfaces provided by a module author. Extending them is intentional and supported.
  • Modifications that change existing elements (for example, renaming the title of an entity field) are not extension interfaces. They assume the targeted element will continue to exist and remain compatible.

Be aware of the following risks:

  • Refactorings in the source module (e.g., a field renamed or removed) can invalidate a modification that targets that element.
  • Modifications may overwrite values in ways not intended by the module author. A change created against module version 1 can introduce invalid states when applied to version 2 if semantics or defaults are changed.
  • Drift across versions: You may add logic (e.g., a tooltip process) to a field defined in an upstream module. In a later major version, the upstream module may introduce its own (different) implementation for that field, and in an even later version remove the field entirely, leaving your modification pointing to a non-existent target.

Recommendations:

  • Consider carefully whether a value should be changed via a modification or via a supported extension interface.
  • After every update of underlying dependencies, review all modifications that affect their data models to verify they are still correct and do not unintentionally alter module logic.
  • Use modifications sparingly. Each additional change increases coupling to the upstream model and the risk that future refactorings or removals will break behavior.
  • During dependency upgrades (especially major versions), explicitly audit for:
    • Targets that were renamed or removed
    • Upstream features that now provide official alternatives to your modifications
    • Diverging logic where your modification conflicts with new upstream behavior.

Concept

When editing models from dependent modules in the Designer, all changes are written as modifications in your own module. The original module remains unchanged. Saving is automatic when a modification is created.

Typical changes represented by modifications include:

  • Adding new elements
  • Overridden processes
  • Changed values within a data model
  • Deleted elements

Example: If you add an EntityField to an Entity that belongs to another module, the field is stored as a modification rather than being written into the Entity source.

note

Analogy: Think of modules as neatly cut wooden boards. Each modification is a physical change to a borrowed board (drilling holes, painting, attaching pieces). The more changes you apply, the less it resembles the original board and the harder it becomes to return to or reason about the original shape. Similarly, many layered modifications make it harder to understand and maintain an effective data model.

Structure of a modification

A modification consists of:

  • A folder with a unique name that contains a UUID and short context information about the change. Each modification needs to have a unique name. Older modifications may contain only the UUID.
  • One .aod file with the same base name as the folder that describes the change.
  • Optional additional artifacts (for example, a process script referenced by the modification).

During transpile, the build process:

  • Resolves all modification entries across modules,
  • Merges them into a unified dist project,
  • Applies the changes defined in the .aod files.
info

When a package of type project is deployed, a transpile is executed automatically before deployment.

Structure of a Modification Data Model

Each modification file contains the same core information.

Being able to read those files is useful for debugging and manual adjustments as well as for reviewing changes in version control.

Every modification file is structured the same. You open any modification file with a text editor (e.g., Visual Studio Code, Notepad++, etc.) and inspect its content.

360Degree-description-0585e18d-b6.aod
<?xml version="1.0" encoding="UTF-8"?>
<modification xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.2.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/modification/1.2.0">
<name>360Degree-description-0585e18d-b6</name>
<majorModelMode>DISTRIBUTED</majorModelMode>
<changeType>MODIFY</changeType>
<position v="1758876586" />
<modelType>neonContext</modelType>
<modelName>360Degree</modelName>
<path>360Degree/description</path>
<value>
<stringValueWrapper>
<name>value</name>
<value>My Description</value>
</stringValueWrapper>
</value>
</modification>
  • name: Must match the folder name and file name (without extension). If the name does not match, the modification cannot be found by the Designer and therefore cannot be applied. Each modification must have a unique name.
  • majorModelMode: Meta information used by the Designer. Use DISTRIBUTED during development, otherwise the Designer might not recognize this document.
  • changeType: Operation represented by the modification.
    • INSERT: Adds an element that did not exist before.
    • MODIFY: Changes an existing element.
    • DELETE: Removes the specified element.
  • position: Ordering hint among modifications, typically set to a timestamp value.
  • modelType: Type of the target data model.
  • modelName: Name of the target data model.
  • path: Path of the target element within the model. The path mirrors the XML structure of the element. Each segment can be either the <name> value of a node or the XML tag name itself. Some XML nodes may be omitted from the path when they are implicit (for example, the only possible child within a parent). To avoid mistakes, let the Designer create the modification and its path automatically. To fully understand the path specification, consult the original AOD document. If the path is not correct, the Transpile cannot apply the modifications.
    Example path: Memo_entity/recordContainers/db/recordFieldMappings/CONTENT.value/columnAlias
    Example source XML:
    excerpt from Memo_entity.aod
    <entity>
    <name>Memo_entity</name>
    <recordContainers>
    <dbRecordContainer>
    <name>db</name>
    <recordFieldMappings>
    <dbRecordFieldMapping>
    <name>CONTENT.value</name>
    <columnAlias>foo</columnAlias>
    </dbRecordFieldMapping>
    </recordFieldMappings>
    </dbRecordContainer>
    </recordContainers>
    </entity>
    For the above example AOD and path:
    • Memo_entity is the top-level <name> of the AOD document inside the <entity> tag.
    • recordContainers is an XML tag directly under the <entity> tag and contains a list of elements.
    • db is the <name> of an element within <recordContainers>.
    • recordFieldMappings is an XML tag under the same parent that provides the db name.
    • CONTENT.value is the <name> of an element inside <recordFieldMappings>.
    • columnAlias is the element to be changed. This final element may not exist yet. INSERT modifications add new content and therefore may target paths where the last element is not present.
  • value: The new or modified content. The content is wrapped in a value wrapper where the inner <name> is always value and the nested <value> contains the actual payload.

In the above example modification 360Degree-description-0585e18d-b6.aod, the Context 360Degree has My Description inserted as description.

note

Some wrappers may differ in its structure inside the <value> depending on the target value type.

Ordering of Elements from Modifications in any Parent Element

When inserting an element (e.g., EntityFields) originating from a Modification into a parent element (e.g., the columns/fields properties of existing ViewTemplates), they do not appear at the exact position where they were inserted.

modification-ordering-elements-origin-position.png
Figure: The field NewFieldFromModification can be placed anywhere in the columns/fields list

Instead:

  • In the client UI, all modification-derived fields are appended after all defined fields of the originating module.
  • In the Designer's columns/fields edit dialog, they initially still appear at the inserted position, but after re-opening the dialog or restarting the designer, they also move to the bottom, reflecting the actual runtime order.

modification-ordering-elements-correct-position.png
Figure: The correct position of the field NewFieldFromModification, as been seen after the dialog was re-opened

Current behavior and limitations:

  • The order of the defined columns/fields of the original module is fixed and cannot be interleaved with modification-derived fields.
  • Modification-derived fields are always placed after all originally defined fields.
  • Among multiple modification-derived fields, their relative order is determined by the Modification attribute position.
  • It is not possible to position modification-derived fields before or between originally defined fields in such dialogs as stated above.
note

This behavior is by design in the current Designer and will not be changed.

applyAllModifications-Flag

The applyAllModifications in the ADITO Designer controls whether a model incorporates modifications from dependent modules.

  • Scope: Available on major data models (Entity, View, Webservice, Context, ...) in projects.
  • Default: true

Behavior:

  • true: Applies all modifications from all modules (including dependencies) to the original model.
  • false: Applies only the base configuration from the origin module and modifications defined in the current project; ignores modifications from other modules.
note

Example: You have a module car with Car_entity. The modules foo and bar depend on car and add modifications to Car_entity. All three are included in your project. If you want to build on the original Car_entity and add your own modifications without pulling in those from foo and bar, set applyAllModifications to false. This way, only your project's modifications apply, avoiding the need to find and undo potential changes from foo and bar.