Cvičení 09 · Doménové vs. integrační události a broker
Odeslání žádosti
- MortgageApplicationSubmitted
- domain vs integration events
- broker
Princip
Doménové události (IncomeChanged…) patří do agregátu a jsou interní. Integrační událost MortgageApplicationSubmitted je stabilní smlouva pro ostatní služby.
Když se interní události vystaví do brokeru, každý odběratel se naváže na jejich tvar a refaktoring uvnitř kalkulačky rozbije cizí služby.
Proto kalkulačka při odeslání žádosti přeloží doménovou událost ApplicationSubmitted na malou integrační událost.
Co sledovat
- V brokeru se objevují interní události jen v anti-vzoru.
- Risk Service skončí v DLQ na IncomeChanged v2.
Bez řešení / S řešením
Bez řešení
Spustit s unikajícími doménovými událostmi
Kalkulačka publikuje do brokeru všechny doménové události. Risk Service se na IncomeChanged naváže a po změně tvaru selže.
Spustit v simulátoru bez řešeníS řešením
Spustit jen s integrační událostí
Ven jde jediná, verzovaná událost MortgageApplicationSubmitted. Interní změny kalkulačky nikoho nerozbijí.
Spustit v simulátoru s řešenímCo udělat: Klikni na „Spustit s unikajícími doménovými událostmi“. Na co se dívat: Risk Service dostane zprávu, které nerozumí, a ta skončí v DLQ. Simulátor potřebuje JavaScript a běží jako samostatná aplikace.
Zkus to ve svém projektu
Zkopíruj prompt do svého coding agenta (Claude Code, Copilot, Codex…) a spusť ho v repozitáři svého projektu.
Oddělit interní doménové události od integračních a publikovat jen stabilní kontrakt MortgageApplicationSubmitted.
# Úkol pro coding agenta: Odeslání žádosti
Stack: Java. Režim: s vedením.
Cíl: Oddělit interní doménové události od integračních a publikovat jen stabilní kontrakt MortgageApplicationSubmitted.
## Kontext existujícího kódu
Pracuješ v existujícím projektu (Java backend (typicky Java 21, Spring Boot, JPA nebo JDBC). Použij build nástroj a styl, který projekt už má (Maven/Gradle, JUnit 5).).
Doména: hypoteční kalkulačka, která se postupně mění v event-driven systém (kalkulačka, rizika, schvalování, identita, účet, dokumenty, výplata).
Předpoklad: projekt má event store s feedem (odběr s checkpointem) a doménovou událost `ApplicationSubmitted`. Pokud ne, nejdřív založ minimální příkaz „odeslat žádost“ nad dokončeným výpočtem; bez brokeru stačí `publish(topic, event)` v paměti.
Nejdřív čti, nic neměň. Najdi a stručně shrň:
- Co dnes kalkulačka publikuje na broker/frontu a kdo to odebírá.
- Kontrakty (schémata) existujících zpráv.
- Které z těchto částí už v projektu existují a které chybí. Než napíšeš vlastní infrastrukturu (broker klient, outbox, retry), ověř, jestli ji projekt nebo organizace nemá jako hotovou knihovnu, a použij ji.
## Očekávané chování
Doménové události jsou interní. Když jdou do brokeru, odběratel se naváže na jejich tvar: Risk Service po změně `IncomeChanged` na v2 skončí v DLQ. Ven jde jen verzovaná `MortgageApplicationSubmitted`, např. `{ eventId, type, version: 1, occurredAt, correlationId, causationId, data: { applicationId, loanAmountMinor, monthlyPaymentMinor, monthlyIncomeMinor, termMonths } }`.
## Konkrétní úkol
Technická specifika (Java): Mapper (MapStruct nebo ručně) do `record`; schéma ověř JSON Schema/Avro testem; publikace přes existující messaging vrstvu projektu.
Postupuj po krocích. Po bodu 1 (plán) napiš, co zjistíš a co navrhuješ, a počkej na potvrzení:
1. Plán: definuj integrační událost (jen pole, která konzumenti potřebují, verze 1, correlationId).
2. Přidej překladovou vrstvu doménová → integrační událost (anti-corruption).
3. Publikuj integrační událost při ApplicationSubmitted z feedu uložených událostí, ne z příkazu vedle zápisu; doménové události neopouštějí službu. `correlationId` z hlavičky požadavku (jinak nové) ulož do doménové události, `causationId` = id doménové události, `eventId` je při opakování stejné.
4. Contract test: schéma v1 je zafixované (změna souboru test shodí), změna interního tvaru ho nerozbije.
Na co si dát pozor:
- Integrační událost nesmí nést celý agregát.
- Pošli jen data, která konzument potřebuje a sám neodvodí.
## Co nesmíš měnit
- Stávající veřejné API a chování endpointů kalkulačky, které teď funguje.
- Databázové schéma stávajících tabulek (nové tabulky/migrace jsou v pořádku, přejmenování a mazání ne).
- Cizí testy, seed data a existující hodnoty. Když je změna nutná, dej ji do samostatného commitu a uveď ji. Pokud změna tvaru události nebo nový konzument nutně mění existující test, uprav ho v samostatném commitu a v závěru uveď proč.
- Veřejné kontrakty (API, schémata událostí) bez zpětné kompatibility.
## Hotovo, když
- Do brokeru jde pouze integrační událost.
- Contract test na schéma.
- Správný correlationId a causationId.
- JUnit 5 testy ve stávající struktuře `src/test/java` projdou build nástrojem projektu.
- V závěru uveď: co jsi změnil, co jsi předpokládal, co zbývá.# Úkol pro coding agenta: Odeslání žádosti
Stack: Java. Režim: challenge.
Cíl: Oddělit interní doménové události od integračních a publikovat jen stabilní kontrakt MortgageApplicationSubmitted.
## Kontext existujícího kódu
Pracuješ v existujícím projektu (Java backend (typicky Java 21, Spring Boot, JPA nebo JDBC). Použij build nástroj a styl, který projekt už má (Maven/Gradle, JUnit 5).).
Doména: hypoteční kalkulačka, která se postupně mění v event-driven systém (kalkulačka, rizika, schvalování, identita, účet, dokumenty, výplata).
Předpoklad: projekt má event store s feedem (odběr s checkpointem) a doménovou událost `ApplicationSubmitted`. Pokud ne, nejdřív založ minimální příkaz „odeslat žádost“ nad dokončeným výpočtem; bez brokeru stačí `publish(topic, event)` v paměti.
Nejdřív čti, nic neměň. Najdi a stručně shrň:
- Co dnes kalkulačka publikuje na broker/frontu a kdo to odebírá.
- Kontrakty (schémata) existujících zpráv.
- Které z těchto částí už v projektu existují a které chybí. Než napíšeš vlastní infrastrukturu (broker klient, outbox, retry), ověř, jestli ji projekt nebo organizace nemá jako hotovou knihovnu, a použij ji.
## Očekávané chování
Doménové události jsou interní. Když jdou do brokeru, odběratel se naváže na jejich tvar: Risk Service po změně `IncomeChanged` na v2 skončí v DLQ. Ven jde jen verzovaná `MortgageApplicationSubmitted`, např. `{ eventId, type, version: 1, occurredAt, correlationId, causationId, data: { applicationId, loanAmountMinor, monthlyPaymentMinor, monthlyIncomeMinor, termMonths } }`.
## Zadání (Challenge)
Při odeslání žádosti publikuj verzovanou integrační událost přeloženou z doménové a zajisti testem, že interní události ven nevytékají.
Technická specifika (Java): Mapper (MapStruct nebo ručně) do `record`; schéma ověř JSON Schema/Avro testem; publikace přes existující messaging vrstvu projektu.
Postup si zvol sám. Pasti v tomto tématu nejsou vypsané: najdi je (souběh, opakované doručení, pořadí, selhání uprostřed) a ke každé napiš test, který by ji odhalil. Na konci vypiš, jaké pasti jsi našel a které jsi vědomě nechal otevřené.
## Co nesmíš měnit
- Stávající veřejné API a chování endpointů kalkulačky, které teď funguje.
- Databázové schéma stávajících tabulek (nové tabulky/migrace jsou v pořádku, přejmenování a mazání ne).
- Cizí testy, seed data a existující hodnoty. Když je změna nutná, dej ji do samostatného commitu a uveď ji. Pokud změna tvaru události nebo nový konzument nutně mění existující test, uprav ho v samostatném commitu a v závěru uveď proč.
- Veřejné kontrakty (API, schémata událostí) bez zpětné kompatibility.
## Hotovo, když
- Do brokeru jde pouze integrační událost.
- Contract test na schéma.
- Správný correlationId a causationId.
- JUnit 5 testy ve stávající struktuře `src/test/java` projdou build nástrojem projektu.
- V závěru uveď: co jsi změnil, co jsi předpokládal, co zbývá.# Úkol pro coding agenta: Odeslání žádosti
Stack: C#. Režim: s vedením.
Cíl: Oddělit interní doménové události od integračních a publikovat jen stabilní kontrakt MortgageApplicationSubmitted.
## Kontext existujícího kódu
Pracuješ v existujícím projektu (C# backend (.NET, ASP.NET Core, EF Core nebo Dapper). Použij solution, styl a DI konvence, které projekt už má (xUnit/NUnit).).
Doména: hypoteční kalkulačka, která se postupně mění v event-driven systém (kalkulačka, rizika, schvalování, identita, účet, dokumenty, výplata).
Předpoklad: projekt má event store s feedem (odběr s checkpointem) a doménovou událost `ApplicationSubmitted`. Pokud ne, nejdřív založ minimální příkaz „odeslat žádost“ nad dokončeným výpočtem; bez brokeru stačí `publish(topic, event)` v paměti.
Nejdřív čti, nic neměň. Najdi a stručně shrň:
- Co dnes kalkulačka publikuje na broker/frontu a kdo to odebírá.
- Kontrakty (schémata) existujících zpráv.
- Které z těchto částí už v projektu existují a které chybí. Než napíšeš vlastní infrastrukturu (broker klient, outbox, retry), ověř, jestli ji projekt nebo organizace nemá jako hotovou knihovnu, a použij ji.
## Očekávané chování
Doménové události jsou interní. Když jdou do brokeru, odběratel se naváže na jejich tvar: Risk Service po změně `IncomeChanged` na v2 skončí v DLQ. Ven jde jen verzovaná `MortgageApplicationSubmitted`, např. `{ eventId, type, version: 1, occurredAt, correlationId, causationId, data: { applicationId, loanAmountMinor, monthlyPaymentMinor, monthlyIncomeMinor, termMonths } }`.
## Konkrétní úkol
Technická specifika (C#): Mapper do `record`; schéma ověř snapshot testem; publikace přes existující messaging knihovnu projektu.
Postupuj po krocích. Po bodu 1 (plán) napiš, co zjistíš a co navrhuješ, a počkej na potvrzení:
1. Plán: definuj integrační událost (jen pole, která konzumenti potřebují, verze 1, correlationId).
2. Přidej překladovou vrstvu doménová → integrační událost (anti-corruption).
3. Publikuj integrační událost při ApplicationSubmitted z feedu uložených událostí, ne z příkazu vedle zápisu; doménové události neopouštějí službu. `correlationId` z hlavičky požadavku (jinak nové) ulož do doménové události, `causationId` = id doménové události, `eventId` je při opakování stejné.
4. Contract test: schéma v1 je zafixované (změna souboru test shodí), změna interního tvaru ho nerozbije.
Na co si dát pozor:
- Integrační událost nesmí nést celý agregát.
- Pošli jen data, která konzument potřebuje a sám neodvodí.
## Co nesmíš měnit
- Stávající veřejné API a chování endpointů kalkulačky, které teď funguje.
- Databázové schéma stávajících tabulek (nové tabulky/migrace jsou v pořádku, přejmenování a mazání ne).
- Cizí testy, seed data a existující hodnoty. Když je změna nutná, dej ji do samostatného commitu a uveď ji. Pokud změna tvaru události nebo nový konzument nutně mění existující test, uprav ho v samostatném commitu a v závěru uveď proč.
- Veřejné kontrakty (API, schémata událostí) bez zpětné kompatibility.
## Hotovo, když
- Do brokeru jde pouze integrační událost.
- Contract test na schéma.
- Správný correlationId a causationId.
- Testy ve stávajícím testovacím projektu projdou (`dotnet test`).
- V závěru uveď: co jsi změnil, co jsi předpokládal, co zbývá.# Úkol pro coding agenta: Odeslání žádosti
Stack: C#. Režim: challenge.
Cíl: Oddělit interní doménové události od integračních a publikovat jen stabilní kontrakt MortgageApplicationSubmitted.
## Kontext existujícího kódu
Pracuješ v existujícím projektu (C# backend (.NET, ASP.NET Core, EF Core nebo Dapper). Použij solution, styl a DI konvence, které projekt už má (xUnit/NUnit).).
Doména: hypoteční kalkulačka, která se postupně mění v event-driven systém (kalkulačka, rizika, schvalování, identita, účet, dokumenty, výplata).
Předpoklad: projekt má event store s feedem (odběr s checkpointem) a doménovou událost `ApplicationSubmitted`. Pokud ne, nejdřív založ minimální příkaz „odeslat žádost“ nad dokončeným výpočtem; bez brokeru stačí `publish(topic, event)` v paměti.
Nejdřív čti, nic neměň. Najdi a stručně shrň:
- Co dnes kalkulačka publikuje na broker/frontu a kdo to odebírá.
- Kontrakty (schémata) existujících zpráv.
- Které z těchto částí už v projektu existují a které chybí. Než napíšeš vlastní infrastrukturu (broker klient, outbox, retry), ověř, jestli ji projekt nebo organizace nemá jako hotovou knihovnu, a použij ji.
## Očekávané chování
Doménové události jsou interní. Když jdou do brokeru, odběratel se naváže na jejich tvar: Risk Service po změně `IncomeChanged` na v2 skončí v DLQ. Ven jde jen verzovaná `MortgageApplicationSubmitted`, např. `{ eventId, type, version: 1, occurredAt, correlationId, causationId, data: { applicationId, loanAmountMinor, monthlyPaymentMinor, monthlyIncomeMinor, termMonths } }`.
## Zadání (Challenge)
Při odeslání žádosti publikuj verzovanou integrační událost přeloženou z doménové a zajisti testem, že interní události ven nevytékají.
Technická specifika (C#): Mapper do `record`; schéma ověř snapshot testem; publikace přes existující messaging knihovnu projektu.
Postup si zvol sám. Pasti v tomto tématu nejsou vypsané: najdi je (souběh, opakované doručení, pořadí, selhání uprostřed) a ke každé napiš test, který by ji odhalil. Na konci vypiš, jaké pasti jsi našel a které jsi vědomě nechal otevřené.
## Co nesmíš měnit
- Stávající veřejné API a chování endpointů kalkulačky, které teď funguje.
- Databázové schéma stávajících tabulek (nové tabulky/migrace jsou v pořádku, přejmenování a mazání ne).
- Cizí testy, seed data a existující hodnoty. Když je změna nutná, dej ji do samostatného commitu a uveď ji. Pokud změna tvaru události nebo nový konzument nutně mění existující test, uprav ho v samostatném commitu a v závěru uveď proč.
- Veřejné kontrakty (API, schémata událostí) bez zpětné kompatibility.
## Hotovo, když
- Do brokeru jde pouze integrační událost.
- Contract test na schéma.
- Správný correlationId a causationId.
- Testy ve stávajícím testovacím projektu projdou (`dotnet test`).
- V závěru uveď: co jsi změnil, co jsi předpokládal, co zbývá.# Úkol pro coding agenta: Odeslání žádosti
Stack: Web (HTML/JS nebo stack aplikace). Režim: s vedením.
Cíl: Oddělit interní doménové události od integračních a publikovat jen stabilní kontrakt MortgageApplicationSubmitted.
## Kontext existujícího kódu
Pracuješ v existujícím projektu (webová aplikace: frontend v prohlížeči, případně s vlastním backendem. Když má projekt backend, patří event store, broker a služby na backend a body o endpointech a tabulkách se týkají jeho. Když backend nemá, použij IndexedDB v prohlížeči a v testech `fake-indexeddb`. Framework a test runner projektu zachovej; nové závislosti přidávej jen s odůvodněním.).
Doména: hypoteční kalkulačka, která se postupně mění v event-driven systém (kalkulačka, rizika, schvalování, identita, účet, dokumenty, výplata).
Předpoklad: projekt má event store s feedem (odběr s checkpointem) a doménovou událost `ApplicationSubmitted`. Pokud ne, nejdřív založ minimální příkaz „odeslat žádost“ nad dokončeným výpočtem; bez brokeru stačí `publish(topic, event)` v paměti.
Nejdřív čti, nic neměň. Najdi a stručně shrň:
- Co dnes kalkulačka publikuje na broker/frontu a kdo to odebírá.
- Kontrakty (schémata) existujících zpráv.
- Které z těchto částí už v projektu existují a které chybí. Než napíšeš vlastní infrastrukturu (broker klient, outbox, retry), ověř, jestli ji projekt nebo organizace nemá jako hotovou knihovnu, a použij ji.
## Očekávané chování
Doménové události jsou interní. Když jdou do brokeru, odběratel se naváže na jejich tvar: Risk Service po změně `IncomeChanged` na v2 skončí v DLQ. Ven jde jen verzovaná `MortgageApplicationSubmitted`, např. `{ eventId, type, version: 1, occurredAt, correlationId, causationId, data: { applicationId, loanAmountMinor, monthlyPaymentMinor, monthlyIncomeMinor, termMonths } }`.
## Konkrétní úkol
Technická specifika (Web (HTML/JS nebo stack aplikace)): Funkce `toIntegrationEvent(domainEvent)`; schéma ověř testem validátorem projektu (Zod, Ajv), jinak ruční kontrolou tvaru.
Postupuj po krocích. Po bodu 1 (plán) napiš, co zjistíš a co navrhuješ, a počkej na potvrzení:
1. Plán: definuj integrační událost (jen pole, která konzumenti potřebují, verze 1, correlationId).
2. Přidej překladovou vrstvu doménová → integrační událost (anti-corruption).
3. Publikuj integrační událost při ApplicationSubmitted z feedu uložených událostí, ne z příkazu vedle zápisu; doménové události neopouštějí službu. `correlationId` z hlavičky požadavku (jinak nové) ulož do doménové události, `causationId` = id doménové události, `eventId` je při opakování stejné.
4. Contract test: schéma v1 je zafixované (změna souboru test shodí), změna interního tvaru ho nerozbije.
Na co si dát pozor:
- Integrační událost nesmí nést celý agregát.
- Pošli jen data, která konzument potřebuje a sám neodvodí.
## Co nesmíš měnit
- Stávající veřejné API a chování endpointů kalkulačky, které teď funguje.
- Databázové schéma stávajících tabulek (nové tabulky/migrace jsou v pořádku, přejmenování a mazání ne).
- Cizí testy, seed data a existující hodnoty. Když je změna nutná, dej ji do samostatného commitu a uveď ji. Pokud změna tvaru události nebo nový konzument nutně mění existující test, uprav ho v samostatném commitu a v závěru uveď proč.
- Veřejné kontrakty (API, schémata událostí) bez zpětné kompatibility.
## Hotovo, když
- Do brokeru jde pouze integrační událost.
- Contract test na schéma.
- Správný correlationId a causationId.
- Testy projdou stávajícím test runnerem; lint a build projdou, pokud je projekt má.
- V závěru uveď: co jsi změnil, co jsi předpokládal, co zbývá.# Úkol pro coding agenta: Odeslání žádosti
Stack: Web (HTML/JS nebo stack aplikace). Režim: challenge.
Cíl: Oddělit interní doménové události od integračních a publikovat jen stabilní kontrakt MortgageApplicationSubmitted.
## Kontext existujícího kódu
Pracuješ v existujícím projektu (webová aplikace: frontend v prohlížeči, případně s vlastním backendem. Když má projekt backend, patří event store, broker a služby na backend a body o endpointech a tabulkách se týkají jeho. Když backend nemá, použij IndexedDB v prohlížeči a v testech `fake-indexeddb`. Framework a test runner projektu zachovej; nové závislosti přidávej jen s odůvodněním.).
Doména: hypoteční kalkulačka, která se postupně mění v event-driven systém (kalkulačka, rizika, schvalování, identita, účet, dokumenty, výplata).
Předpoklad: projekt má event store s feedem (odběr s checkpointem) a doménovou událost `ApplicationSubmitted`. Pokud ne, nejdřív založ minimální příkaz „odeslat žádost“ nad dokončeným výpočtem; bez brokeru stačí `publish(topic, event)` v paměti.
Nejdřív čti, nic neměň. Najdi a stručně shrň:
- Co dnes kalkulačka publikuje na broker/frontu a kdo to odebírá.
- Kontrakty (schémata) existujících zpráv.
- Které z těchto částí už v projektu existují a které chybí. Než napíšeš vlastní infrastrukturu (broker klient, outbox, retry), ověř, jestli ji projekt nebo organizace nemá jako hotovou knihovnu, a použij ji.
## Očekávané chování
Doménové události jsou interní. Když jdou do brokeru, odběratel se naváže na jejich tvar: Risk Service po změně `IncomeChanged` na v2 skončí v DLQ. Ven jde jen verzovaná `MortgageApplicationSubmitted`, např. `{ eventId, type, version: 1, occurredAt, correlationId, causationId, data: { applicationId, loanAmountMinor, monthlyPaymentMinor, monthlyIncomeMinor, termMonths } }`.
## Zadání (Challenge)
Při odeslání žádosti publikuj verzovanou integrační událost přeloženou z doménové a zajisti testem, že interní události ven nevytékají.
Technická specifika (Web (HTML/JS nebo stack aplikace)): Funkce `toIntegrationEvent(domainEvent)`; schéma ověř testem validátorem projektu (Zod, Ajv), jinak ruční kontrolou tvaru.
Postup si zvol sám. Pasti v tomto tématu nejsou vypsané: najdi je (souběh, opakované doručení, pořadí, selhání uprostřed) a ke každé napiš test, který by ji odhalil. Na konci vypiš, jaké pasti jsi našel a které jsi vědomě nechal otevřené.
## Co nesmíš měnit
- Stávající veřejné API a chování endpointů kalkulačky, které teď funguje.
- Databázové schéma stávajících tabulek (nové tabulky/migrace jsou v pořádku, přejmenování a mazání ne).
- Cizí testy, seed data a existující hodnoty. Když je změna nutná, dej ji do samostatného commitu a uveď ji. Pokud změna tvaru události nebo nový konzument nutně mění existující test, uprav ho v samostatném commitu a v závěru uveď proč.
- Veřejné kontrakty (API, schémata událostí) bez zpětné kompatibility.
## Hotovo, když
- Do brokeru jde pouze integrační událost.
- Contract test na schéma.
- Správný correlationId a causationId.
- Testy projdou stávajícím test runnerem; lint a build projdou, pokud je projekt má.
- V závěru uveď: co jsi změnil, co jsi předpokládal, co zbývá.Související části prezentace
Školení pro váš tým
Chcete školení pro svůj tým?
Školení vedeme na vašem kódu a vašem doménovém problému. Domluvíme rozsah, termín a formu.
Probrat školení