<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Entwickler on dsyr.DataBridge</title><link>https://databridge.docs.dsyr.de/themen/entwickler/</link><description>Recent content in Entwickler on dsyr.DataBridge</description><generator>Hugo</generator><language>de</language><atom:link href="https://databridge.docs.dsyr.de/themen/entwickler/index.xml" rel="self" type="application/rss+xml"/><item><title>Architektur im Detail</title><link>https://databridge.docs.dsyr.de/entwicklung/architektur/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/architektur/</guid><description>&lt;p&gt;Dieser Abschnitt beschreibt die dsyr.DataBridge so detailliert, dass sie ohne Lesen des&#10;Quellcodes verstanden werden kann. Er richtet sich an &lt;strong&gt;Entwickler&lt;/strong&gt;, die Connectoren,&#10;Resolver oder Services erweitern, und an technische Reviewer.&lt;/p&gt;&#10;&lt;p&gt;Die Übersicht für Administratoren steht unter&#10;&lt;a href="https://databridge.docs.dsyr.de/docs/ueberblick/architektur/"&gt;Dokumentation → Überblick → Architektur&lt;/a&gt;. Dort sind&#10;C4-Diagramme, Queue-Struktur und Connector-Hierarchie beschrieben. Die Seiten hier setzen&#10;darauf auf und gehen eine Ebene tiefer: Sequenzdiagramme, Bicep-Module, DI-Verdrahtung,&#10;Request- und Nachrichten-Schemata.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Seite&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Inhalt&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/architektur/systemkontext/"&gt;Systemkontext und Prinzipien&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Zweck, Hauptfunktionen, Architekturprinzipien, Phasen, Betriebs- und Skalierungsmodell&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/architektur/infrastruktur/"&gt;Infrastruktur (Bicep)&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Module, Ressourcen, App-Settings, Rollen, Alerts, Marketplace-Artefakte&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/architektur/anwendung/"&gt;Anwendungsarchitektur&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Projekte, DI, &lt;code&gt;host.json&lt;/code&gt;, Functions, Services, Connector-Basisklassen, Transformations-Pipeline, Domänenobjekte&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/architektur/api-referenz/"&gt;API- und Nachrichten-Referenz&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP-Endpunkte mit Request/Response, Trigger-Bindungen, Service-Bus-Nachrichtenschema, Fehlerverhalten&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/architektur/datenfluesse/"&gt;Datenflüsse&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Sequenzdiagramme für Erkennung, Verarbeitung, Response-Jobs, Fehlerpfad; Persistenz; Watermark-Logik&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/architektur/abhaengigkeiten/"&gt;Abhängigkeiten&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Projekt- und Azure-Abhängigkeiten, externe Systeme, architekturkritische Kopplungen&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/architektur/capabilities/"&gt;Fähigkeiten-Katalog&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Alle Fähigkeiten mit ihrer technischen Umsetzung&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="alert alert-info" role="alert"&gt;&lt;div class="h4 alert-heading" role="heading"&gt;Stand&lt;/div&gt;&#10;&lt;p&gt;Die Inhalte entsprechen dem Code-Stand von &lt;strong&gt;Version 2.3&lt;/strong&gt;. Quellen sind &lt;code&gt;src/&lt;/code&gt;, &lt;code&gt;bicep/&lt;/code&gt;&#10;und &lt;code&gt;cicd/&lt;/code&gt; im Repository. Wo eine Aussage eine Annahme ist, steht das im Text.&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title>Gegen Podman debuggen</title><link>https://databridge.docs.dsyr.de/entwicklung/debuggen/podman/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/debuggen/podman/</guid><description>&lt;p&gt;Voraussetzung ist die &lt;a href="../../lokale-testumgebung/"&gt;Podman-Testumgebung&lt;/a&gt;. Der &lt;code&gt;databridge&lt;/code&gt;-Container&#10;würde sonst Port 7062 belegen, deshalb startet &lt;code&gt;up.sh&lt;/code&gt;/&lt;code&gt;up.ps1&lt;/code&gt; alles außer der DataBridge selbst:&lt;/p&gt;&#10;&#10;&#10;&#10;&lt;ul class="nav nav-tabs" id="tabs-0" role="tablist"&gt;&#10; &lt;li class="nav-item"&gt;&#10; &lt;button class="nav-link active"&#10; id="tabs-00-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-00" role="tab"&#10; data-td-tp-persist="windows (powershell)" aria-controls="tabs-00-00" aria-selected="true"&gt;&#10; Windows (PowerShell)&#10; &lt;/button&gt;&#10; &lt;/li&gt;&lt;li class="nav-item"&gt;&#10; &lt;button class="nav-link"&#10; id="tabs-00-01-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-01" role="tab"&#10; data-td-tp-persist="linux / macos" aria-controls="tabs-00-01" aria-selected="false"&gt;&#10; Linux / macOS&#10; &lt;/button&gt;&#10; &lt;/li&gt;&#10;&lt;/ul&gt;&#10;&#10;&lt;div class="tab-content" id="tabs-0-content"&gt;&#10; &lt;div class="tab-body tab-pane fade show active"&#10; id="tabs-00-00" role="tabpanel" aria-labelled-by="tabs-00-00-tab" tabindex="0"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dev\up.ps1 -HostMode mssql &lt;span style="color:#66d9ef"&gt;process&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="tab-body tab-pane fade"&#10; id="tabs-00-01" role="tabpanel" aria-labelled-by="tabs-00-01-tab" tabindex="0"&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dev/up.sh --host mssql process&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;p&gt;&lt;code&gt;--host&lt;/code&gt; (bzw. &lt;code&gt;-HostMode&lt;/code&gt;) lässt sich mit allen anderen Argumenten kombinieren (Datenbanken,&#10;Mocks, &lt;code&gt;getchanges&lt;/code&gt;, &lt;code&gt;process&lt;/code&gt;, &lt;code&gt;servicebus&lt;/code&gt;) und startet alles außer dem &lt;code&gt;databridge&lt;/code&gt;-Container&#10;selbst (dafür gibt es das Profil &lt;code&gt;databridge&lt;/code&gt;, das sonst automatisch aktiv ist). Der Befehl&#10;generiert zusätzlich&#10;&lt;code&gt;src/DataBridge/local.settings.json&lt;/code&gt; aus der Vorlage &lt;code&gt;dev/local.settings.dev.json&lt;/code&gt; (Azurite über&#10;&lt;code&gt;UseDevelopmentStorage=true&lt;/code&gt;, Service-Bus-Emulator über &lt;code&gt;localhost&lt;/code&gt; statt über den&#10;Compose-Servicenamen &lt;code&gt;servicebus&lt;/code&gt;, sowie die Toggles aus &lt;code&gt;dev/.env&lt;/code&gt;, siehe&#10;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/debuggen/podman/#getchangesprocessqueueitems-steuern"&gt;GetChanges/Process*QueueItems steuern&lt;/a&gt;).&lt;/p&gt;</description></item><item><title>Systemkontext und Prinzipien</title><link>https://databridge.docs.dsyr.de/entwicklung/architektur/systemkontext/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/architektur/systemkontext/</guid><description>&lt;h2 id="zweck"&gt;Zweck&lt;/h2&gt;&#10;&lt;p&gt;Die dsyr.DataBridge ist eine serverlose &lt;strong&gt;Datenintegrations-Bridge&lt;/strong&gt; auf Azure Functions&#10;(.NET 10, Isolated Worker). Sie synchronisiert Datensätze nahezu in Echtzeit zwischen&#10;heterogenen Geschäftssystemen, ohne diese direkt zu koppeln. Quelle und Ziel sind über&#10;&lt;strong&gt;Azure Service Bus&lt;/strong&gt; entkoppelt, Änderungen werden über Watermarks change-getrieben&#10;übertragen.&lt;/p&gt;&#10;&lt;p&gt;Die Bridge hält &lt;strong&gt;keine Fachdaten&lt;/strong&gt; dauerhaft. Sie speichert nur Konfiguration und&#10;Synchronisationsstände in Azure Table Storage; Nachrichten liegen transient im Service Bus.&lt;/p&gt;&#10;&lt;h2 id="hauptfunktionen"&gt;Hauptfunktionen&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Funktion&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Beschreibung&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Change Detection&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Periodisches Pollen der Quellsysteme (Timer &lt;code&gt;GetChanges&lt;/code&gt;, optional Durable-Orchestrierung)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Asynchrone Entkopplung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Erkannte Änderungen landen als Nachrichten in priorisierten Queues (Low / Standard / High)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Feld-Mapping und Transformation&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Konfigurierbare Zuordnung inkl. Typ-Coercion, Default-Werten, Option-Mapping, Lookups, Source-/Target-Operationen&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Multi-System-Konnektivität&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;D365 BC, CE/Dataverse, NAV, generische REST-APIs über OpenAPI-Spezifikation, SQL-Datenbanken (MSSQL, PostgreSQL, MySQL, Oracle)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Idempotente Zielverarbeitung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Upsert/Delete über Primär-, Custom- oder Filter-Keys, mehrere Schlüssel mit Rangfolge&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Aktions-Jobs&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;InvokeAction&lt;/code&gt; ruft benannte Nicht-CRUD-Endpunkte auf (OpenAPI &lt;code&gt;operationId&lt;/code&gt;, CE &lt;code&gt;OrganizationRequest&lt;/code&gt;)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Watermarking&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Persistierter Stand pro Job, nur neue Änderungen werden übertragen&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Response-Jobs&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Rückschreiben von im Ziel erzeugten Schlüsseln in die Quelle&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Diagnose und KI-Anbindung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP-Endpunkte (&lt;code&gt;CheckList&lt;/code&gt;, &lt;code&gt;Validate&lt;/code&gt;, &lt;code&gt;JobApi&lt;/code&gt;, &lt;code&gt;MappingApi&lt;/code&gt;) und ein read-only MCP-Server&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Selektive Telemetrie&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Gepuffertes Logging pro Invocation, Dependency-Sampling, pre-aggregierte Custom Metrics&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Fehlerresilienz&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Backoff-Retry, Transitive-Queues, Dead-Letter-Queues, Alerts&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="zielgruppen"&gt;Zielgruppen&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Zielgruppe&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Nutzen&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Integrations-/ERP-Berater&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Konfigurieren Connections, Jobs und Mappings in Table Storage, ohne Code zu deployen&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cloud-/DevOps-Engineers&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Deployen via Bicep oder Marketplace, betreiben und überwachen die Function App&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Entwickler&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Erweitern Connectoren, Resolver und Source-Operationen in &lt;code&gt;DataBridge.Core&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;KI-Assistenten&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Lesen Konfiguration und Queue-Zustand über den MCP-Server&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="architekturprinzipien"&gt;Architekturprinzipien&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Prinzip&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Umsetzung&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Separation of Concerns&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Host (Trigger) ↔ Core (Logik) ↔ Connectoren (System-Anbindung) ↔ Resolver/Mapper (Transformation)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Configuration over Code&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Connections, Jobs, Mappings, Watermarks liegen in Table Storage&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Lazy Initialization&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Services sind DI-Singletons; die Konfiguration wird einmalig und thread-sicher beim ersten Aufruf geladen&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Asynchrone Entkopplung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Service Bus zwischen Lese- und Schreibseite; jede Nachricht wird isoliert verarbeitet&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Idempotenz&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Upsert/Delete über definierte Target-Keys&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Resilienz&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Backoff, Lock-Renewal, Transitive-Queues, Dead-Letter-Queues, &lt;code&gt;DeadLetterMover&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Erweiterbarkeit&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Source-Operation-Handler werden per Reflection registriert; Connectoren über &lt;code&gt;ConnectionTypes&lt;/code&gt; gemappt; Resolver-Registries je Connector als statische &lt;code&gt;FrozenDictionary&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Observability first&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Gepuffertes Logging, Requests und Exceptions nie gesampelt, Custom Metrics ohne Sampling&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="die-zwei-phasen"&gt;Die zwei Phasen&lt;/h2&gt;&#10;&lt;pre class="mermaid"&gt;flowchart LR&#10; SRC[&amp;#34;Quellsystem&amp;#34;] --&amp;gt;|&amp;#34;1. Erkennung (Pull)&amp;#34;| FUNC1[&amp;#34;GetChanges&amp;lt;br/&amp;gt;oder Orchestrator &amp;#43; Activity&amp;#34;]&#10; FUNC1 --&amp;gt;|&amp;#34;QueueMessage&amp;#34;| SB[(&amp;#34;Service Bus&amp;lt;br/&amp;gt;Low / Standard / High&amp;#34;)]&#10; SB --&amp;gt;|&amp;#34;2. Verarbeitung (Push)&amp;#34;| FUNC2[&amp;#34;Process*QueueItems&amp;#34;]&#10; FUNC2 --&amp;gt;|&amp;#34;Upsert / Delete / Action&amp;#34;| TGT[&amp;#34;Zielsystem&amp;#34;]&#10; FUNC1 -.-&amp;gt;|&amp;#34;Watermark&amp;#34;| WM[(&amp;#34;watermark&amp;#34;)]&#10; FUNC2 -.-&amp;gt;|&amp;#34;Response-Job / Transitive / Ignored&amp;#34;| SB&lt;/pre&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Erkennung:&lt;/strong&gt; &lt;code&gt;GetChanges&lt;/code&gt; (Timer) liest Änderungen aus den Quellsystemen und&#10;enqueued sie. Die Durable-Orchestrierung ist eine Alternative, die nur per HTTP&#10;gestartet wird und im Regelbetrieb nicht läuft.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Verarbeitung:&lt;/strong&gt; Drei Service-Bus-Trigger (je Priorität) dequeuen und schreiben ins&#10;Zielsystem.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Diese Entkopplung erlaubt unabhängige Skalierung beider Seiten und überbrückt temporäre&#10;Ausfälle des Zielsystems. Details in &lt;a href="../datenfluesse/"&gt;Datenflüsse&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Gegen echtes Azure debuggen</title><link>https://databridge.docs.dsyr.de/entwicklung/debuggen/cloud/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/debuggen/cloud/</guid><description>&lt;p&gt;Hier läuft kein Podman-Stack mit — die lokal gestartete DataBridge verbindet sich direkt mit einem&#10;echten Storage Account, einem echten Service Bus Namespace und den echten Quell-/Zielsystemen (BC,&#10;CE, NAV, SQL). Das ist der klassische Weg, um ein Problem aus einer konkreten Umgebung&#10;(z. B. &lt;code&gt;dsyr-wysatest&lt;/code&gt;) lokal nachzuvollziehen oder mit dem Debugger zu untersuchen.&lt;/p&gt;&#10;&lt;h2 id="localsettingsjson-vorbereiten"&gt;&lt;code&gt;local.settings.json&lt;/code&gt; vorbereiten&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;code&gt;src/DataBridge/sample.local.settings.json&lt;/code&gt; nach &lt;code&gt;src/DataBridge/local.settings.json&lt;/code&gt; kopieren&#10;(falls noch nicht vorhanden — die Datei ist in &lt;code&gt;.gitignore&lt;/code&gt;, geht also nicht versehentlich in&#10;einen Commit).&lt;/li&gt;&#10;&lt;li&gt;Die Platzhalter durch echte Werte aus dem Azure Portal bzw. Key Vault ersetzen:&#10;&lt;code&gt;AzureWebJobsStorage&lt;/code&gt; (Storage-Account-Connection-String), &lt;code&gt;ExportQueueServiceBus&lt;/code&gt;&#10;(Service-Bus-Connection-String) sowie die Connection-Strings/Secrets der Quell- und&#10;Zielsysteme, je nachdem was getestet werden soll. &lt;strong&gt;Diese Werte niemals committen&lt;/strong&gt; und nicht in&#10;Chats/Tickets einfügen.&lt;/li&gt;&#10;&lt;li&gt;Wenn &lt;code&gt;enableManagedIdentity&lt;/code&gt; in der Zielumgebung aktiv ist (siehe&#10;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/architektur/"&gt;Identity-Verbindungen&lt;/a&gt; bzw. &lt;code&gt;SettingsService&lt;/code&gt;), fehlen dort&#10;Connection-Strings ganz — stattdessen &lt;code&gt;AzureWebJobsStorage__accountName&lt;/code&gt; und&#10;&lt;code&gt;ExportQueueServiceBus__fullyQualifiedNamespace&lt;/code&gt; setzen und lokal per &lt;code&gt;az login&lt;/code&gt; angemeldet&#10;sein, damit &lt;code&gt;DefaultAzureCredential&lt;/code&gt; greift. Das erfordert eine Rollenzuweisung für den&#10;eigenen Benutzer auf Storage und Service Bus (Data-Rollen, nicht nur Management), sonst schlägt&#10;der Verbindungstest beim Start fehl.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="alert alert-warning" role="alert"&gt;&lt;div class="h4 alert-heading" role="heading"&gt;Podman überschreibt dieselbe Datei&lt;/div&gt;&#10;&lt;p&gt;&lt;code&gt;src/DataBridge/local.settings.json&lt;/code&gt; ist die &lt;strong&gt;einzige&lt;/strong&gt; Datei, aus der sowohl der Podman-Host-Modus&#10;als auch dieses Cloud-Setup lesen — es gibt keine zweite, von der Function-Runtime automatisch&#10;erkannte Datei. Läuft danach &lt;code&gt;dev/up.sh --host&lt;/code&gt;/&lt;code&gt;dev\up.ps1 -HostMode&lt;/code&gt; (siehe&#10;&lt;a href="../podman/"&gt;Debuggen → Gegen Podman&lt;/a&gt;), wird die Datei &lt;strong&gt;kommentarlos überschrieben&lt;/strong&gt; und die&#10;gerade eingetragenen echten Zugangsdaten sind weg. Wer beides abwechselnd nutzt, siehe&#10;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/debuggen/cloud/#podman--und-cloud-settings-parallel-halten"&gt;Podman- und Cloud-Settings parallel halten&lt;/a&gt; weiter&#10;unten.&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title>Infrastruktur (Bicep)</title><link>https://databridge.docs.dsyr.de/entwicklung/architektur/infrastruktur/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/architektur/infrastruktur/</guid><description>&lt;p&gt;Einstiegspunkt ist &lt;code&gt;bicep/main.bicep&lt;/code&gt;. Das Deployment läuft im Scope einer bestehenden&#10;Resource Group (Bicep-Default, kein explizites &lt;code&gt;targetScope&lt;/code&gt;), im Modus Incremental.&#10;Die Parameter aus Anwendersicht sind unter&#10;&lt;a href="https://databridge.docs.dsyr.de/docs/einrichtung/installation/"&gt;Installation&lt;/a&gt; beschrieben; hier geht es um den inneren&#10;Aufbau.&lt;/p&gt;&#10;&lt;h2 id="module-und-parameterfluss"&gt;Module und Parameterfluss&lt;/h2&gt;&#10;&lt;pre class="mermaid"&gt;flowchart TD&#10; MAIN[&amp;#34;main.bicep&amp;#34;]&#10;&#10; SA[&amp;#34;storageaccount.bicep&amp;#34;]&#10; AI[&amp;#34;applicationinsights.bicep&amp;#34;]&#10; ASP[&amp;#34;appserviceplan.bicep&amp;#34;]&#10; SB[&amp;#34;servicebus.bicep&amp;#34;]&#10; ALERT[&amp;#34;metricalerts.bicep&amp;lt;br/&amp;gt;if enableAlerts&amp;#34;]&#10; DASH[&amp;#34;dashboard.bicep&amp;lt;br/&amp;gt;if enableGrafanaDashboard&amp;#34;]&#10; FUNC[&amp;#34;azurefunction.bicep&amp;#34;]&#10; ROLES[&amp;#34;roleassignments.bicep&amp;lt;br/&amp;gt;if enableManagedIdentity&amp;#34;]&#10;&#10; MAIN --&amp;gt; SA &amp;amp; AI &amp;amp; ASP &amp;amp; SB &amp;amp; ALERT &amp;amp; DASH &amp;amp; FUNC &amp;amp; ROLES&#10;&#10; SA --&amp;gt;|&amp;#34;id, name&amp;#34;| FUNC&#10; AI --&amp;gt;|&amp;#34;connectionString, id&amp;#34;| FUNC&#10; AI --&amp;gt;|&amp;#34;id&amp;#34;| DASH&#10; ASP --&amp;gt;|&amp;#34;id&amp;#34;| FUNC&#10; SB --&amp;gt;|&amp;#34;authorizationRuleId, name&amp;#34;| FUNC&#10; SB --&amp;gt;|&amp;#34;id&amp;#34;| ALERT&#10; FUNC --&amp;gt;|&amp;#34;principalId&amp;#34;| ROLES&#10; SA --&amp;gt;|&amp;#34;id&amp;#34;| ROLES&#10; SB --&amp;gt;|&amp;#34;id&amp;#34;| ROLES&lt;/pre&gt;&#10;&lt;p&gt;Die Abhängigkeiten ergeben sich über Modul-Outputs, es gibt keine Zyklen. Zusätzlich legt&#10;&lt;code&gt;main.bicep&lt;/code&gt; ein leeres Tracking-Deployment für die Microsoft-Partner-Attribution an.&lt;/p&gt;</description></item><item><title>MCP für die Testumgebung</title><link>https://databridge.docs.dsyr.de/entwicklung/mcp-testumgebung/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/mcp-testumgebung/</guid><description>&lt;p&gt;Die DataBridge in der &lt;a href="../lokale-testumgebung/"&gt;Podman-Testumgebung&lt;/a&gt; bringt denselben&#10;&lt;a href="https://databridge.docs.dsyr.de/docs/mcp-server/"&gt;MCP-Server&lt;/a&gt; mit wie jede andere Instanz. Damit kann ein KI-Assistent die&#10;Beispiel-Jobs und -Mappings lesen und die Metadaten der Testdatenbanken abfragen, ohne dass&#10;dafür etwas in Azure laufen muss.&lt;/p&gt;&#10;&lt;h2 id="zwei-server-nebeneinander"&gt;Zwei Server nebeneinander&lt;/h2&gt;&#10;&lt;p&gt;Die &lt;code&gt;.mcp.json&lt;/code&gt; im Repository definiert zwei DataBridge-Server:&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Server&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Ziel&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;URL&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;databridge&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Eine Azure-Instanz (bzw. ohne Konfiguration der lokale Host)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;${DATABRIDGE_MCP_URL:-http://localhost:7062}/api/mcp?code=${DATABRIDGE_FUNCTION_KEY:-local}&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;databridge-dev&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Die Podman-Testumgebung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;http://localhost:7062/api/mcp?code=local&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;mcpServers&amp;#34;&lt;/span&gt;: {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;databridge&amp;#34;&lt;/span&gt;: {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;http&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;${DATABRIDGE_MCP_URL:-http://localhost:7062}/api/mcp?code=${DATABRIDGE_FUNCTION_KEY:-local}&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;databridge-dev&amp;#34;&lt;/span&gt;: {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;http&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;http://localhost:7062/api/mcp?code=local&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;databridge&lt;/code&gt; zeigt auf eine Azure-Instanz, sobald &lt;code&gt;DATABRIDGE_MCP_URL&lt;/code&gt; und&#10;&lt;code&gt;DATABRIDGE_FUNCTION_KEY&lt;/code&gt; gesetzt sind — üblicherweise im Block &lt;code&gt;env&lt;/code&gt; der persönlichen&#10;&lt;code&gt;.claude/settings.local.json&lt;/code&gt; (siehe &lt;a href="https://databridge.docs.dsyr.de/docs/mcp-server/nutzung/"&gt;MCP-Server → Nutzung&lt;/a&gt;).&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;databridge-dev&lt;/code&gt; zeigt immer auf die Testumgebung. Der Function Key ist dort fest auf &lt;code&gt;local&lt;/code&gt;&#10;gesetzt (&lt;code&gt;dev/functions-secrets/host.json&lt;/code&gt;), es muss also nichts konfiguriert werden.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;In Claude Code erscheinen die Tools entsprechend mit den Präfixen &lt;code&gt;mcp__databridge__…&lt;/code&gt; und&#10;&lt;code&gt;mcp__databridge-dev__…&lt;/code&gt;. Im Prompt genügt es zu sagen, welcher Server gemeint ist, z. B. „frag&#10;über databridge-dev die Tabellen von oracle-dev ab“.&lt;/p&gt;</description></item><item><title>Anwendungsarchitektur</title><link>https://databridge.docs.dsyr.de/entwicklung/architektur/anwendung/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/architektur/anwendung/</guid><description>&lt;h2 id="projekte-srcdatabridgeslnx"&gt;Projekte (&lt;code&gt;src/DataBridge.slnx&lt;/code&gt;)&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Projekt&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Typ&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Zweck&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;DataBridge&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Azure Functions, net10.0, isolated&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Host: Trigger, DI, Telemetrie-Bootstrap, Durable Functions, MCP-Endpunkt&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;DataBridge.Core&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Class Library&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Services, Connectoren, Resolver, Mapper, Source-Operationen, Modelle, Telemetrie&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;DataBridge.Test&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;xUnit v3 + Moq (Microsoft Testing Platform)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Unit-Tests; Ordnerstruktur spiegelt &lt;code&gt;DataBridge.Core&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;DeadLetterMover&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Konsolenanwendung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Requeue von Dead-Letter-Nachrichten&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="dependency-injection-programcs"&gt;Dependency Injection (&lt;code&gt;Program.cs&lt;/code&gt;)&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;FunctionsApplication.CreateBuilder(args)&lt;/code&gt; (moderner Einstiegspunkt statt &lt;code&gt;new HostBuilder()&lt;/code&gt;),&#10;mit &lt;code&gt;builder.UseMiddleware&amp;lt;InvocationContextMiddleware&amp;gt;()&lt;/code&gt;, die jede Invocation in einen&#10;&lt;code&gt;InvocationContext&lt;/code&gt; einbettet und am Ende das gepufferte Log flusht.&lt;/li&gt;&#10;&lt;li&gt;Application Insights über &lt;code&gt;AddApplicationInsightsTelemetryWorkerService&lt;/code&gt;, Adaptive&#10;Sampling &lt;strong&gt;deaktiviert&lt;/strong&gt;; &lt;code&gt;DependencySamplingProcessor&lt;/code&gt; per&#10;&lt;code&gt;AddApplicationInsightsTelemetryProcessor&lt;/code&gt;. Der Standard-AI-Logger-Provider ist auf&#10;&lt;code&gt;LogLevel.None&lt;/code&gt; gesetzt, einziger Pfad nach AI ist der &lt;code&gt;BufferingLoggerProvider&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Alle Services sind &lt;strong&gt;Singletons&lt;/strong&gt;: &lt;code&gt;MetricsService&lt;/code&gt;, &lt;code&gt;SettingsService&lt;/code&gt;, &lt;code&gt;StorageService&lt;/code&gt;,&#10;&lt;code&gt;ConnectionService&lt;/code&gt;, &lt;code&gt;MappingService&lt;/code&gt;, &lt;code&gt;JobService&lt;/code&gt;, &lt;code&gt;WatermarkService&lt;/code&gt;,&#10;&lt;code&gt;ServiceBusService&lt;/code&gt;, &lt;code&gt;ProcessQueueMessageService&lt;/code&gt;,&#10;&lt;code&gt;ProcessJobsForRetrievalInOrderService&lt;/code&gt;, &lt;code&gt;CheckListService&lt;/code&gt;, &lt;code&gt;InitializationService&lt;/code&gt;,&#10;&lt;code&gt;McpToolService&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Log-Level: Kategorien &lt;code&gt;DataBridge&lt;/code&gt; und &lt;code&gt;Function&lt;/code&gt; auf &lt;code&gt;Trace&lt;/code&gt;, der Puffer-Provider&#10;filtert auf &lt;code&gt;Debug&lt;/code&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="hostjson"&gt;&lt;code&gt;host.json&lt;/code&gt;&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Bereich&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Einstellung&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Wert&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Allgemein&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;functionTimeout&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;10 min&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;AI-Sampling&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;excludedTypes&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Request;Exception&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Durable&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;hubName&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;DurableFunctionsHub&lt;/code&gt;, Azure-Storage-Provider, Distributed Tracing V2&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Storage Queues&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;batchSize&lt;/code&gt; / &lt;code&gt;maxDequeueCount&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;1 / 5 (nur für Durable relevant)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Service Bus&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;autoCompleteMessages&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Service Bus&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;maxConcurrentCalls&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;12&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Service Bus&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;maxAutoLockRenewalDuration&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;5 min&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="functions"&gt;Functions&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Function&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Trigger&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Aufgabe&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;GetChanges&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Timer &lt;code&gt;%GetChangesTimerExpression%&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Initialisiert thread-sicher über &lt;code&gt;InitializationService&lt;/code&gt; und ruft &lt;code&gt;ProcessJobsForRetrievalInOrderService.Execute&lt;/code&gt; auf&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;ProcessStandardQueueItems&lt;/code&gt;, &lt;code&gt;ProcessHighPriorityQueueItems&lt;/code&gt;, &lt;code&gt;ProcessLowPriorityQueueItems&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Service Bus &lt;code&gt;sbqexport&lt;/code&gt;, &lt;code&gt;sbqhighexport&lt;/code&gt;, &lt;code&gt;sbqlowexport&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Verarbeiten je eine Nachricht end-to-end über &lt;code&gt;ProcessQueueMessageService.Execute&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;ExecuteJob&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP POST&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Stößt einen Job per Name über &lt;code&gt;ProcessJobsForRetrievalInOrderService.ExecuteByJobName&lt;/code&gt; an&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;ExecuteHttpRequest&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP POST&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ad-hoc-HTTP-GET mit eigenem &lt;code&gt;HttpClient&lt;/code&gt; (NTLM oder anonym), unabhängig von den Connectoren&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;GetInfo&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP GET&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Assembly-Version&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;CheckList&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP GET&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;InitializationService.CheckAsync()&lt;/code&gt;: Mappings gegen Live-Metadaten der Systeme&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Validate&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP GET&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Erzwingt die Initialisierung, liefert das Fehlerlog&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;GetJobs&lt;/code&gt;, &lt;code&gt;GetJobByRowKey&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP GET &lt;code&gt;job&lt;/code&gt;, &lt;code&gt;job/{rowKey}&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Geladene Job-Konfiguration&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;GetMappings&lt;/code&gt;, &lt;code&gt;GetMappingByRowKey&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP GET &lt;code&gt;mapping&lt;/code&gt;, &lt;code&gt;mapping/{name}&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Geladene Mappings, Suche per Name mit Fallback auf RowKey&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Mcp&lt;/code&gt;, &lt;code&gt;McpGet&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP POST/GET &lt;code&gt;mcp&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;MCP-Server; GET antwortet mit 405, weil SSE-Streams nicht unterstützt werden&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;StartGetChangesOrchestration&lt;/code&gt;, &lt;code&gt;GetChangesOrchestrator&lt;/code&gt;, &lt;code&gt;GetChangesActivity&lt;/code&gt;, &lt;code&gt;JobState&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HTTP, Orchestration, Activity, Entity&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Optionale Durable-Variante der Erkennung&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;Details zu Request und Response: &lt;a href="../api-referenz/"&gt;API-Referenz&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Entwicklung</title><link>https://databridge.docs.dsyr.de/entwicklung/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/</guid><description>&lt;p&gt;Dieser Bereich richtet sich an &lt;strong&gt;Entwickler&lt;/strong&gt; der dsyr.DataBridge, nicht an Betreiber einer&#10;Instanz. Er beschreibt Werkzeuge aus dem Repository, die beim Entwickeln und Testen helfen und&#10;nicht Teil des ausgelieferten Produkts sind.&lt;/p&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="architektur-im-detail"&gt;Architektur im Detail&lt;/h2&gt;&#10;&lt;div class="td-card-group card-group p-0 mb-4"&gt;&#10;&lt;div class="td-card card border me-4"&gt;&#10;&lt;div class="card-header"&gt;&#10; &lt;strong&gt;Architektur im Detail&lt;/strong&gt;&#10; &lt;/div&gt;&#10;&lt;div class="card-body"&gt;&#10; &lt;p class="card-text"&gt;&#10; &lt;p&gt;Systemkontext, Bicep-Module, DI und &lt;code&gt;host.json&lt;/code&gt;, HTTP- und Nachrichten-Referenz,&#10;Sequenzdiagramme der Datenflüsse, Abhängigkeiten und Fähigkeiten-Katalog — eine Ebene&#10;tiefer als die &lt;a href="https://databridge.docs.dsyr.de/docs/ueberblick/architektur/"&gt;Architektur-Übersicht&lt;/a&gt; für Administratoren.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/architektur/"&gt;→ Zum Abschnitt&lt;/a&gt;&lt;/p&gt;&#10;&lt;/p&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10;&#10;&lt;/div&gt;&#10;&#10;&lt;hr&gt;&#10;&lt;h2 id="lokale-testumgebung"&gt;Lokale Testumgebung&lt;/h2&gt;&#10;&lt;div class="td-card-group card-group p-0 mb-4"&gt;&#10;&lt;div class="td-card card border me-4"&gt;&#10;&lt;div class="card-header"&gt;&#10; &lt;strong&gt;MCP für die Testumgebung&lt;/strong&gt;&#10; &lt;/div&gt;&#10;&lt;div class="card-body"&gt;&#10; &lt;p class="card-text"&gt;&#10; &lt;p&gt;Den lokalen Container als eigenen MCP-Server &lt;code&gt;databridge-dev&lt;/code&gt; in Claude Code nutzen — parallel&#10;zur Cloud-Instanz.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/mcp-testumgebung/"&gt;→ Zum Artikel&lt;/a&gt;&lt;/p&gt;&#10;&lt;/p&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10;&#10;&lt;div class="td-card card border me-4"&gt;&#10;&lt;div class="card-header"&gt;&#10; &lt;strong&gt;Podman-Testumgebung&lt;/strong&gt;&#10; &lt;/div&gt;&#10;&lt;div class="card-body"&gt;&#10; &lt;p class="card-text"&gt;&#10; &lt;p&gt;DataBridge-Container, Azurite und wahlweise MSSQL, PostgreSQL, MySQL und Oracle — mit&#10;Beispieldaten, Connections, Jobs und Mappings, gestartet mit einem Befehl.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/lokale-testumgebung/"&gt;→ Zum Artikel&lt;/a&gt;&lt;/p&gt;&#10;&lt;/p&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10;&#10;&lt;div class="td-card card border me-4"&gt;&#10;&lt;div class="card-header"&gt;&#10; &lt;strong&gt;Debuggen&lt;/strong&gt;&#10; &lt;/div&gt;&#10;&lt;div class="card-body"&gt;&#10; &lt;p class="card-text"&gt;&#10; &lt;p&gt;Die DataBridge lokal mit Breakpoints debuggen — gegen den Podman-Stack oder gegen eine echte&#10;Azure-Instanz.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/debuggen/"&gt;→ Zum Artikel&lt;/a&gt;&lt;/p&gt;&#10;&lt;/p&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10;&#10;&lt;/div&gt;</description></item><item><title>Podman-Testumgebung</title><link>https://databridge.docs.dsyr.de/entwicklung/lokale-testumgebung/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/lokale-testumgebung/</guid><description>&lt;p&gt;Die Testumgebung unter &lt;code&gt;dev/&lt;/code&gt; startet eine vollständig vorkonfigurierte DataBridge auf dem eigenen&#10;Rechner — ohne Azure-Ressourcen und ohne Kosten. Sie ist gedacht, um Connectoren gegen &lt;strong&gt;echte&#10;Datenbanken&lt;/strong&gt; und gegen &lt;strong&gt;HTTP-Mocks&lt;/strong&gt; (Business Central, NAV, OpenAPI) zu testen, ohne vorher&#10;Mappings und Jobs von Hand anzulegen.&lt;/p&gt;&#10;&lt;div class="alert alert-warning" role="alert"&gt;&lt;div class="h4 alert-heading" role="heading"&gt;Nur für Entwicklung&lt;/div&gt;&#10;&lt;p&gt;Die Umgebung nutzt feste Passwörter und einen festen Function Key (&lt;code&gt;local&lt;/code&gt;). Sie ist nicht für&#10;den Betrieb gedacht und darf nicht aus dem Internet erreichbar sein.&lt;/p&gt;&#10;&lt;/div&gt;</description></item><item><title>API- und Nachrichten-Referenz</title><link>https://databridge.docs.dsyr.de/entwicklung/architektur/api-referenz/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/architektur/api-referenz/</guid><description>&lt;h2 id="authentifizierung"&gt;Authentifizierung&lt;/h2&gt;&#10;&lt;p&gt;Alle HTTP-Functions verwenden &lt;code&gt;AuthorizationLevel.Function&lt;/code&gt;. Der Funktionsschlüssel wird&#10;als Query-Parameter &lt;code&gt;code&lt;/code&gt; oder Header &lt;code&gt;x-functions-key&lt;/code&gt; übergeben. Es gibt keine&#10;Easy-Auth- oder Entra-Konfiguration im Deployment. Timer-, Service-Bus- und&#10;Durable-Trigger haben keinen HTTP-Endpunkt.&lt;/p&gt;&#10;&lt;p&gt;Routen ohne &lt;code&gt;Route&lt;/code&gt;-Attribut folgen der Konvention &lt;code&gt;/api/&amp;lt;FunctionName&amp;gt;&lt;/code&gt;.&lt;/p&gt;&#10;&lt;h2 id="http-endpunkte"&gt;HTTP-Endpunkte&lt;/h2&gt;&#10;&lt;h3 id="get-apigetinfo"&gt;&lt;code&gt;GET /api/GetInfo&lt;/code&gt;&lt;/h3&gt;&#10;&lt;p&gt;Liefert die Assembly-Version, keine Gesundheitsprüfung.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{ &lt;span style="color:#f92672"&gt;&amp;#34;Version&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;2.3.2026.0926&amp;#34;&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="post-apiexecutejob"&gt;&lt;code&gt;POST /api/ExecuteJob&lt;/code&gt;&lt;/h3&gt;&#10;&lt;p&gt;Stößt einen Job aus der Tabelle &lt;code&gt;jobs&lt;/code&gt; manuell an (Erkennungsphase).&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{ &lt;span style="color:#f92672"&gt;&amp;#34;JobName&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;RowKey des Jobs&amp;gt;&amp;#34;&lt;/span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ablauf: &lt;code&gt;JobName&lt;/code&gt; prüfen → &lt;code&gt;EnsureInitializedAsync&lt;/code&gt; → &lt;code&gt;ProcessJobForRetrieval&lt;/code&gt;.&#10;Antwort &lt;code&gt;200 OK&lt;/code&gt;; Fehler propagieren als 500. Der Aufruf läuft ohne Job-Locking parallel&#10;zum Timer, siehe &lt;a href="../datenfluesse/#watermark-logik"&gt;Datenflüsse → Watermark&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Debuggen</title><link>https://databridge.docs.dsyr.de/entwicklung/debuggen/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/debuggen/</guid><description>&lt;p&gt;Für Breakpoints und Step-Through läuft die DataBridge nicht im Container, sondern lokal als&#10;Prozess in der IDE. Zwei grundsätzlich verschiedene Varianten, je nachdem wogegen die lokal&#10;laufende DataBridge sprechen soll:&lt;/p&gt;&#10;&lt;div class="td-card-group card-group p-0 mb-4"&gt;&#10;&lt;div class="td-card card border me-4"&gt;&#10;&lt;div class="card-header"&gt;&#10; &lt;strong&gt;Gegen Podman debuggen&lt;/strong&gt;&#10; &lt;/div&gt;&#10;&lt;div class="card-body"&gt;&#10; &lt;p class="card-text"&gt;&#10; &lt;p&gt;Azurite, Podman-Datenbanken, Service-Bus-Emulator, WireMock — alles lokal, keine Azure-Kosten,&#10;jederzeit zurücksetzbar.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/debuggen/podman/"&gt;→ Zum Artikel&lt;/a&gt;&lt;/p&gt;&#10;&lt;/p&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10;&#10;&lt;div class="td-card card border me-4"&gt;&#10;&lt;div class="card-header"&gt;&#10; &lt;strong&gt;Gegen echtes Azure debuggen&lt;/strong&gt;&#10; &lt;/div&gt;&#10;&lt;div class="card-body"&gt;&#10; &lt;p class="card-text"&gt;&#10; &lt;p&gt;Echter Storage Account, echter Service Bus, echte Quell-/Zielsysteme — für Probleme aus einer&#10;konkreten Umgebung.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://databridge.docs.dsyr.de/entwicklung/debuggen/cloud/"&gt;→ Zum Artikel&lt;/a&gt;&lt;/p&gt;&#10;&lt;/p&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10;&#10;&lt;/div&gt;</description></item><item><title>Datenflüsse</title><link>https://databridge.docs.dsyr.de/entwicklung/architektur/datenfluesse/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/architektur/datenfluesse/</guid><description>&lt;p&gt;Die konzeptuelle Beschreibung steht unter &lt;a href="https://databridge.docs.dsyr.de/docs/ueberblick/wie-es-funktioniert/"&gt;Wie es funktioniert&lt;/a&gt;.&#10;Hier folgen die Abläufe auf Klassenebene.&lt;/p&gt;&#10;&lt;h2 id="erkennung-timer"&gt;Erkennung (Timer)&lt;/h2&gt;&#10;&lt;pre class="mermaid"&gt;sequenceDiagram&#10; autonumber&#10; participant Timer as GetChanges (Timer)&#10; participant Init as InitializationService&#10; participant PJ as ProcessJobsForRetrievalInOrderService&#10; participant Job as JobService&#10; participant WM as WatermarkService&#10; participant Conn as Source-Connector&#10; participant SBS as ServiceBusService&#10; participant SB as Service Bus&#10;&#10; Timer-&amp;gt;&amp;gt;Init: EnsureInitializedAsync()&#10; Note over Init: einmalig: Storage → Connections → Mappings → Jobs&#10; Timer-&amp;gt;&amp;gt;PJ: Execute()&#10; PJ-&amp;gt;&amp;gt;Job: GetJobsToRun()&#10; Note over Job,WM: GetAllWatermarks() (Bulk) für LastCronRun&#10; loop je Job nach Order&#10; PJ-&amp;gt;&amp;gt;WM: GetWatermarkByJobName(job)&#10; PJ-&amp;gt;&amp;gt;Conn: RetrieveChangesAsync(mapping, job, watermark, filter)&#10; loop seitenweise&#10; Conn--&amp;gt;&amp;gt;PJ: QueueMessage (serialisiert)&#10; PJ-&amp;gt;&amp;gt;SBS: AddMessageOrSendAsync(msg, priority)&#10; alt Batch voll (200) oder Größenlimit&#10; SBS-&amp;gt;&amp;gt;SB: SendMessagesAsync(batch)&#10; end&#10; PJ-&amp;gt;&amp;gt;PJ: lastChangeTracker = msg.ChangeTracker&#10; end&#10; PJ-&amp;gt;&amp;gt;SBS: FlushBatch()&#10; PJ-&amp;gt;&amp;gt;WM: UpdateWatermarkByJobName(newWatermark, lastCronRun)&#10; end&lt;/pre&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Die Serialisierung (Key-Aufbau → Feld-Mappings → Source-Operationen / Resolver) passiert&#10;im Connector (&lt;code&gt;ConnectorBase.Serialize&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;Die Watermark wird &lt;strong&gt;erst am Ende&lt;/strong&gt; eines Jobs geschrieben. Bricht der Lauf vorher ab,&#10;wird beim nächsten Lauf erneut ab dem alten Stand gelesen; &lt;code&gt;SkipOutdatedMessages&lt;/code&gt; fängt&#10;Doppel-Nachrichten im Ziel ab.&lt;/li&gt;&#10;&lt;li&gt;Bei reinem Zeitstempel-Vorrücken ohne fachliche Änderung wird &lt;code&gt;JobActionType.TimeStamp&lt;/code&gt;&#10;verwendet.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;MetricsService&lt;/code&gt; zählt &lt;code&gt;ChangesDetected&lt;/code&gt; je Job.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="erkennung-durable"&gt;Erkennung (Durable)&lt;/h2&gt;&#10;&lt;pre class="mermaid"&gt;sequenceDiagram&#10; autonumber&#10; participant HTTP as StartGetChangesOrchestration&#10; participant Orch as GetChangesOrchestrator&#10; participant State as JobState (Entity)&#10; participant Act as GetChangesActivity&#10; participant Conn as Source-Connector&#10; participant SBS as ServiceBusService&#10;&#10; HTTP--&amp;gt;&amp;gt;HTTP: 202 &amp;#43; InstanceId&#10; loop je Job aus GetJobsToRun&#10; Orch-&amp;gt;&amp;gt;State: InProgress(jobName)?&#10; alt in Bearbeitung&#10; Orch-&amp;gt;&amp;gt;Orch: überspringen&#10; else&#10; Orch-&amp;gt;&amp;gt;State: Add(jobName)&#10; loop do … while HasMoreRecord&#10; Orch-&amp;gt;&amp;gt;Act: CallActivity(JobActivityParam)&#10; Act-&amp;gt;&amp;gt;Conn: RetrieveChangesAsync(…, MaxBatchSize=3)&#10; Act-&amp;gt;&amp;gt;SBS: SendMessage(record, priority)&#10; Act--&amp;gt;&amp;gt;Orch: Page, Cookie, Watermark, HasMoreRecord&#10; end&#10; Orch-&amp;gt;&amp;gt;State: Remove(jobName)&#10; end&#10; end&lt;/pre&gt;&#10;&lt;p&gt;Der Durable-Pfad persistiert die Watermark nicht und ist im Timer-Betrieb nicht aktiv.&lt;/p&gt;</description></item><item><title>Abhängigkeiten</title><link>https://databridge.docs.dsyr.de/entwicklung/architektur/abhaengigkeiten/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/architektur/abhaengigkeiten/</guid><description>&lt;h2 id="plattform"&gt;Plattform&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;net10.0&lt;/code&gt; in allen Projekten, &lt;code&gt;ImplicitUsings&lt;/code&gt; und &lt;code&gt;Nullable&lt;/code&gt; aktiv.&lt;/li&gt;&#10;&lt;li&gt;Azure Functions v4, Isolated Worker, &lt;code&gt;OutputType=Exe&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Tests auf xUnit v3 mit Microsoft Testing Platform. Aufruf mit&#10;&lt;code&gt;dotnet test --project …&lt;/code&gt;; das Positionsargument funktioniert nicht mehr.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="projekte"&gt;Projekte&lt;/h2&gt;&#10;&lt;pre class="mermaid"&gt;flowchart LR&#10; HOST[&amp;#34;DataBridge (Host)&amp;#34;] --&amp;gt; CORE[&amp;#34;DataBridge.Core&amp;#34;]&#10; DLM[&amp;#34;DeadLetterMover&amp;#34;] --&amp;gt; CORE&#10; TEST[&amp;#34;DataBridge.Test&amp;#34;] --&amp;gt; CORE&#10; TEST --&amp;gt; HOST&lt;/pre&gt;&#10;&lt;h2 id="nuget-pakete"&gt;NuGet-Pakete&lt;/h2&gt;&#10;&lt;p&gt;Die Versionen werden zentral in &lt;code&gt;src/Directory.Packages.props&lt;/code&gt; gepflegt (Central Package&#10;Management); die &lt;code&gt;.csproj&lt;/code&gt;-Dateien referenzieren Pakete nur noch ohne &lt;code&gt;Version&lt;/code&gt;. Ein Update&#10;passiert also an genau einer Stelle.&lt;/p&gt;</description></item><item><title>Fähigkeiten-Katalog</title><link>https://databridge.docs.dsyr.de/entwicklung/architektur/capabilities/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://databridge.docs.dsyr.de/entwicklung/architektur/capabilities/</guid><description>&lt;h2 id="integration-und-datenfluss"&gt;Integration und Datenfluss&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Fähigkeit&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Umsetzung&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Change Detection (Pull)&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;GetChanges&lt;/code&gt; → &lt;code&gt;ProcessJobsForRetrievalInOrderService&lt;/code&gt;; je Connector &lt;code&gt;RetrieveChangesAsync&lt;/code&gt; (BC/NAV &lt;code&gt;$filter&lt;/code&gt;, CE &lt;code&gt;RetrieveEntityChangesRequest&lt;/code&gt;, SQL seitenweises SELECT, OpenAPI Query-String)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Orchestrierter Abruf&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Durable: &lt;code&gt;GetChangesOrchestrator&lt;/code&gt;, &lt;code&gt;GetChangesActivity&lt;/code&gt;, Entity &lt;code&gt;JobState&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Asynchrone Entkopplung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Service Bus mit sieben Queues, &lt;code&gt;ServiceBusService&lt;/code&gt; mit Batch bis 200&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Priorisierte Verarbeitung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;JobPriorityType&lt;/code&gt; → Queue; drei Trigger&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Reihenfolgensteuerung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Job.Order&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Idempotentes Schreiben&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Connector.Upsert/Delete&lt;/code&gt;; &lt;code&gt;TargetKey&lt;/code&gt;/&lt;code&gt;TargetKeys&lt;/code&gt; mit &lt;code&gt;KeyRank&lt;/code&gt;, erster Treffer gewinnt&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Aktions-Jobs&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;InvokeAction&lt;/code&gt;: Job-&lt;code&gt;Action&lt;/code&gt; ohne CRUD-Bedeutung ruft einen benannten Endpunkt&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Job-eigene Pfade&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Source&lt;/code&gt;/&lt;code&gt;Target&lt;/code&gt; am Job überschreiben &lt;code&gt;SourceTable&lt;/code&gt;/&lt;code&gt;TargetTable&lt;/code&gt; des Mappings&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Eingebettete Kinder&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;EmbedChildren&lt;/code&gt; (nur CE als Quelle)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Response-Jobs&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Upsert(..., responseMapping, job)&lt;/code&gt; → Response-Nachricht&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Watermarking&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;WatermarkService&lt;/code&gt; + &lt;code&gt;WatermarkValue&lt;/code&gt;; Typen &lt;code&gt;date&lt;/code&gt;, &lt;code&gt;datetime&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="konnektivität"&gt;Konnektivität&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Fähigkeit&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Umsetzung&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;D365 Business Central&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;BcConnector : HttpConnectorBase&lt;/code&gt;, OAuth2 / Basic / Managed Identity&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;D365 CE / Dataverse&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;CeConnector : ConnectorBase&lt;/code&gt;, &lt;code&gt;ServiceClient&lt;/code&gt; (Connection-String oder &lt;code&gt;url&lt;/code&gt; + Managed Identity)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;D365 NAV&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;NavConnector : HttpConnectorBase&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;REST über OpenAPI&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;OpenApiConnector : HttpConnectorBase&lt;/code&gt;, Spec aus &lt;code&gt;openApiSpecUrl&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;MSSQL, PostgreSQL, MySQL, Oracle&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;SqlConnectorBase&amp;lt;T&amp;gt;&lt;/code&gt;, nur lesend&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Auth-Varianten HTTP&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Basic, OAuth2 Client Credentials mit &lt;code&gt;tokenUrl&lt;/code&gt;, API-Key, Managed Identity (explizit über &lt;code&gt;authmethod&lt;/code&gt;)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Key-Vault-Bezug&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;keyVaultUrl&lt;/code&gt; in der Connection + &lt;code&gt;DefaultAzureCredential&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Schema-Metadaten&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;IConnector.GetTableNames&lt;/code&gt;, &lt;code&gt;GetTableMetadata&lt;/code&gt; für alle Connector-Typen&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ad-hoc-HTTP&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;ExecuteHttpRequest&lt;/code&gt; (nur GET)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="transformation-und-mapping"&gt;Transformation und Mapping&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Fähigkeit&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Umsetzung&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Feld-Mapping&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;TableMapping&lt;/code&gt; + &lt;code&gt;FieldMapping&lt;/code&gt; aus &lt;code&gt;mappings&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Typ-Coercion&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;AttributeResolver&lt;/code&gt;-Familien je Systemtyp&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Metadaten-basierte Resolver-Wahl&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;TargetValueMapper&lt;/code&gt; je Connector, statische &lt;code&gt;FrozenDictionary&lt;/code&gt;-Registry mit Coverage-Tests&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Default-Werte&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Target-Operationen &lt;code&gt;DefaultValue&lt;/code&gt;, &lt;code&gt;DefaultValueIfNullOrEmpty&lt;/code&gt;, &lt;code&gt;DefaultValueMap&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Option-/Picklist-Mapping&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;OptionMapping&lt;/code&gt;, CE-Resolver für Picklist, MultiSelect, State/Status&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Lookup-Auflösung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Source-Operation &lt;code&gt;LookupValue&lt;/code&gt; mit Cache; CE mit Batch-Pre-Caching; &lt;code&gt;DoNotCreate&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;CE-Beziehungen&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;ActivityParty&lt;/code&gt;, &lt;code&gt;LinkToRecord&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;ReadFromMessage&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Wert aus der Nachricht übernehmen&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Virtuelle Felder&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;_&lt;/code&gt;-Präfix im &lt;code&gt;SourceField&lt;/code&gt;, nie gegen Metadaten validiert&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Erweiterbarkeit&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Source-Operation-Handler per Reflection&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="konfiguration-und-steuerung"&gt;Konfiguration und Steuerung&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Fähigkeit&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Umsetzung&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Konfigurationsgetriebener Betrieb&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Table Storage, &lt;code&gt;StorageService&lt;/code&gt;, &lt;code&gt;SettingsService&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cron je Job&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Job.Schedule&lt;/code&gt;, &lt;code&gt;NCrontab.Signed&lt;/code&gt;, sechs Felder&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Manueller Job-Start&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;ExecuteJob&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Function-Toggles&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;AzureWebJobs.&amp;lt;Name&amp;gt;.Disabled&lt;/code&gt;, Bicep &lt;code&gt;disabledFunctions&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Konfig-Diagnose&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;CheckList&lt;/code&gt;, &lt;code&gt;Validate&lt;/code&gt;, &lt;code&gt;JobApi&lt;/code&gt;, &lt;code&gt;MappingApi&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;KI-Anbindung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;MCP-Server mit read-only Tools&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Self-Repair der Initialisierung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;ResetInitialization&lt;/code&gt; bei Fehlern&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Quell-Filter&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Job.Filter&lt;/code&gt; mit &lt;code&gt;{{…}}&lt;/code&gt;-Templating&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Veraltete Nachrichten überspringen&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;SkipOutdatedMessages&lt;/code&gt; → &lt;code&gt;sbqignored&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="resilienz"&gt;Resilienz&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Fähigkeit&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Umsetzung&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Backoff-Retry&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;DeliveryCount² · 1000 ms&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Lock-Renewal&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hintergrund-Task alle 30 s&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Konflikt-Isolation&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;TransitiveException&lt;/code&gt; → &lt;code&gt;sbqtransitive*&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Dead-Lettering&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;maxDeliveryCount&lt;/code&gt;, Fehler-Properties an der Nachricht&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Requeue&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;DeadLetterMover&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Kommunikationsfehler&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;GetChanges&lt;/code&gt; fängt &lt;code&gt;EndpointNotFoundException&lt;/code&gt;, &lt;code&gt;CommunicationException&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="observability"&gt;Observability&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Fähigkeit&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Umsetzung&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Gepuffertes Logging&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;BufferingLoggerProvider&lt;/code&gt;, Flush pro Invocation&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Dependency-Sampling&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;DependencySamplingProcessor&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Custom Metrics&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;MetricsService&lt;/code&gt; (&lt;code&gt;ChangesDetected&lt;/code&gt;, &lt;code&gt;MessagesProcessed&lt;/code&gt;)&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Korrelation&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;InvocationContext&lt;/code&gt;, &lt;code&gt;operation_id&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Steuerung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;TELEMETRY_CONTROL&lt;/code&gt;, drei Raten-Settings&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Alerts&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;DLQ-Stufen, Queue-Länge, Action Group&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Dashboard&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Grafana-Dashboard aus Bicep&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Version&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;GetInfo&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="infrastruktur-und-auslieferung"&gt;Infrastruktur und Auslieferung&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Fähigkeit&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Umsetzung&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Infrastructure as Code&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Bicep mit Modulen und &lt;code&gt;.bicepparam&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Marketplace&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;createUiDefinition.json&lt;/code&gt;, generierte &lt;code&gt;mainTemplate.json&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Identitätsbasierter Zugriff&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;enableManagedIdentity&lt;/code&gt; + Rollen&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Serverless-Skalierung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Y1 / EP1–EP3, &lt;code&gt;functionScaleLimit&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Run-from-Package&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;WEBSITE_RUN_FROM_PACKAGE=1&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Container&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Dockerfile&lt;/code&gt;, &lt;code&gt;compose.yml&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Versionierung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;Major.Minor.yyyy.MMdd&lt;/code&gt;, manueller Bump&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;CI/CD&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Azure Pipelines unter &lt;code&gt;cicd/&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Lokale Entwicklung&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;a href="../../lokale-testumgebung/"&gt;Podman-Testumgebung&lt;/a&gt; mit DBs und HTTP-Mocks&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="qualitätssicherung"&gt;Qualitätssicherung&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Fähigkeit&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Umsetzung&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Unit-Tests&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;DataBridge.Test&lt;/code&gt;, xUnit v3, Moq&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Coverage&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Microsoft Testing Platform Code Coverage&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Resolver-Vollständigkeit&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;*TargetValueMapperCoverageTests&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Dokumentation&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hugo/Docsy unter &lt;code&gt;docs/&lt;/code&gt;, veröffentlicht per Pipeline&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;</description></item></channel></rss>