Zum Inhalt

Referenz für Agent-Authoring

Siehe auch die generierten Quellenfähigkeiten, Ziele und Exporter, Client-Operationen und strukturellen Operationen.

Ablauf zum Zusammensetzen

1. Absicht des Aufrufers erfassen

Erfasse Produkte, Anzahlen, Beziehungen, Ausgabeziele und Akzeptanzkriterien, bevor du Generatoren oder Syntax auswählst.

Warum: Der Datenvertrag des Aufrufers muss das Modell bestimmen; ein nur plausibler Descriptor genügt nicht.

Modellpfade: document.root, expectations

Regeln: validation

Kanonischer BuildRequestV4-Starter:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
  "version": "4.0",
  "document": {
    "version": "1",
    "root": {
      "kind": "setup",
      "properties": {},
      "content": null,
      "children": [
        {
          "kind": "generate",
          "properties": {
            "name": "starter_records",
            "count": "1"
          },
          "content": null,
          "children": [
            {
              "kind": "key",
              "properties": {
                "name": "value",
                "constant": "example"
              },
              "content": null,
              "children": []
            }
          ]
        }
      ]
    }
  },
  "expectations": [
    {
      "kind": "exact_count",
      "subject": {
        "kind": "product",
        "product": "starter_records"
      },
      "count": 1
    },
    {
      "kind": "fixed_value",
      "subject": {
        "kind": "product",
        "product": "starter_records"
      },
      "field": "value",
      "value": "example"
    }
  ],
  "environment_bindings": [],
  "descriptor_path": "model.xml",
  "max_count": 1,
  "sample_rows": 1
}

2. Ausführungsbasis wählen

Wähle je Top-Level-Ablauf einen registrierten DM-JSON-Node: generate für Erzeugung oder quellengestützte Transformation, iterate für reine Quelliteration und operate für eine Operation.

Warum: Der registrierte Element-Node besitzt die Ausführungssemantik; DM JSON erfindet keinen parallelen Produktmodus.

Modellpfade: document.root.children[].kind, document.root.children[].properties.count, document.root.children[].properties.traversal_count, document.root.children[].properties.traversal_limit

Regeln: limit

3. Begrenzte Quelle konfigurieren

Wähle für einen quellengestützten Node eine katalogisierte Quellfamilie, setze traversal_count oder traversal_limit und verwende nur unterstützte Distributionen und Optionen.

Warum: Quellfamilien haben unterschiedliche Verträge für Reihenfolge, Eindeutigkeit, Wiederholung, Selektoren und Parallelität.

Modellpfade: document.root.children[].properties.source, document.root.children[].properties.traversal_count, document.root.children[].properties.traversal_limit, expectations[].exact_count

Regeln: limit

4. Felder in Abhängigkeitsreihenfolge zusammensetzen

Deklariere key-, nestedKey- und reference-Nodes in Abhängigkeitsreihenfolge und nutze Skripte nur für echte Ableitungen.

Warum: Frühere Felder und Bindings bilden den Ausdruckskontext für spätere Skriptfelder.

Modellpfade: document.root.children[].children, expectations

Regeln:

5. Parent-Child-Beziehungen modellieren

Verschachtele einen generate-Node unter seinem unmittelbaren Parent und kopiere dessen Identifier mit parent.<field> oder this.parent.<field>. Nutze für mehrere gemeinsame Werte eine explizite Memstore-Lineage.

Warum: Expliziter Parent-Scope hält Produktgraphen reviewbar und ermöglicht abgeleitete Referenzprüfungen.

Modellpfade: document.root.children[].children, document.root.children[].children[].properties.script, document.root.children[].properties.source, document.root.children[].properties.target, document.root.children[].properties.converter

Regeln: foreign_key

6. Ziele und Seiteneffekte wählen

Wähle Ziel-Properties nur aus dem Capability-Katalog und halte technische Verbindungsdaten außerhalb des DM-JSON-Dokuments.

Warum: Ziele definieren extern sichtbare Seiteneffekte und verändern daher die Task-Absicht.

Modellpfade: document.root.children[].properties.target, document.root.children[].properties.export_uri

Regeln: side_effect

7. Akzeptanzerwartungen festhalten

Überführe sichtbare Invarianten in explizite Erwartungen für Anzahlen, Eindeutigkeit, Foreign Keys, erlaubte Werte, Bereiche und Datensatzbedingungen.

Warum: Erwartungen beweisen, dass die Ausgabe die Absicht bewahrt, statt lediglich zu kompilieren.

Modellpfade: expectations

Regeln: exact_count, per_parent_count, unique, foreign_key, allowed_values, range, row_condition

