This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="720" height="1190" viewBox="0 0 720 1190" role="img" aria-labelledby="title desc">
|
||||
<title id="title">Диагностика duplicate и replay учебного события</title>
|
||||
<desc id="desc">Вертикальное дерево: проверка envelope, проверка consumer contract и schema version, lookup в ledger. Из веток выходят effect recorded, duplicate or replay suppressed и contract update required.</desc>
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="12" markerHeight="12" refX="10" refY="6" orient="auto">
|
||||
<path d="M0,0 L12,6 L0,12 Z" fill="#4bc0c8"/>
|
||||
</marker>
|
||||
<marker id="warnarrow" markerWidth="12" markerHeight="12" refX="10" refY="6" orient="auto">
|
||||
<path d="M0,0 L12,6 L0,12 Z" fill="#e7aa55"/>
|
||||
</marker>
|
||||
<style>
|
||||
.bg { fill: #0d1724; }
|
||||
.panel { fill: #162437; stroke: #36516b; stroke-width: 2; }
|
||||
.check { fill: #123d4b; stroke: #4bc0c8; stroke-width: 2; }
|
||||
.ok { fill: #1d3b30; stroke: #77c893; stroke-width: 2; }
|
||||
.warn { fill: #3b3030; stroke: #e7aa55; stroke-width: 2; }
|
||||
.line { stroke: #4bc0c8; stroke-width: 4; fill: none; marker-end: url(#arrow); }
|
||||
.warnline { stroke: #e7aa55; stroke-width: 4; fill: none; marker-end: url(#warnarrow); }
|
||||
.title { fill: #f3fbff; font: 32px Arial, sans-serif; font-weight: 700; }
|
||||
.label { fill: #d9edf6; font: 24px Arial, sans-serif; font-weight: 700; }
|
||||
.body { fill: #a8bed0; font: 21px Arial, sans-serif; }
|
||||
.code { fill: #92e3e8; font: 22px "SFMono-Regular", Consolas, monospace; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="bg" width="720" height="1190" rx="28"/>
|
||||
<text class="title" x="48" y="62">Перед replay собираем evidence</text>
|
||||
<text class="body" x="48" y="96">id · source · schema · contract · ledger</text>
|
||||
|
||||
<rect class="check" x="54" y="140" width="612" height="142" rx="18"/>
|
||||
<text class="label" x="84" y="182">1. Envelope валиден?</text>
|
||||
<text class="code" x="84" y="222">source · id · type · subject</text>
|
||||
<text class="body" x="84" y="256">Нет → rejected envelope, без effect.</text>
|
||||
|
||||
<path class="line" d="M360 282 L360 354"/>
|
||||
<rect class="check" x="54" y="370" width="612" height="148" rx="18"/>
|
||||
<text class="label" x="84" y="412">2. Contract принимает schema?</text>
|
||||
<text class="code" x="84" y="452">consumerId · schemaVersion</text>
|
||||
<text class="body" x="84" y="486">Нет → contract update required.</text>
|
||||
|
||||
<path class="line" d="M360 518 L360 590"/>
|
||||
<rect class="panel" x="54" y="606" width="612" height="138" rx="18"/>
|
||||
<text class="label" x="84" y="648">3. Ledger уже содержит key?</text>
|
||||
<text class="code" x="84" y="688">consumerId : source : id</text>
|
||||
<text class="body" x="84" y="722">Проверяется до нового учебного result.</text>
|
||||
|
||||
<path class="line" d="M230 744 L230 816"/>
|
||||
<rect class="ok" x="54" y="832" width="334" height="178" rx="18"/>
|
||||
<text class="label" x="82" y="874">Нет ключа</text>
|
||||
<text class="code" x="82" y="916">effect-recorded</text>
|
||||
<text class="body" x="82" y="954">record resultVersion</text>
|
||||
<text class="body" x="82" y="984">и input schema</text>
|
||||
|
||||
<path class="line" d="M490 744 L490 816"/>
|
||||
<rect class="warn" x="420" y="832" width="246" height="178" rx="18"/>
|
||||
<text class="label" x="446" y="874">Есть ключ</text>
|
||||
<text class="code" x="446" y="916">suppress</text>
|
||||
<text class="body" x="446" y="954">duplicate или</text>
|
||||
<text class="body" x="446" y="984">controlled replay</text>
|
||||
|
||||
<path class="warnline" d="M652 444 C704 444 704 1092 602 1092"/>
|
||||
<rect class="warn" x="54" y="1052" width="612" height="92" rx="18"/>
|
||||
<text class="label" x="84" y="1090">Unknown schema: effect запрещён</text>
|
||||
<text class="body" x="84" y="1122">Сохраняем причину для contract update.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,65 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="720" height="1160" viewBox="0 0 720 1160" role="img" aria-labelledby="title desc">
|
||||
<title id="title">Матрица совместимости схемы события</title>
|
||||
<desc id="desc">Вертикальная схема показывает событие v1, v2 с добавочным необязательным полем и v3 с изменённой семантикой. Consumer v1 читает stable fields, consumer v2 умеет нормализовать отсутствие нового поля, v3 требует обновления договора.</desc>
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="12" markerHeight="12" refX="10" refY="6" orient="auto">
|
||||
<path d="M0,0 L12,6 L0,12 Z" fill="#4bc0c8"/>
|
||||
</marker>
|
||||
<style>
|
||||
.bg { fill: #0d1724; }
|
||||
.event { fill: #163544; stroke: #4bc0c8; stroke-width: 2; }
|
||||
.consumer { fill: #1b293d; stroke: #607d9a; stroke-width: 2; }
|
||||
.blocked { fill: #3b3030; stroke: #e7aa55; stroke-width: 2; }
|
||||
.line { stroke: #4bc0c8; stroke-width: 4; fill: none; marker-end: url(#arrow); }
|
||||
.warnline { stroke: #e7aa55; stroke-width: 4; fill: none; marker-end: url(#arrow); }
|
||||
.title { fill: #f3fbff; font: 32px Arial, sans-serif; font-weight: 700; }
|
||||
.label { fill: #d9edf6; font: 24px Arial, sans-serif; font-weight: 700; }
|
||||
.body { fill: #a8bed0; font: 21px Arial, sans-serif; }
|
||||
.code { fill: #92e3e8; font: 22px "SFMono-Regular", Consolas, monospace; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="bg" width="720" height="1160" rx="28"/>
|
||||
<text class="title" x="48" y="62">Схема меняется по парам</text>
|
||||
<text class="body" x="48" y="96">writer event ↔ declared reader contract</text>
|
||||
|
||||
<rect class="event" x="48" y="140" width="286" height="202" rx="18"/>
|
||||
<text class="label" x="76" y="180">Event schema v1</text>
|
||||
<text class="code" x="76" y="222">orderId</text>
|
||||
<text class="code" x="76" y="256">status</text>
|
||||
<text class="body" x="76" y="300">старый writer</text>
|
||||
|
||||
<rect class="consumer" x="386" y="140" width="286" height="202" rx="18"/>
|
||||
<text class="label" x="414" y="180">Consumer v1</text>
|
||||
<text class="code" x="414" y="222">reads stable fields</text>
|
||||
<text class="body" x="414" y="266">resultVersion .1</text>
|
||||
<text class="body" x="414" y="300">v1 accepted</text>
|
||||
<path class="line" d="M334 241 L374 241"/>
|
||||
|
||||
<rect class="event" x="48" y="438" width="286" height="238" rx="18"/>
|
||||
<text class="label" x="76" y="478">Event schema v2</text>
|
||||
<text class="code" x="76" y="520">orderId · status</text>
|
||||
<text class="code" x="76" y="554">paymentReference?</text>
|
||||
<text class="body" x="76" y="600">добавлено optional field</text>
|
||||
<text class="body" x="76" y="632">stable meaning сохранён</text>
|
||||
|
||||
<rect class="consumer" x="386" y="414" width="286" height="128" rx="18"/>
|
||||
<text class="label" x="414" y="454">Consumer v1</text>
|
||||
<text class="body" x="414" y="490">игнорирует declared optional</text>
|
||||
<text class="body" x="414" y="520">resultVersion .1</text>
|
||||
<path class="line" d="M334 500 L374 478"/>
|
||||
|
||||
<rect class="consumer" x="386" y="570" width="286" height="154" rx="18"/>
|
||||
<text class="label" x="414" y="610">Consumer v2</text>
|
||||
<text class="body" x="414" y="648">читает поле или null</text>
|
||||
<text class="body" x="414" y="680">resultVersion .2</text>
|
||||
<path class="line" d="M334 592 L374 646"/>
|
||||
|
||||
<rect class="blocked" x="48" y="838" width="624" height="206" rx="18"/>
|
||||
<text class="label" x="78" y="882">Event schema v3: semantic change</text>
|
||||
<text class="code" x="78" y="926">state вместо status</text>
|
||||
<text class="body" x="78" y="966">JSON может распарситься, но meaning не объявлен.</text>
|
||||
<text class="label" x="78" y="1014">contract update required</text>
|
||||
<path class="warnline" d="M360 724 L360 816"/>
|
||||
|
||||
<text class="body" x="48" y="1112">Compatible — свойство конкретной пары writer и reader.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,54 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="720" height="1140" viewBox="0 0 720 1140" role="img" aria-labelledby="title desc">
|
||||
<title id="title">Учебная топология событийной интеграции</title>
|
||||
<desc id="desc">Вертикальная схема: producer формирует envelope и payload, граница доставки передаёт их consumer, consumer валидирует договор и записывает versioned result в ledger. Повтор и controlled replay несут тот же source и event id.</desc>
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="12" markerHeight="12" refX="10" refY="6" orient="auto">
|
||||
<path d="M0,0 L12,6 L0,12 Z" fill="#4bc0c8"/>
|
||||
</marker>
|
||||
<style>
|
||||
.bg { fill: #0d1724; }
|
||||
.panel { fill: #162437; stroke: #36516b; stroke-width: 2; }
|
||||
.accent { fill: #123d4b; stroke: #4bc0c8; stroke-width: 2; }
|
||||
.warn { fill: #3b3030; stroke: #e7aa55; stroke-width: 2; }
|
||||
.line { stroke: #4bc0c8; stroke-width: 4; fill: none; marker-end: url(#arrow); }
|
||||
.muted { fill: #a8bed0; font: 22px Arial, sans-serif; }
|
||||
.label { fill: #d9edf6; font: 24px Arial, sans-serif; font-weight: 700; }
|
||||
.title { fill: #f3fbff; font: 32px Arial, sans-serif; font-weight: 700; }
|
||||
.small { fill: #a8bed0; font: 20px Arial, sans-serif; }
|
||||
.code { fill: #92e3e8; font: 22px "SFMono-Regular", Consolas, monospace; }
|
||||
</style>
|
||||
</defs>
|
||||
<rect class="bg" width="720" height="1140" rx="28"/>
|
||||
<text class="title" x="54" y="62">Один event, несколько delivery</text>
|
||||
<text class="muted" x="54" y="96">Учебный contract июня 2021</text>
|
||||
|
||||
<rect class="accent" x="54" y="138" width="612" height="188" rx="18"/>
|
||||
<text class="label" x="84" y="180">1. Producer: формирует факт</text>
|
||||
<text class="code" x="84" y="220">id · source · type · subject</text>
|
||||
<text class="code" x="84" y="254">schemaVersion · data</text>
|
||||
<text class="small" x="84" y="294">Envelope и payload имеют разных owners.</text>
|
||||
|
||||
<path class="line" d="M360 326 L360 402"/>
|
||||
<rect class="panel" x="54" y="418" width="612" height="154" rx="18"/>
|
||||
<text class="label" x="84" y="460">2. Delivery boundary</text>
|
||||
<text class="muted" x="84" y="498">Передаёт event consumer-у.</text>
|
||||
<text class="small" x="84" y="534">Delivery не равна доменному факту.</text>
|
||||
|
||||
<path class="line" d="M360 572 L360 648"/>
|
||||
<rect class="accent" x="54" y="664" width="612" height="192" rx="18"/>
|
||||
<text class="label" x="84" y="706">3. Consumer: сначала проверка</text>
|
||||
<text class="code" x="84" y="746">validate envelope → contract</text>
|
||||
<text class="code" x="84" y="780">schema version → projection</text>
|
||||
<text class="small" x="84" y="820">Unknown schema не создаёт effect.</text>
|
||||
|
||||
<path class="line" d="M360 856 L360 932"/>
|
||||
<rect class="panel" x="54" y="948" width="612" height="142" rx="18"/>
|
||||
<text class="label" x="84" y="990">4. Versioned result ledger</text>
|
||||
<text class="code" x="84" y="1028">consumerId : source : id</text>
|
||||
<text class="small" x="84" y="1062">resultVersion объясняет интерпретацию.</text>
|
||||
|
||||
<path class="line" d="M652 506 C704 506 704 796 652 796"/>
|
||||
<rect class="warn" x="432" y="364" width="234" height="88" rx="16"/>
|
||||
<text class="label" x="452" y="400">Duplicate / replay</text>
|
||||
<text class="small" x="452" y="430">тот же source:id</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
Reference in New Issue
Block a user