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ím

Co 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.

Jazyk
Varianta
# Ú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á.

Š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í