Compiler-validiertes Authoring-Muster:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
{
  "version": "4.0",
  "document": {
    "version": "1",
    "root": {
      "kind": "setup",
      "properties": {
        "rng_seed": 42117
      },
      "content": null,
      "children": [
        {
          "kind": "database",
          "properties": {
            "id": "fixture-db"
          },
          "content": null,
          "children": []
        },
        {
          "kind": "generate",
          "properties": {
            "name": "state_created",
            "count": "1",
            "target": "fixture-db",
            "target_entity": "state_log"
          },
          "content": null,
          "children": [
            {
              "kind": "key",
              "properties": {
                "name": "record_id",
                "constant": "record-001"
              },
              "content": null,
              "children": []
            },
            {
              "kind": "key",
              "properties": {
                "name": "state",
                "constant": "CREATED"
              },
              "content": null,
              "children": []
            }
          ]
        },
        {
          "kind": "generate",
          "properties": {
            "name": "state_processed",
            "count": "1",
            "target": "fixture-db",
            "target_entity": "state_log"
          },
          "content": null,
          "children": [
            {
              "kind": "key",
              "properties": {
                "name": "record_id",
                "constant": "record-002"
              },
              "content": null,
              "children": []
            },
            {
              "kind": "key",
              "properties": {
                "name": "state",
                "constant": "PROCESSED"
              },
              "content": null,
              "children": []
            }
          ]
        },
        {
          "kind": "generate",
          "properties": {
            "name": "state_archived",
            "count": "1",
            "target": "fixture-db",
            "target_entity": "state_log"
          },
          "content": null,
          "children": [
            {
              "kind": "key",
              "properties": {
                "name": "record_id",
                "constant": "record-003"
              },
              "content": null,
              "children": []
            },
            {
              "kind": "key",
              "properties": {
                "name": "state",
                "constant": "ARCHIVED"
              },
              "content": null,
              "children": []
            }
          ]
        }
      ]
    }
  },
  "expectations": [
    {
      "kind": "exact_count",
      "subject": {
        "kind": "declared_sink",
        "sink": {
          "kind": "database",
          "environment": "fixture-db",
          "entity": "state_log"
        }
      },
      "count": 3
    },
    {
      "kind": "unique",
      "subject": {
        "kind": "declared_sink",
        "sink": {
          "kind": "database",
          "environment": "fixture-db",
          "entity": "state_log"
        }
      },
      "field": "record_id"
    },
    {
      "kind": "allowed_values",
      "subject": {
        "kind": "declared_sink",
        "sink": {
          "kind": "database",
          "environment": "fixture-db",
          "entity": "state_log"
        }
      },
      "field": "state",
      "values": [
        "CREATED",
        "PROCESSED",
        "ARCHIVED"
      ]
    },
    {
      "kind": "unique",
      "subject": {
        "kind": "declared_sink",
        "sink": {
          "kind": "database",
          "environment": "fixture-db",
          "entity": "state_log"
        }
      },
      "field": "state"
    }
  ],
  "environment_bindings": [
    {
      "environment": "fixture-db",
      "family": "database"
    }
  ],
  "descriptor_path": "model.xml",
  "max_count": 3,
  "sample_rows": 1
}

8. Validieren, kompilieren und beweisen

Validiere DmJsonDocumentV1, kompiliere es mit dem einzigen EE-Codec zu XML, validiere dieses XML und führe anschließend begrenzte Evidenzprüfungen aus.

Warum: Jede Projektion erkennt andere Fehlerklassen; erfolgreiche JSON-Validierung allein genügt nicht.

Modellpfade: version, document, expectations, max_count, sample_rows

Regeln: validation, limit, side_effect

Vollständige Assembly-Beispiele

Deterministisches flaches Produkt zusammensetzen

Warum: Beginne hier bei einem begrenzten Produkt mit Identität und expliziten Wertebedingungen.

