<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog on SaaSForge</title><link>https://saasforge.cz/cs/blog/</link><description>Recent content in Blog on SaaSForge</description><generator>Hugo</generator><language>cs</language><lastBuildDate>Mon, 04 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://saasforge.cz/cs/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>Spring Modulith v praxi: Od kódu k živým architektonickým diagramům</title><link>https://saasforge.cz/cs/blog/spring-modulith-c4-documentation/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/spring-modulith-c4-documentation/</guid><description>&lt;p&gt;Váš architektonický diagram v Confluence je šest měsíců starý. Ten na wiki stále ukazuje Auth modul, který byl sloučen do Usera už v lednu. Tabule v zasedačce? Někdo ji smazal, aby nakreslil retrospektivu sprintu.&lt;/p&gt;
&lt;p&gt;Architektonická dokumentace má zásadní problém: udržují ji lidé a lidé zapomínají. Kód se mění denně. Diagramy se mění, když si někdo vzpomene. Nakonec je mezera tak velká, že všichni přestanou diagramům věřit a začnou číst přímo kód — čímž se celý smysl diagramů ztrácí.&lt;/p&gt;</description></item><item><title>Kamal vs Flux CD: Jednoduchost nebo odolnost — vyberte si</title><link>https://saasforge.cz/cs/blog/kamal-vs-flux-simplicity-or-resilience/</link><pubDate>Mon, 27 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/kamal-vs-flux-simplicity-or-resilience/</guid><description>&lt;p&gt;Váš kontejner spadl ve 3 ráno. S Flux CD si toho cluster všiml, restartoval pod a sesynchronizoval požadovaný stav z Gitu. Dozvěděli jste se o tom z notifikace na Slacku u ranní kávy. S Kamalem — nikdo si ničeho nevšiml. Vaše aplikace byla čtyři hodiny nedostupná. První, kdo si toho všiml, byl zákazník, a neposlal bug report. Prostě odešel.&lt;/p&gt;
&lt;p&gt;Toto je zásadní rozdíl mezi Kamalem a Flux CD a je důležitější, než většina srovnávacích článků připouští. Nejde o to, který nástroj je &amp;ldquo;lepší.&amp;rdquo; Jde o to, zda je váš nasazovací nástroj zodpovědný za to, že vaše aplikace běží, nebo jen za to, že ji tam umístí.&lt;/p&gt;</description></item><item><title>Spring Modulith v praxi: Vynucování architektury v rostoucím monolitu</title><link>https://saasforge.cz/cs/blog/spring-modulith-in-practice/</link><pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/spring-modulith-in-practice/</guid><description>&lt;p&gt;Každá rostoucí Spring Boot aplikace dospěje do bodu, kdy někdo nakreslí hranice modulů na tabuli. Krabičky s čistými šipkami. „Venue závisí na Site, ale ne na internals Useru.&amp;quot; Všichni přikývnou. O dva sprinty později vývojář importuje repository z modulu, na kterém by neměl záviset, protože je to nejrychlejší cesta k opravě bugu. Nikdo si toho v code review nevšimne. Diagram na tabuli je teď fikce.&lt;/p&gt;
&lt;p&gt;Spring Modulith mění ty šipky na tabuli na selhání buildu.&lt;/p&gt;</description></item><item><title>Mise vs SDKMAN: Proč přecházím po letech s .sdkmanrc</title><link>https://saasforge.cz/cs/blog/mise-vs-sdkman/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/mise-vs-sdkman/</guid><description>&lt;p&gt;Kolega dnes zmínil &lt;a href="https://mise.jdx.dev/"&gt;Mise&lt;/a&gt;. Jsem věrný uživatel SDKMAN už roky — &lt;code&gt;.sdkmanrc&lt;/code&gt; v každém projektu, &lt;code&gt;sdk use java 21.0.2-tem&lt;/code&gt; vrytý do svalové paměti. Funguje to, je to spolehlivé, nikdy jsem neměl důvod hledat jinde.&lt;/p&gt;
&lt;p&gt;Pak jsem se ale podíval, co Mise umí, a nejsem si jistý, jestli se můžu vrátit.&lt;/p&gt;
&lt;h2 id="problém-s-jedním-nástrojem-na-jazyk"&gt;Problém s jedním nástrojem na jazyk&lt;/h2&gt;
&lt;p&gt;SDKMAN spravuje JDK (a Gradle, Maven a pár dalších JVM nástrojů). Dělá to dobře. Ale moje projekty nepotřebují jen Javu:&lt;/p&gt;</description></item><item><title>Jak používáme Claude Code Skills k formalizaci našich vývojových vzorů</title><link>https://saasforge.cz/cs/blog/claude-code-skills-guide/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/claude-code-skills-guide/</guid><description>&lt;p&gt;Každý kód má své vzory. Způsob, jakým píšete testy, strukturujete komponenty, propojujete API — tyto konvence žijí v kolektivní paměti týmu, roztroušené mezi code reviews, onboardingovými dokumenty a kmenovou znalostí. Když do mixu přidáte AI asistenta pro kódování, nic z toho nezná. Napíše naprosto validní kód, který poruší každou konvenci, kterou jste zavedli.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.anthropic.com/en/docs/claude-code/skills"&gt;Claude Code Skills&lt;/a&gt; tento problém řeší tím, že vám umožní zakódovat vaše vzory jako znovupoužitelné šablony, které Claude automaticky načte, když je to relevantní.&lt;/p&gt;</description></item><item><title>Observabilita a optimalizace vašeho GraphQL API</title><link>https://saasforge.cz/cs/blog/dgs-observing-optimizing-graphql/</link><pubDate>Thu, 09 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/dgs-observing-optimizing-graphql/</guid><description>&lt;p&gt;&lt;em&gt;Část 7 série „Production GraphQL with Netflix DGS&amp;quot; — Bonus: Provoz&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;GraphQL API jsou pro tradiční monitoring neviditelná. Každý request dorazí na stejný endpoint &lt;code&gt;/graphql&lt;/code&gt;, vrátí HTTP 200 (i když tělo odpovědi obsahuje chyby) a nenese žádný URL-based kontext pro vaše dashboardy. Pokud monitorujete GraphQL API stejně jako REST, letíte naslepo.&lt;/p&gt;
&lt;p&gt;Tento článek pokrývá vrstvu observability a optimalizace nad vaším DGS backendem: &lt;strong&gt;federation s GraphQL routerem&lt;/strong&gt;, &lt;strong&gt;identifikace klientů&lt;/strong&gt;, &lt;strong&gt;metriky na úrovni operací&lt;/strong&gt;, &lt;strong&gt;klasifikace chyb&lt;/strong&gt;, &lt;strong&gt;analytika schématu&lt;/strong&gt; a &lt;strong&gt;techniky optimalizace výkonu&lt;/strong&gt;, které zabrání vašemu API stát se úzkým hrdlem.&lt;/p&gt;</description></item><item><title>Typově bezpečné GraphQL na frontendu</title><link>https://saasforge.cz/cs/blog/dgs-frontend-type-safety/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/dgs-frontend-type-safety/</guid><description>&lt;p&gt;&lt;em&gt;Šestý díl ze sedmi v sérii &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo; — Bonus: Klientská strana&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Předchozích pět článků pokrývalo backend: návrh schématu, data loadery, zabezpečení, subscriptions a škálování. Typová bezpečnost ale nekončí na hranici API. Tento článek ukazuje, jak ji přenést až do Vue (nebo React) komponenty — a jak návrh fragmentů brání tichému zabijákovi výkonu, kterým je overfetching.&lt;/p&gt;
&lt;h2 id="problém-se-string-dotazy"&gt;Problém se string dotazy&lt;/h2&gt;
&lt;p&gt;Většina GraphQL tutoriálů začíná nějak takto:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__header"&gt;
 &lt;span class="code-block__lang"&gt;TYPESCRIPT&lt;/span&gt;
 &lt;button class="code-block__copy" onclick="let c=this.closest('.code-block').querySelector('pre'),i=this.querySelector('.material-icons-outlined');navigator.clipboard.writeText(c.textContent);i.textContent='check';setTimeout(()=&gt;i.textContent='content_copy',2000)"&gt;&lt;span class="material-icons-outlined"&gt;content_copy&lt;/span&gt;&lt;/button&gt;
 &lt;/div&gt;&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-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/graphql&amp;#39;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;method&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;JSON.stringify&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;query&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; query {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; product(id: &amp;#34;123&amp;#34;) {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; id
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; name
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; price
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; `&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;data&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;json&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// data.data.product.name — je to string? Objekt? Kdo ví.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Tohle funguje. Je to ale také past na údržbu:&lt;/p&gt;</description></item><item><title>DGS ve velkém měřítku: Testování, evoluce schématu a federation</title><link>https://saasforge.cz/cs/blog/dgs-at-scale/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/dgs-at-scale/</guid><description>&lt;p&gt;&lt;em&gt;Část 5 ze 7 v sérii „Production GraphQL with Netflix DGS&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Postavit GraphQL API je jedna věc. Provozovat stovky operací v produkci, spolehlivě je testovat a vyvíjet schéma bez rozbití klientů — to je teprve začátek skutečného inženýrství. Tento závěrečný článek pokrývá postupy, na kterých záleží, jakmile vaše DGS API přeroste pár dotazů.&lt;/p&gt;
&lt;h2 id="testování-dgs-komponent"&gt;Testování DGS komponent&lt;/h2&gt;
&lt;p&gt;DGS data fetchery jsou Spring beany s injektovanými závislostmi. To je činí přímočarými pro unit testování — zamockujte závislosti, zavolejte metodu, ověřte výsledek.&lt;/p&gt;</description></item><item><title>Virtuální vlákna nezabila WebFlux</title><link>https://saasforge.cz/cs/blog/virtual-threads-vs-webflux/</link><pubDate>Mon, 23 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/virtual-threads-vs-webflux/</guid><description>&lt;p&gt;Každých pár měsíců někdo publikuje benchmark ukazující, že virtuální vlákna zvládnou 100 000 souběžných requestů s jednoduchým imperativním kódem, a dojde k závěru, že WebFlux je zastaralý. Komentáře se plní větami jako „konečně žádné reaktivní špagety.&amp;quot; Manažeři přepošlou článek svým týmům: „Můžeme to přepsat na virtuální vlákna?&amp;quot;&lt;/p&gt;
&lt;p&gt;Ne. Tedy — záleží na tom, co to „to&amp;quot; dělá. Ale pravděpodobně ne.&lt;/p&gt;
&lt;p&gt;Virtuální vlákna a WebFlux řeší různé problémy. Zmatek pochází z toho, že se obě technologie objevují ve větě „efektivně zpracovat mnoho souběžných requestů.&amp;quot; To je ale jako říct, že kladivo a šroubovák jsou konkurenti, protože oba „spojují věci dohromady.&amp;quot;&lt;/p&gt;</description></item><item><title>Real-time a reaktivní vzory s Netflix DGS</title><link>https://saasforge.cz/cs/blog/dgs-realtime-reactive-patterns/</link><pubDate>Thu, 19 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/dgs-realtime-reactive-patterns/</guid><description>&lt;p&gt;&lt;em&gt;Čtvrtý díl ze sedmi v sérii &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;REST API fungují na principu request-response: klient se zeptá, server odpoví, spojení se zavře. GraphQL subscriptions tento vzor narušují — server posílá aktualizace klientovi v okamžiku, kdy nastanou. Tento článek popisuje, jak DGS implementuje subscriptions, jak fungují reaktivní typy napříč frameworkem a jak to celé monitorovat v produkci.&lt;/p&gt;
&lt;h2 id="graphql-subscriptions"&gt;GraphQL Subscriptions&lt;/h2&gt;
&lt;p&gt;Subscriptions umožňují klientům přijímat proud aktualizací přes persistentní spojení. Typické případy použití: živé výsledkové tabule, sledování průběhu, notifikace, kolaborativní editace.&lt;/p&gt;</description></item><item><title>Přestaňte bourat dům kvůli výměně nábytku: Proč je GitOps lepší než push-based deployment</title><link>https://saasforge.cz/cs/blog/gitops-pull-vs-push-deployment/</link><pubDate>Mon, 16 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/gitops-pull-vs-push-deployment/</guid><description>&lt;p&gt;Chcete nasadit novou verzi API. Změna jednoho řádku: posunout image tag z &lt;code&gt;v1.4.2&lt;/code&gt; na &lt;code&gt;v1.4.3&lt;/code&gt;. S GitOps setupem pushnete do Gitu a za 30 sekund je cluster srovnaný. S push-based přístupem, který stále vidím v produkci — Helm charty publikované Terraformem — spustíte pipeline, která naplánuje celou infrastrukturu, vyhodnotí každý resource, čeká na schválení a pak aplikuje změnu. To je jako bourat dům kvůli výměně nábytku.&lt;/p&gt;
&lt;p&gt;A přesto push-based deployment přes Terraform zůstává pozoruhodně populární. Manažeři ho mají rádi, protože vidí tlačítko &amp;ldquo;Deploy&amp;rdquo; v CI/CD rozhraní. Inženýři ho používají ze setrvačnosti, protože Terraform už spravuje cluster. Ale cena je reálná — v délce pipeline, v blast radius, v provázanosti a v operační odolnosti.&lt;/p&gt;</description></item><item><title>Zabezpečení GraphQL API s Netflix DGS</title><link>https://saasforge.cz/cs/blog/dgs-securing-graphql-api/</link><pubDate>Thu, 12 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/dgs-securing-graphql-api/</guid><description>&lt;p&gt;&lt;em&gt;Třetí díl ze sedmi v sérii &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;GraphQL dává klientům mimořádnou flexibilitu — sami si volí, která pole načíst, jak hluboko zanořit dotaz a kolik operací poslat naráz. Tato flexibilita je zároveň vaším útočným povrchem. Tento článek pokrývá tři vrstvy obrany, které potřebuje každé produkční GraphQL API: &lt;strong&gt;autentizaci a autorizaci&lt;/strong&gt;, &lt;strong&gt;sanitizaci chyb&lt;/strong&gt; a &lt;strong&gt;ochranu proti zneužití dotazů&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="vrstva-1-autentizace-a-autorizace"&gt;Vrstva 1: Autentizace a autorizace&lt;/h2&gt;
&lt;p&gt;DGS běží uvnitř Spring Bootu, takže máte k dispozici kompletní toolkit Spring Security. Nejpraktičtějším vzorem jsou &lt;strong&gt;anotace &lt;code&gt;@PreAuthorize&lt;/code&gt; přímo na DGS metodách&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>Testování Axon 5 agregátů pomocí Spocku: Praktický průvodce</title><link>https://saasforge.cz/cs/blog/axon5-spock-aggregate-testing/</link><pubDate>Mon, 09 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/axon5-spock-aggregate-testing/</guid><description>&lt;p&gt;Event-sourcingový model Axon Frameworku se přirozeně snoubí s expresivním &lt;code&gt;given-when-then&lt;/code&gt; stylem Spocku. Přesto většina příkladů online ukazuje JUnit. Tento průvodce pokrývá, jak testovat kompletní stavový automat Axon 5 agregátu pomocí Spocku a &lt;code&gt;AxonTestFixture&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="doména-agregát-objednávky"&gt;Doména: Agregát objednávky&lt;/h2&gt;
&lt;p&gt;Použijeme jednoduchý životní cyklus objednávky:&lt;/p&gt;
&lt;div class="mermaid"&gt;stateDiagram-v2
 [*] --&gt; CREATED
 CREATED --&gt; CONFIRMED: confirm
 CONFIRMED --&gt; SHIPPED: ship
 SHIPPED --&gt; DELIVERED: deliver
 CREATED --&gt; CANCELLED: cancel
 CONFIRMED --&gt; CANCELLED: cancel
&lt;/div&gt;
&lt;p&gt;Agregát sleduje stav pomocí &lt;code&gt;@EventSourcingHandler&lt;/code&gt; metod, které přehrávají uložené eventy:&lt;/p&gt;</description></item><item><title>Řešení N+1 problému pomocí Data Loaderů a Field Resolverů</title><link>https://saasforge.cz/cs/blog/dgs-data-loaders-field-resolvers/</link><pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/dgs-data-loaders-field-resolvers/</guid><description>&lt;p&gt;&lt;em&gt;Druhý díl ze 7 v sérii „Production GraphQL with Netflix DGS&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;GraphQL dává klientům možnost požádat přesně o ta data, která potřebují. To je jeho síla — a zároveň jeho past. Bez pečlivého návrhu backendu může jediný dotaz vyvolat stovky databázových volání. Tento článek ukazuje, jak tomu DGS data loadery a field resolvery zabraňují.&lt;/p&gt;
&lt;h2 id="n1-problém-vizuálně"&gt;N+1 problém vizuálně&lt;/h2&gt;
&lt;p&gt;Představte si jednoduchý dotaz, který načítá objednávky s jejich produkty:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__header"&gt;
 &lt;span class="code-block__lang"&gt;GRAPHQL&lt;/span&gt;
 &lt;button class="code-block__copy" onclick="let c=this.closest('.code-block').querySelector('pre'),i=this.querySelector('.material-icons-outlined');navigator.clipboard.writeText(c.textContent);i.textContent='check';setTimeout(()=&gt;i.textContent='content_copy',2000)"&gt;&lt;span class="material-icons-outlined"&gt;content_copy&lt;/span&gt;&lt;/button&gt;
 &lt;/div&gt;&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-graphql" data-lang="graphql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;query&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;orders&lt;/span&gt;(pageNumber: &lt;span style="color:#a6e22e"&gt;0&lt;/span&gt;, pageSize: &lt;span style="color:#a6e22e"&gt;20&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; items {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; status
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; product { &lt;span style="color:#75715e"&gt;# ← This field is the problem&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; price
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Bez optimalizace se na backendu stane následující:&lt;/p&gt;</description></item><item><title>Schema-first GraphQL s Netflix DGS</title><link>https://saasforge.cz/cs/blog/dgs-schema-first-graphql/</link><pubDate>Thu, 26 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/dgs-schema-first-graphql/</guid><description>&lt;p&gt;&lt;em&gt;1. díl ze 7 série &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Pokud stavíte GraphQL API se Spring Bootem, pravděpodobně jste si všimli dvou velkých frameworků soupeřících o vaši pozornost: &lt;strong&gt;Netflix DGS&lt;/strong&gt; a &lt;strong&gt;Spring for GraphQL&lt;/strong&gt;. Roky si týmy musely vybrat jednu stranu. Tato volba už neexistuje — a příběh toho, jak tyto frameworky splynuly, stojí za pochopení dřív, než napíšete svůj první &lt;code&gt;@DgsQuery&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="dva-frameworky-se-staly-jedním"&gt;Dva frameworky se staly jedním&lt;/h2&gt;
&lt;p&gt;Netflix open-sourcoval framework Domain Graph Service (DGS) v roce 2021. Byl ověřený na Netflixím měřítku — stovky služeb, tisíce dotazů — a nabízel něco, co Spring v té době neměl: propracovaný, anotacemi řízený programovací model pro GraphQL.&lt;/p&gt;</description></item><item><title>Tichá mezera v metadatech: Proč vaše Axon 5 eventy nemají atribuci uživatele</title><link>https://saasforge.cz/cs/blog/axon5-command-metadata-propagation/</link><pubDate>Wed, 25 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/axon5-command-metadata-propagation/</guid><description>&lt;p&gt;Když jsme migrovali z Axon Framework 4 na 5, pečlivě jsme aktualizovali agregáty na &lt;code&gt;EventAppender&lt;/code&gt;, přepsali command handlery na statické tovární metody a upravili event sourcing handlery. Vše se zkompilovalo. Testy prošly. Eventy proudily. Pak jsme během interního QA kola zpozorovali něco zvláštního: timeline historie agregátu ukazovala eventy bez autora — jen časové značky a typy eventů vznášející se v prázdnu.&lt;/p&gt;
&lt;p&gt;Příčina? &lt;strong&gt;Metadata příkazů v Axonu se automaticky nepropagují do eventů.&lt;/strong&gt; A když se soustředíte na velké změny migrace na Axon 5, přesně tohle je věc, která vám proklouzne.&lt;/p&gt;</description></item><item><title>Váš MCP Server funguje lokálně. Pak Kubernetes zabije session.</title><link>https://saasforge.cz/cs/blog/mcp-stateless-kubernetes/</link><pubDate>Mon, 23 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/mcp-stateless-kubernetes/</guid><description>&lt;p&gt;Provozujeme Spring AI MCP server v produkci na GKE. Slouží Claude Code jako klient a vystavuje 60+ nástrojů pro správu lezeckých dat — lokality, cesty, stěny, prostě všechno. Autentizační vrstva je solidní: JWT tokeny perzistované v PostgreSQL, duální validace (HS256 service tokeny, RS256 OAuth uživatelské tokeny), kontrola revokace při každém požadavku.&lt;/p&gt;
&lt;p&gt;Pak, občasně, Claude Code začne vyhazovat toto:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__header"&gt;
 &lt;span class="code-block__lang"&gt;Text&lt;/span&gt;
 &lt;button class="code-block__copy" onclick="let c=this.closest('.code-block').querySelector('pre'),i=this.querySelector('.material-icons-outlined');navigator.clipboard.writeText(c.textContent);i.textContent='check';setTimeout(()=&gt;i.textContent='content_copy',2000)"&gt;&lt;span class="material-icons-outlined"&gt;content_copy&lt;/span&gt;&lt;/button&gt;
 &lt;/div&gt;&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-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Session not found: f4456324-79fb-4d84-ab2b-eebf27c5a475&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Token je platný. Server běží. Endpoint odpovídá. Ale session je pryč.&lt;/p&gt;</description></item><item><title>Nahrazení Flux Bootstrap operátorem Flux: GitOps na autopilota</title><link>https://saasforge.cz/cs/blog/flux-operator-gitops/</link><pubDate>Fri, 20 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/flux-operator-gitops/</guid><description>&lt;p&gt;Správa Flux CD v produkci dříve znamenala spuštění &lt;code&gt;flux bootstrap&lt;/code&gt;, commitnutí stovek řádků generovaného YAML a manuální koordinaci upgradů napříč clustery. S &lt;a href="https://github.com/controlplaneio-fluxcd/flux-operator"&gt;Flux Operátorem&lt;/a&gt; je toto vše nahrazeno jediným Kubernetes custom resource — &lt;strong&gt;FluxInstance&lt;/strong&gt; — který deklaruje celou vaši Flux instalaci jako kód.&lt;/p&gt;
&lt;p&gt;V tomto článku projdeme, jak jsme migrovali z tradičního Flux bootstrap přístupu na Flux Operator na GKE Autopilot clusteru, celé řízeno Terraformem.&lt;/p&gt;
&lt;h2 id="co-je-flux-operator"&gt;Co je Flux Operator?&lt;/h2&gt;
&lt;img src="https://saasforge.cz/assets/flux-operator-logo.svg" alt="Flux Operator" style="height: 48px; margin-bottom: 16px;"&gt;
&lt;p&gt;Flux Operator je Kubernetes controller vyvinutý společností &lt;a href="https://control-plane.io/"&gt;ControlPlane&lt;/a&gt;, který spravuje životní cyklus instalací &lt;a href="https://fluxcd.io/"&gt;Flux CD&lt;/a&gt;. Místo bootstrapování Fluxu přes CLI (které generuje a commituje &lt;code&gt;gotk-components.yaml&lt;/code&gt; a &lt;code&gt;gotk-sync.yaml&lt;/code&gt; do vašeho repozitáře) nainstalujete operátor jednou a pak deklarujete &lt;code&gt;FluxInstance&lt;/code&gt; custom resource popisující, co chcete.&lt;/p&gt;</description></item><item><title>Propagace identity uživatele v Axon 5 query handlerech</title><link>https://saasforge.cz/cs/blog/axon5-query-auth-metadata/</link><pubDate>Wed, 18 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/axon5-query-auth-metadata/</guid><description>&lt;p&gt;&lt;strong&gt;Aktualizace (březen 2026):&lt;/strong&gt; &lt;a href="https://github.com/AxonFramework/AxonFramework/issues/4207"&gt;Nahlásili jsme tento problém&lt;/a&gt; týmu Axon Frameworku. Jádro problému — prázdný &lt;code&gt;ReactiveSecurityContextHolder&lt;/code&gt; uvnitř &lt;code&gt;@QueryHandler&lt;/code&gt; — je nyní sledováno jako &lt;a href="https://github.com/AxonFramework/AxonFramework/issues/4207"&gt;GitHub issue #4207&lt;/a&gt;. Viz &lt;a href="https://saasforge.cz/cs/blog/axon5-query-auth-metadata/#aktualizace-issue-nahl%c3%a1%c5%a1eno-v-axon-frameworku"&gt;sekce s aktualizací&lt;/a&gt; níže.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Během interního testování nové verze jsme narazili na záhadný bug: vlastníci neviděli své vlastní entity na správcovské stránce. Chybová zpráva byla jednoduše &amp;ldquo;Unable to load&amp;rdquo; — přestože záznam v databázi prokazatelně existoval.&lt;/p&gt;
&lt;p&gt;Naše aplikace používá &lt;strong&gt;Axon Framework 5&lt;/strong&gt; se &lt;strong&gt;Spring WebFlux&lt;/strong&gt; a &lt;strong&gt;Netflix DGS&lt;/strong&gt; (GraphQL). Query handler dělal něco zdánlivě rozumného — kontroloval, zda je autentizovaný uživatel vlastníkem, před vrácením INACTIVE záznamů:&lt;/p&gt;</description></item><item><title>Migrace z Axon Framework 4 na 5: Co jsme se naučili</title><link>https://saasforge.cz/cs/blog/axon-framework-4-to-5-migration/</link><pubDate>Mon, 16 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/axon-framework-4-to-5-migration/</guid><description>&lt;p&gt;Provozujeme CQRS/Event Sourcing backend — nyní spokojeně na Java 25, Spring Boot 4 a Axon Framework 5. Ale cesta sem z Axon 4.12 nebyla jednoduchá. Codebase obsahuje desítky agregátů, více ság, přes stovku typů událostí a stovky anotovaných handler metod.&lt;/p&gt;
&lt;p&gt;Tady je, co jsme se naučili.&lt;/p&gt;
&lt;h2 id="proč-jsme-chtěli-axon-5"&gt;Proč jsme chtěli Axon 5&lt;/h2&gt;
&lt;p&gt;Motivace byla jednoduchá: &lt;strong&gt;nativní reaktivní podpora v event handlerech&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Axon 4.x má známý problém se subscribing event procesory. Když &lt;code&gt;@EventHandler&lt;/code&gt; vrátí &lt;code&gt;Mono&amp;lt;Void&amp;gt;&lt;/code&gt;, framework se na něj nikdy nepřihlásí. Reaktivní řetězec se jednoduše neprovede. Přišli jsme na to tvrdým způsobem, když projekční handlery přestaly tiše zapisovat do databáze.&lt;/p&gt;</description></item><item><title>Proč je OpenTelemetry lepší než proprietární APM agenti</title><link>https://saasforge.cz/cs/blog/why-opentelemetry-beats-vendor-agents/</link><pubDate>Sat, 14 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/cs/blog/why-opentelemetry-beats-vendor-agents/</guid><description>&lt;p&gt;Pokud jste někdy zkoušeli vyměnit svého APM dodavatele, znáte tu bolest. Proprietární agenti od Datadogu, Dynatrace nebo New Relicu se hluboce zaplétají do vašeho deployment pipeline — různé binární agenty pro každý jazyk, vendor-specifická konfigurace, custom SDK ve vašem aplikačním kódu. Přechod znamená vše vytrhnout a začít znovu.&lt;/p&gt;
&lt;p&gt;OpenTelemetry nabízí zásadně odlišný přístup: &lt;strong&gt;jeden otevřený standard pro instrumentaci všeho&lt;/strong&gt; se svobodou posílat telemetrická data kamkoli chcete.&lt;/p&gt;
&lt;h2 id="problém-s-proprietárními-agenty"&gt;Problém s proprietárními agenty&lt;/h2&gt;
&lt;p&gt;Tradiční APM dodavatelé dodávají své vlastní proprietární agenty. V praxi to znamená:&lt;/p&gt;</description></item></channel></rss>