Wichtige Entscheidungen:

  • Ein geshuffelter Integer-Bereich mit Seed liefert begrenzte eindeutige Identifier.
  • Feldrollen kommunizieren Identität unabhängig von der Wertgenerierungsstrategie.
  • Erwartungen formulieren Anzahl, Eindeutigkeit, Vokabular und Wertebereich als ausführbaren Intent.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {
      "rng_seed": 42
    },
    "content": null,
    "children": [
      {
        "kind": "generate",
        "properties": {
          "name": "records",
          "count": "5",
          "target": "LogExporter"
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "type": "int",
              "min": "1",
              "max": "99",
              "distribution": "shuffle"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "category",
              "values": "('A', 'B', 'C')"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "score",
              "type": "int",
              "min": "10",
              "max": "20"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
5
6
7
<setup rngSeed="42">
    <generate name="records" count="5" target="LogExporter">
        <key name="id" type="int" min="1" max="99" distribution="shuffle"/>
        <key name="category" values="('A', 'B', 'C')"/>
        <key name="score" type="int" min="10" max="20"/>
    </generate>
</setup>

Regeln: exact_count, unique, allowed_values, range

Komplementäre Feldstrategien kombinieren

Warum: Verwende dieses Muster, wenn ein Produkt IDs, gewichtete Kategorien, Patterns, Bereiche und Konstanten kombiniert.

Wichtige Entscheidungen:

  • Jedes Feld wählt genau einen Eigentümer seines Werts.
  • Gewichtete Werte drücken Geschäftshäufigkeiten aus, ohne sie in einem Skript zu verstecken.
  • Patterns beschreiben die lexikalische Form; Dezimalbereiche erhalten numerische Absicht.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {
      "rng_seed": 42
    },
    "content": null,
    "children": [
      {
        "kind": "generate",
        "properties": {
          "name": "tickets",
          "count": "10"
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "type": "int",
              "min": "1",
              "max": "999",
              "distribution": "shuffle"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "priority",
              "values": "('low', 'medium', 'high')",
              "weights": "(0.6, 0.3, 0.1)"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "code",
              "pattern": "TCK-[0-9]{4}"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "handling_fee",
              "type": "float",
              "min": "0.5",
              "max": "9.99"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "channel",
              "constant": "web"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
5
6
7
8
9
<setup rngSeed="42">
    <generate name="tickets" count="10">
        <key name="id" type="int" min="1" max="999" distribution="shuffle"/>
        <key name="priority" values="('low', 'medium', 'high')" weights="(0.6, 0.3, 0.1)"/>
        <key name="code" pattern="TCK-[0-9]{4}"/>
        <key name="handling_fee" type="float" min="0.5" max="9.99"/>
        <key name="channel" constant="web"/>
    </generate>
</setup>

Regeln: unique, allowed_values, range

Parent-Child-Produktgraph zusammensetzen

Warum: Verwende dieses Muster für einstufige Kinddatensätze, deren Foreign Key jeden unmittelbaren Parent referenzieren muss.

Wichtige Entscheidungen:

  • Das Kind liegt unter dem Parent; seine Anzahl gilt daher pro Parent.
  • parent.id kopiert den Schlüssel des unmittelbaren Parents in den Kinddatensatz.
  • Foreign-Key-Rolle und Erwartungen machen die Beziehungsabsicht unabhängig prüfbar.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {
      "rng_seed": 42
    },
    "content": null,
    "children": [
      {
        "kind": "generate",
        "properties": {
          "name": "customers",
          "count": "4"
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "type": "int",
              "min": "1",
              "max": "99",
              "distribution": "shuffle"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "region",
              "values": "('north', 'south', 'east', 'west')"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "generate",
            "properties": {
              "name": "orders",
              "count": "2"
            },
            "content": null,
            "children": [
              {
                "kind": "key",
                "properties": {
                  "name": "customer_id",
                  "script": "parent.id"
                },
                "content": null,
                "children": []
              },
              {
                "kind": "key",
                "properties": {
                  "name": "amount",
                  "type": "float",
                  "min": "10",
                  "max": "500"
                },
                "content": null,
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<setup rngSeed="42">
    <generate name="customers" count="4">
        <key name="id" type="int" min="1" max="99" distribution="shuffle"/>
        <key name="region" values="('north', 'south', 'east', 'west')"/>
        <generate name="orders" count="2">
            <key name="customer_id" script="parent.id"/>
            <key name="amount" type="float" min="10" max="500"/>
        </generate>
    </generate>
</setup>

Regeln: per_parent_count, foreign_key

Generated- und Source-Produkte über Memstore verketten

Warum: Verwende dieses Muster für begrenzte mehrstufige Verarbeitung, wenn ein späteres Produkt ein früheres im selben Lauf konsumiert.

Wichtige Entscheidungen:

  • Producer-Target-ID und Consumer-Source-ID sind identisch.
  • Das Source-Produkt ist explizit begrenzt und kopiert Quellfelder über this..
  • Produktübergreifende Rollen und Erwartungen bewahren Lineage und Wertebedingungen.

Authoring-Modell:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {
      "rng_seed": 42
    },
    "content": null,
    "children": [
      {
        "kind": "generate",
        "properties": {
          "name": "users",
          "count": "5",
          "target": "mem",
          "target_entity": "users_memstore"
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "type": "int",
              "min": "100",
              "max": "999",
              "distribution": "shuffle"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "region",
              "values": "('eu', 'us', 'apac')"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "credit_limit",
              "type": "int",
              "min": "100",
              "max": "1000"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "internal_note",
              "constant": "producer-only"
            },
            "content": null,
            "children": []
          }
        ]
      },
      {
        "kind": "generate",
        "properties": {
          "name": "user_audit",
          "source": "memstore://users_memstore",
          "distribution": "ordered",
          "converter": "ProjectFields('id', 'region', 'credit_limit')",
          "traversal_count": 5
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "script": "this.id"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "region",
              "script": "this.region"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "credit_limit",
              "script": "this.credit_limit"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<setup rngSeed="42">
    <generate name="users" count="5" target="mem" targetEntity="users_memstore">
        <key name="id" type="int" min="100" max="999" distribution="shuffle"/>
        <key name="region" values="('eu', 'us', 'apac')"/>
        <key name="credit_limit" type="int" min="100" max="1000"/>
        <key name="internal_note" constant="producer-only"/>
    </generate>
    <generate name="user_audit" source="memstore://users_memstore" distribution="ordered" converter="ProjectFields('id', 'region', 'credit_limit')" count="5">
        <key name="id" script="this.id"/>
        <key name="region" script="this.region"/>
        <key name="credit_limit" script="this.credit_limit"/>
    </generate>
</setup>

Regeln: exact_count, foreign_key

Constraints an der richtigen Ausführungsgrenze platzieren

Warum: Verwende dieses Muster, wenn Quellzeilen vor dem Mapping und fertige Zeilen vor dem Export geprüft oder verändert werden müssen.

Wichtige Entscheidungen:

  • source_constraints prüfen geladene Zeilen vor der Feldverarbeitung.
  • target_constraints prüfen oder verändern den fertigen Datensatz vor dem Export.
  • Allgemeine Erwartungen bleiben getrennte Evidenzprüfungen über erfasste Ergebnisse.

Authoring-Modell:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {
      "rng_seed": 42
    },
    "content": null,
    "children": [
      {
        "kind": "generate",
        "properties": {
          "name": "source_rows",
          "count": "4",
          "target": "mem",
          "target_entity": "source_rows_mem"
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "region",
              "values": "('EU', 'US')"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "score",
              "type": "int",
              "min": "1",
              "max": "100"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "review_status",
              "constant": "clear"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "targetConstraints",
            "properties": {
              "if_rule": "score != 50",
              "require_rule": "review_status = 'required'"
            },
            "content": null,
            "children": []
          }
        ]
      },
      {
        "kind": "generate",
        "properties": {
          "name": "eu_rows",
          "source": "memstore://source_rows_mem",
          "distribution": "ordered",
          "traversal_count": 4
        },
        "content": null,
        "children": [
          {
            "kind": "sourceConstraints",
            "properties": {
              "if_rule": "region == 'EU'",
              "require_rule": "score != 0"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "region",
              "script": "this.region"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "score",
              "script": "this.score"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "review_status",
              "script": "this.review_status"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<setup rngSeed="42">
    <generate name="source_rows" count="4" target="mem" targetEntity="source_rows_mem">
        <key name="region" values="('EU', 'US')"/>
        <key name="score" type="int" min="1" max="100"/>
        <key name="review_status" constant="clear"/>
        <targetConstraints if="score != 50" require="review_status = 'required'"/>
    </generate>
    <generate name="eu_rows" source="memstore://source_rows_mem" distribution="ordered" count="4">
        <sourceConstraints if="region == 'EU'" require="score != 0"/>
        <key name="region" script="this.region"/>
        <key name="score" script="this.score"/>
        <key name="review_status" script="this.review_status"/>
    </generate>
</setup>

Regeln: exact_count, range

Deterministische Zeitreihendatensätze zusammensetzen

Warum: Verwende dieses Muster, wenn Start, Ende, Intervall und Serienanzahl die Kardinalität statt einer festen Zeilenanzahl bestimmen.

Wichtige Entscheidungen:

  • Das halboffene Fenster und Intervall bestimmen die Ticks je Serie.
  • ts.now, ts.step und ts.series stellen Iteratorzustand für Skriptfelder bereit.
  • Die Timestamp-Rolle markiert die Beobachtungszeit; Erwartungen prüfen abgeleitete Kardinalität und Werte.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {
      "rng_seed": 42
    },
    "content": null,
    "children": [
      {
        "kind": "generate",
        "properties": {
          "name": "readings",
          "count": "2",
          "start": "2026-01-01T00:00:00Z",
          "end": "2026-01-01T06:00:00Z",
          "interval": "PT1H"
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "observed_at",
              "script": "ts.now.isoformat()"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "series_id",
              "script": "f'sensor-{ts.series}'"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "step",
              "script": "ts.step"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "sensor",
              "values": "('temp', 'humidity')"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "value",
              "type": "float",
              "min": "0",
              "max": "100"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
5
6
7
8
9
<setup rngSeed="42">
    <generate name="readings" count="2" start="2026-01-01T00:00:00Z" end="2026-01-01T06:00:00Z" interval="PT1H">
        <key name="observed_at" script="ts.now.isoformat()"/>
        <key name="series_id" script="f'sensor-{ts.series}'"/>
        <key name="step" script="ts.step"/>
        <key name="sensor" values="('temp', 'humidity')"/>
        <key name="value" type="float" min="0" max="100"/>
    </generate>
</setup>

Regeln: exact_count, allowed_values, range

Die übrigen Feld-Intents kombinieren

Warum: Nutze dieses begrenzte Projekt zur Wahl zwischen Generatoren, Entity-Attributen, längenbegrenzten Strings, korrelierten Referenzen und verschachtelten Listen.

Wichtige Entscheidungen:

  • Ein Generator besitzt einen domänenspezifischen synthetischen Wert; ein Entity-Binding erhält korrelierten Entity-Zustand.
  • Eine Referenz übernimmt zwei Werte aus derselben Quellzeile, statt beide unabhängig zu ziehen.
  • nested_list besitzt eine begrenzte wiederholte Objektstruktur innerhalb jedes Profils.
data/customers.wgt.ent.csv
1
2
3
id|country|weight
100|DE|1
200|FR|1

Authoring-Modell:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {
      "rng_seed": 42
    },
    "content": null,
    "children": [
      {
        "kind": "generate",
        "properties": {
          "name": "profiles",
          "count": "2"
        },
        "content": null,
        "children": [
          {
            "kind": "variable",
            "properties": {
              "name": "_ent_person",
              "entity": "Person"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "generator": "UUIDGenerator"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "given_name",
              "script": "_ent_person.given_name"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "note",
              "type": "string",
              "min_length": 5,
              "max_length": 12
            },
            "content": null,
            "children": []
          },
          {
            "kind": "reference",
            "properties": {
              "name": "customer",
              "source": "data/customers.wgt.ent.csv",
              "weight_column": "weight",
              "distribution": "ordered"
            },
            "content": null,
            "children": [
              {
                "kind": "field",
                "properties": {
                  "target": "customer_id",
                  "source_key": "id"
                },
                "content": null,
                "children": []
              },
              {
                "kind": "field",
                "properties": {
                  "target": "customer_country",
                  "source_key": "country"
                },
                "content": null,
                "children": []
              }
            ]
          },
          {
            "kind": "nestedKey",
            "properties": {
              "name": "risk",
              "type": "dict"
            },
            "content": null,
            "children": [
              {
                "kind": "key",
                "properties": {
                  "name": "level",
                  "constant": "LOW"
                },
                "content": null,
                "children": []
              }
            ]
          },
          {
            "kind": "nestedKey",
            "properties": {
              "name": "contacts",
              "type": "list",
              "min_count": 1,
              "max_count": 1
            },
            "content": null,
            "children": [
              {
                "kind": "key",
                "properties": {
                  "name": "type",
                  "constant": "email"
                },
                "content": null,
                "children": []
              },
              {
                "kind": "key",
                "properties": {
                  "name": "address",
                  "pattern": "[a-z]{5}@example\\.com"
                },
                "content": null,
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<setup rngSeed="42">
    <generate name="profiles" count="2">
        <variable name="_ent_person" entity="Person"/>
        <key name="id" generator="UUIDGenerator"/>
        <key name="given_name" script="_ent_person.given_name"/>
        <key name="note" type="string" minLength="5" maxLength="12"/>
        <reference name="customer" source="data/customers.wgt.ent.csv" weightColumn="weight" distribution="ordered">
            <field target="customer_id" sourceKey="id"/>
            <field target="customer_country" sourceKey="country"/>
        </reference>
        <nestedKey name="risk" type="dict">
            <key name="level" constant="LOW"/>
        </nestedKey>
        <nestedKey name="contacts" type="list" minCount="1" maxCount="1">
            <key name="type" constant="email"/>
            <key name="address" pattern="[a-z]{5}@example\.com"/>
        </nestedKey>
    </generate>
</setup>

Regeln: unique

Ein endliches heterogenes Fixture über einen deklarierten Sink absichern

Warum: Nutze dieses Muster nur für ein kleines endliches Fixture mit bewusst unterschiedlichen Zeilen, die ein einzelnes deklaratives Generated-Produkt nicht ausdrücken kann.

Wichtige Entscheidungen:

  • Bevorzuge ein Produkt, wenn dessen Zeilenvariation bereits deklarativ ausdrückbar ist.
  • Nutze Singleton-Contributors nur für eine endliche Menge bewusst unterschiedlicher Fixture-Zeilen.
  • Count und Eindeutigkeit verwenden die vereinigten Zeilen des deklarierten Sinks statt eines Singleton-Produkts.
  • Der begrenzte Beweis behauptet weder Eventreihenfolge noch den Zustand einer externen Datenbank.

Authoring-Modell:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {
      "rng_seed": 42117
    },
    "content": null,
    "children": [
      {
        "kind": "database",
        "properties": {
          "id": "fixture-db"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "generate",
        "properties": {
          "name": "state_created",
          "count": "1",
          "target": "fixture-db",
          "target_entity": "state_log"
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "record_id",
              "constant": "record-001"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "state",
              "constant": "CREATED"
            },
            "content": null,
            "children": []
          }
        ]
      },
      {
        "kind": "generate",
        "properties": {
          "name": "state_processed",
          "count": "1",
          "target": "fixture-db",
          "target_entity": "state_log"
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "record_id",
              "constant": "record-002"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "state",
              "constant": "PROCESSED"
            },
            "content": null,
            "children": []
          }
        ]
      },
      {
        "kind": "generate",
        "properties": {
          "name": "state_archived",
          "count": "1",
          "target": "fixture-db",
          "target_entity": "state_log"
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "record_id",
              "constant": "record-003"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "state",
              "constant": "ARCHIVED"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<setup rngSeed="42117">
    <database id="fixture-db"/>
    <generate name="state_created" count="1" target="fixture-db" targetEntity="state_log">
        <key name="record_id" constant="record-001"/>
        <key name="state" constant="CREATED"/>
    </generate>
    <generate name="state_processed" count="1" target="fixture-db" targetEntity="state_log">
        <key name="record_id" constant="record-002"/>
        <key name="state" constant="PROCESSED"/>
    </generate>
    <generate name="state_archived" count="1" target="fixture-db" targetEntity="state_log">
        <key name="record_id" constant="record-003"/>
        <key name="state" constant="ARCHIVED"/>
    </generate>
</setup>

Regeln: exact_count, unique, allowed_values, unassured_multi_contributor_sink

Eine Projektdatei in ein Artefakt transformieren

Warum: Nutze dieses Muster für begrenzte lokale Eingaben, deren transformierte Zeilen als Datei-Artefakt entstehen sollen.

Wichtige Entscheidungen:

  • Die Endung .ent.csv deklariert eine strukturierte Projektdatei als Quelle.
  • Geordnete Auswahl und count machen den Lesevorgang begrenzt und reproduzierbar.
  • Das CSV-Target erzeugt ein Platform-verwaltetes Artefakt ohne fest codierten Storage-Pfad.
data/orders.ent.csv
1
2
3
id|status
1|new
2|paid

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {},
    "content": null,
    "children": [
      {
        "kind": "generate",
        "properties": {
          "name": "orders_export",
          "source": "file://data/orders.ent.csv",
          "target": "CSV",
          "distribution": "ordered",
          "traversal_count": 2
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "script": "this.id"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "status",
              "script": "this.status"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
5
6
<setup>
    <generate name="orders_export" source="file://data/orders.ent.csv" target="CSV" distribution="ordered" count="2">
        <key name="id" script="this.id"/>
        <key name="status" script="this.status"/>
    </generate>
</setup>

Regeln: exact_count

Eine explizite Datenbankoperation ausführen

Warum: Nutze operation ausschließlich für ein geprüftes, quellfreies clear oder MongoDB-drop.

Wichtige Entscheidungen:

  • Das Operation-Produkt hat keine Felder oder Zeilenanzahl, weil es genau eine Anweisung darstellt.
  • Das Target benennt konfigurierten Client, physische Entity und erlaubtes Verb.
  • Das externe Datenbankprofil besitzt Credentials und Seiteneffektprüfung.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {},
    "content": null,
    "children": [
      {
        "kind": "database",
        "properties": {
          "id": "orders_db"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "generate",
        "properties": {
          "name": "clear_orders",
          "target": "orders_db.clear",
          "target_entity": "orders"
        },
        "content": null,
        "children": []
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
<setup>
    <database id="orders_db"/>
    <generate name="clear_orders" target="orders_db.clear" targetEntity="orders"/>
</setup>

Regeln: side_effect

Eine begrenzte relationale Auswahl kopieren

Warum: Nutze dieses Muster, wenn Zeilen aus einer relationalen Quelle in ein explizites Datenbankziel fließen.

Wichtige Entscheidungen:

  • Getrennte Source- und Target-IDs halten Lese- und Schreibberechtigung explizit.
  • Geordnete Auswahl plus count besitzt den begrenzten Eingabevertrag.
  • Akzeptanz prüft erfasste transformierte Zeilen unabhängig vom Datenbankschreiben.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {},
    "content": null,
    "children": [
      {
        "kind": "database",
        "properties": {
          "id": "source_db"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "database",
        "properties": {
          "id": "target_db"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "generate",
        "properties": {
          "name": "orders_copy",
          "source": "database://source_db",
          "target": "target_db",
          "distribution": "ordered",
          "source_entity": "orders",
          "target_entity": "orders_copy",
          "traversal_count": 5
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "script": "this.id"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "status",
              "script": "this.status"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
5
6
7
8
<setup>
    <database id="source_db"/>
    <database id="target_db"/>
    <generate name="orders_copy" source="database://source_db" target="target_db" distribution="ordered" sourceEntity="orders" targetEntity="orders_copy" count="5">
        <key name="id" script="this.id"/>
        <key name="status" script="this.status"/>
    </generate>
</setup>

Regeln: exact_count

Eine begrenzte MongoDB-Collection projizieren

Warum: Nutze dieses Muster für eine begrenzte Collection-Auswahl, die in eine andere Collection geschrieben wird.

Wichtige Entscheidungen:

  • Die MongoDB-Quelle benennt Collection und geordnete begrenzte Traversierung.
  • Die Ziel-Collection ist statisch und insert ist explizit.
  • Clientkonfiguration und Cleanup gehören ins MongoDB-CI-Profil.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {},
    "content": null,
    "children": [
      {
        "kind": "mongodb",
        "properties": {
          "id": "mongo_in"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "mongodb",
        "properties": {
          "id": "mongo_out"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "generate",
        "properties": {
          "name": "customer_projection",
          "source": "mongodb://mongo_in",
          "target": "mongo_out",
          "distribution": "ordered",
          "source_entity": "customers",
          "target_entity": "customer_projection",
          "traversal_count": 5
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "script": "this.id"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "segment",
              "script": "this.segment"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
5
6
7
8
<setup>
    <mongodb id="mongo_in"/>
    <mongodb id="mongo_out"/>
    <generate name="customer_projection" source="mongodb://mongo_in" target="mongo_out" distribution="ordered" sourceEntity="customers" targetEntity="customer_projection" count="5">
        <key name="id" script="this.id"/>
        <key name="segment" script="this.segment"/>
    </generate>
</setup>

Regeln: exact_count

Eine begrenzte Kafka-Auswahl weiterleiten

Warum: Nutze dieses Muster, wenn eine endliche Topic-Auswahl transformiert und erneut publiziert werden soll.

Wichtige Entscheidungen:

  • Importer- und Exporter-IDs bleiben getrennte Verträge.
  • count begrenzt den Konsum; Kafka-Reihenfolge bleibt partitionslokal.
  • Das Kafka-CI-Profil besitzt Topics, Brokeradressen und Consumer-Gruppen.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {},
    "content": null,
    "children": [
      {
        "kind": "kafka-importer",
        "properties": {
          "id": "orders_in",
          "topic": "orders.created"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "kafka-exporter",
        "properties": {
          "id": "orders_out",
          "topic": "orders.generated"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "generate",
        "properties": {
          "name": "orders_forwarded",
          "source": "kafka://orders_in",
          "target": "orders_out",
          "distribution": "ordered",
          "traversal_count": 10
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "script": "this.id"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "payload",
              "script": "this.payload"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
5
6
7
8
<setup>
    <kafka-importer id="orders_in" topic="orders.created"/>
    <kafka-exporter id="orders_out" topic="orders.generated"/>
    <generate name="orders_forwarded" source="kafka://orders_in" target="orders_out" distribution="ordered" count="10">
        <key name="id" script="this.id"/>
        <key name="payload" script="this.payload"/>
    </generate>
</setup>

Regeln: exact_count

Eine begrenzte RabbitMQ-Queue weiterleiten

Warum: Nutze dieses Muster für count-begrenzten FIFO/SP-Konsum mit bestätigter Publikation.

Wichtige Entscheidungen:

  • ordered erzwingt bewusst einen Worker, um FIFO zu erhalten.
  • count besitzt die Obergrenze; eine leere Queue darf früher beenden.
  • Die Queue-Topologie bleibt brokerverwaltet und der Exporter wartet auf Confirms.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {},
    "content": null,
    "children": [
      {
        "kind": "rabbitmq-importer",
        "properties": {
          "id": "orders_in",
          "queue": "orders.created"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "rabbitmq-exporter",
        "properties": {
          "id": "orders_out",
          "exchange": "orders",
          "routing_key": "orders.generated"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "generate",
        "properties": {
          "name": "orders_forwarded",
          "source": "rabbitmq://orders_in",
          "target": "orders_out",
          "distribution": "ordered",
          "traversal_count": 10
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "script": "this.id"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "payload",
              "script": "this.payload"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
5
6
7
8
<setup>
    <rabbitmq-importer id="orders_in" queue="orders.created"/>
    <rabbitmq-exporter id="orders_out" exchange="orders" routing_key="orders.generated"/>
    <generate name="orders_forwarded" source="rabbitmq://orders_in" target="orders_out" distribution="ordered" count="10">
        <key name="id" script="this.id"/>
        <key name="payload" script="this.payload"/>
    </generate>
</setup>

Regeln: exact_count

Ein begrenztes persistiertes ML-Modell konsumieren

Warum: Nutze dieses Muster nach ml-train, wenn ein begrenztes Produkt Datensätze aus dem persistierten Modell erzeugen soll.

Wichtige Entscheidungen:

  • Der Modellname wird zur kanonischen ml://-Source-URI.
  • count begrenzt die Sample-Erzeugung; ordered ist die einzige unterstützte Source-Policy.
  • Training bleibt explizite Voraussetzung, weil Authoring keinen ml-train-Task erfindet.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {},
    "content": null,
    "children": [
      {
        "kind": "generate",
        "properties": {
          "name": "synthetic_customers",
          "source": "ml://customer_model",
          "target": "LogExporter",
          "distribution": "ordered",
          "traversal_count": 10
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "model_source",
              "constant": "customer_model"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
5
<setup>
    <generate name="synthetic_customers" source="ml://customer_model" target="LogExporter" distribution="ordered" count="10">
        <key name="model_source" constant="customer_model"/>
    </generate>
</setup>

Regeln: exact_count

Ein Objekt in ein gespeichertes Artefakt transformieren

Warum: Nutze dieses Muster, wenn Eingabe und erzeugte Datei-Artefakte hinter einem Object-Storage-Client liegen.

Wichtige Entscheidungen:

  • Die Source-URI adressiert ein Objekt über den konfigurierten Storage-Client.
  • Dieselbe Storage-ID am Datei-Target schreibt das Artefakt zurück.
  • count begrenzt den Read; das MinIO-CI-Profil besitzt Bucket-Setup und Cleanup.

Authoring-Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{
  "version": "1",
  "root": {
    "kind": "setup",
    "properties": {},
    "content": null,
    "children": [
      {
        "kind": "object-storage",
        "properties": {
          "id": "archive"
        },
        "content": null,
        "children": []
      },
      {
        "kind": "generate",
        "properties": {
          "name": "archived_orders",
          "source": "object-storage://archive",
          "target": "JSON",
          "source_uri": "incoming/orders.csv",
          "storage_id": "archive",
          "export_uri": "processed/orders",
          "distribution": "ordered",
          "traversal_count": 5
        },
        "content": null,
        "children": [
          {
            "kind": "key",
            "properties": {
              "name": "id",
              "script": "this.id"
            },
            "content": null,
            "children": []
          },
          {
            "kind": "key",
            "properties": {
              "name": "status",
              "script": "this.status"
            },
            "content": null,
            "children": []
          }
        ]
      }
    ]
  }
}

Kompilierte DSL:

1
2
3
4
5
6
7
<setup>
    <object-storage id="archive"/>
    <generate name="archived_orders" source="object-storage://archive" target="JSON" sourceUri="incoming/orders.csv" storageId="archive" exportUri="processed/orders" distribution="ordered" count="5">
        <key name="id" script="this.id"/>
        <key name="status" script="this.status"/>
    </generate>
</setup>

Regeln: exact_count

Authoring-Regeln

Regel exact_count

Die erfassten Produktdatensätze müssen genau der angeforderten Anzahl entsprechen.

Gilt für: Explizite oder abgeleitete Erwartungen an eine exakte Anzahl.

Abhilfe: Passe Produktanzahl oder Generierungsabsicht an die angeforderte Datensatzanzahl an.

Regel per_parent_count

Jeder Parent muss die angeforderte Anzahl an Kinddatensätzen besitzen.

Gilt für: Explizite oder abgeleitete Anzahlerwartungen für verschachtelte Beziehungen.

Abhilfe: Passe Kindanzahl oder Beziehungsabsicht für jeden Parent an.

Regel unique

Erfasste Werte müssen innerhalb des deklarierten Scopes eindeutig sein.

Gilt für: Explizite oder abgeleitete Unique-Erwartungen für Felder.

Abhilfe: Verwende einen Generator und Scope, der keine doppelten Feldwerte ausgeben kann.

Regel foreign_key

Erfasste Foreign-Key-Werte eines Kindes müssen erfasste Parent-Werte referenzieren.

Gilt für: Explizite oder abgeleitete Foreign-Key-Erwartungen.

Abhilfe: Korrigiere das Beziehungsfeld des Kindes, sodass jeder Schlüssel einen Parent-Datensatz referenziert.

Regel allowed_values

Erfasste Feldwerte müssen zur deklarierten erlaubten Wertemenge gehören.

Gilt für: Explizite oder abgeleitete Allowed-Values-Erwartungen.

Abhilfe: Begrenze den Feldgenerator auf die deklarierten erlaubten Werte.

Regel range

Erfasste numerische Werte müssen innerhalb des deklarierten Bereichs bleiben.

Gilt für: Explizite Bereichserwartungen.

Abhilfe: Passe Feldbereich oder Generatorgrenzen an die Erwartung an.

Regel fixed_value

Jeder erfasste Feldwert muss dem deklarierten festen Wert entsprechen.

Gilt für: Explizite Fixed-Value-Erwartungen.

Abhilfe: Verwende ein konstantes Feld oder passe den erwarteten Wert an.

Regel field_present

Jeder erfasste Datensatz muss das deklarierte Feld enthalten.

Gilt für: Explizite Pflichtfeld-Erwartungen.

Abhilfe: Deklariere und befülle das Pflichtfeld in jedem Datensatz.

Regel field_absent

Kein erfasster Datensatz darf das deklarierte Feld enthalten.

Gilt für: Explizite Verbotsfeld-Erwartungen.

Abhilfe: Entferne das verbotene Feld aus dem Produktmodell.

Regel row_condition

Jeder erfasste Datensatz muss seine deklarierte Bedingung erfüllen.

Gilt für: Explizite Erwartungen an Datensatzbedingungen.

Abhilfe: Ändere Bedingung oder Generierungsabsicht, sodass jeder Datensatz sie erfüllt.

Regel unassured_multi_contributor_sink

Mehrere Produkte teilen sich eine deklarierte Senke ohne senkenspezifische Zusicherung.

Gilt für: Unterstützte deklarierte Insert-Senken mit mehr als einem beitragenden Produkt.

Abhilfe: Ergänze eine Erwartung, deren Subject die deklarierte Senke und die benötigte Regel benennt.

Regel unevaluable_sink_expectation

Eine Senken-Erwartung benötigt die vollständige begrenzte Erfassung aller beitragenden Produkte.

Gilt für: Explizite Erwartungen über die Vereinigung einer deklarierten Senke.

Abhilfe: Stelle sicher, dass alle Beiträge zur deklarierten Senke vor der Auswertung erfasst werden.

Regel limit

Begrenzte Ausführung muss unbegrenzte oder übermäßige Expansion vor der Ausführung ablehnen.

Gilt für: Anzahlen, Prozesse, verschachtelte Expansion und quellengesteuerte Authoring-Ausführung.

Abhilfe: Verwende literale Anzahlen innerhalb des konfigurierten Maximums und einen Prozess für begrenzte Authoring-Evidenz.

Regel side_effect

Dry-Run-Ausführung muss schreibfähige Descriptor-Elemente ablehnen.

Gilt für: Begrenzte Ausführung mit deaktivierten Seiteneffekten.

Abhilfe: Verwende run mit expliziter Seiteneffektfreigabe oder entferne schreibfähige Elemente.

Regel input

Authoring-Befehle benötigen eine zur gewählten typisierten Operation passende Eingabe.

Gilt für: Applikationsanfragen mit fehlender oder ungültiger DM-JSON-, Build- oder XML-Eingabe.

Abhilfe: Stelle den vollständigen typisierten Payload über den deklarierten Eingabekanal der gewählten Operation bereit.

Regel validation

Authoring-Payloads müssen den versionierten DmJsonDocumentV1- oder BuildRequestV4-Vertrag erfüllen.

Gilt für: Validierung von DM-JSON- und Build-Payloads.

Abhilfe: Korrigiere das gemeldete Feld, den Diskriminator oder die Graphreferenz.

Regel include

Begrenzte Authoring-Prüfung lehnt jedes Include ab, weil die Eingrenzung der Projektabhängigkeiten nicht nachgewiesen ist.

Gilt für: Relative, verschachtelte und bedingte Include-Elemente in der begrenzten Authoring-Prüfung.

Abhilfe: Bette den vollständigen Abhängigkeitsgraphen vor der begrenzten Prüfung ein und validiere ihn. Die vollständige Include-Ausführung bleibt unverfügbar, bis Workspace-Eingrenzung und Abhängigkeitskonsistenz nachgewiesen sind.

Regel unsupported_bounded_operation

Begrenzte Authoring-Prüfung lehnt Operationen ohne begrenzten Evidenzmodus ab.

Gilt für: Laufzeitoperationen wie Modelltraining und Artefakterzeugung.

Abhilfe: Entferne die Operation aus der begrenzten Authoring-Prüfung und validiere sie über ihren dedizierten Laufzeitablauf.

Runtime-Fehlerregeln