<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="sl">
  <title>Novosti iz tovarne | MicroSaaS Toolkit</title>
  <link href="https://microsaaskit.dev/sl/novosti/feed.xml" rel="self"/>
  <link href="https://microsaaskit.dev/sl/novosti/"/>
  <id>https://microsaaskit.dev/sl/novosti/</id>
  <updated>2026-10-23T00:00:00Z</updated>
  <author><name>Jure Hrastnik</name></author>
  <entry>
    <title>Celica, naša enota infrastrukture: z enim ukazom zgrajena v 1,7 minute</title>
    <link href="https://microsaaskit.dev/sl/novosti/the-cell/"/>
    <id>https://microsaaskit.dev/sl/novosti/the-cell/</id>
    <updated>2026-10-23T00:00:00Z</updated>
    <published>2026-10-23T00:00:00Z</published>
    <summary>Po zasnovi je celica samostojna enota, danes en strežnik, z vsem, na čemer teče produkt. Prva, zgrajena s skriptom, je v 3,8 minute zagnala kopijo produkta v uporabi.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/the-cell-sl.png&quot; alt=&quot;Diagram: celica, samostojna enota, vsebuje vstopno točko s TLS, produkte, varnostne kopije, nadzor in požarni zid. Med delovanjem celice ne delijo ničesar.&quot;&gt;&lt;/p&gt;&lt;p&gt;Tovarna, ki dodaja vedno nove produkte, potrebuje enoto infrastrukture, ki ob rasti ohrani svojo obliko. Pri nas je to celica.&lt;/p&gt;
&lt;h2&gt;Kaj je celica&lt;/h2&gt;
&lt;p&gt;Po zasnovi je celica samostojna enota, danes en strežnik, z vsem, kar produkt potrebuje, da streže uporabnikom: z vstopno točko, ki hrani certifikate TLS in imena produktov v celici, z nočnimi varnostnimi kopijami in z nadzorom, vse za lastnim požarnim zidom. Vsako okolje produkta je nameščeno v natanko eni celici, njegovo ime pa kaže nanjo.&lt;/p&gt;
&lt;p&gt;Med delovanjem celice ne delijo ničesar: ne omrežja, ne vstopne točke, ne baze. Zunaj njih ostanejo deli, ki ne strežejo zahtevam, na primer CI in registri slik.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/news/the-cell-figure-sl.png&quot; alt=&quot;Diagram zasnove celice: dve celici, vsaka za lastnim požarnim zidom, z vstopno točko, produkti, varnostnimi kopijami in nadzorom. Produkt se iz celice A v celico B premakne v treh korakih. Deli, ki ne strežejo zahtevam, na primer CI in registri slik, ostanejo zunaj.&quot;&gt;&lt;/p&gt;
&lt;p&gt;Celica je 22. oktobra nadomestila naš prejšnji načrt z eno osrednjo vstopno točko za vsa imena vseh produktov. Če bi produkti tekli na več strežnikih, bi vsi odpovedali skupaj s strežnikom, na katerem je ta vstopna točka, za dostop do ostalih pa bi potrebovali zasebno omrežje in odkrivanje storitev, ki bi ju vzdrževali ročno. S celicami okvara ostane v svoji celici, tovarna pa raste z novimi celicami, ne z večjim strežnikom.&lt;/p&gt;
&lt;p&gt;Po zasnovi se produkt premakne v treh korakih: ista slika na novi celici, njegovi podatki in njegovo ime, preusmerjeno na novo celico. Produkt s seboj prinese slike, zgrajene v CI, konfiguracijo iz okolja in preverjanje zdravja, na katero počaka namestitev. Enako zahteva tudi orkestrator, kot je Kubernetes, zato ta možnost ostaja odprta.&lt;/p&gt;
&lt;h2&gt;Prva celica, zgrajena s skriptom&lt;/h2&gt;
&lt;p&gt;Enota infrastrukture je vredna toliko, kolikor stane naslednja. &lt;code&gt;bin/cell.sh build&lt;/code&gt; iz svežega strežnika z Ubuntujem naredi celico, za vsak del pa uporabi skript iz repozitorija, ki mu pripada: nastavitve strežnika, požarni zid, vstopno točko, nadzor in varnostne kopije.&lt;/p&gt;
&lt;p&gt;Ukaz smo 23. oktobra pognali na začasnem strežniku v drugem podatkovnem centru: strežnik je bil pripravljen v pol minute, celica v 1,7 minute. Nato smo nanj namestili nespremenjeno produkcijsko izdajo produkta v uporabi in njegovi bazi obnovili iz izvozov prejšnje noči. Celoten tek je trajal 3,8 minute in vseh 13 preverjanj je uspelo, od primerjave števila vrstic z izvozi do spletne strani in API-ja produkta, ki sta odgovorila prek nove vstopne točke. Imena produkta namenoma nismo preusmerili na kopijo, zato ni prejela nobene zahteve strank; strežnik smo nato izbrisali.&lt;/p&gt;
&lt;p&gt;Naslednja celica se začne z istim ukazom, čas prve pa je zapisan.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Stran, ki je predstavila naš gradnik za oblikovni sistem, zdaj temelji na njem</title>
    <link href="https://microsaaskit.dev/sl/novosti/landing-on-the-design-system/"/>
    <id>https://microsaaskit.dev/sl/novosti/landing-on-the-design-system/</id>
    <updated>2026-10-21T00:00:00Z</updated>
    <published>2026-10-21T00:00:00Z</published>
    <summary>Od 21. oktobra ima microsaaskit.dev pripet oblikovni sistem 1.1.0: našo modro določa dvanajst vlog, ki jih preveri gradnik, Tailwind je v njegovih plasteh, tri preverbe pa lahko ustavijo gradnjo.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/landing-on-the-design-system-sl.png&quot; alt=&quot;Terminal: pravilo zunaj plasti, dodano v brand.css, ustavi gradnjo strani; svetlo modra barva za dejanja pade na testu znamke gradnika s kontrastom 1,80 : 1, zahtevano je vsaj 4,5 : 1.&quot;&gt;&lt;/p&gt;&lt;p&gt;Reputo in Leadgener imata od 13. oktobra pripet en sam &lt;a href=&quot;/sl/novosti/shared-design-system/&quot;&gt;gradnik za oblikovni sistem&lt;/a&gt;, ta stran pa je o tem poročala še isti dan. Gradnika sama ni uporabljala: imela je lastne vrednosti barv za obe temi, pisavo IBM Plex Sans namesto pisave Inter, ki jo določa gradnik, lastne gumbe in lasten okvir fokusa.&lt;/p&gt;
&lt;h2&gt;En paket, dve zapisani izjemi&lt;/h2&gt;
&lt;p&gt;Stran smo 21. oktobra 2026 prenesli na gradnikov paket npm, pripet na različico 1.1.0. V svetli temi zdaj površine, besedilo in obrobe strani sledijo vlogam gradnika. Gumbi, debelina pisave v naslovih, pisava besedila in okvir fokusa na kontrolnikih so gradnikovi. Modra barva toolkita je v &lt;code&gt;brand.css&lt;/code&gt;: dvanajst barvnih vlog iz pogodbe znamke gradnika, ki jih v testih strani preveri gradnikov &lt;code&gt;assertBrand&lt;/code&gt;, tako kot v Reputu in Leadgenerju. Svetlo modra barva za dejanja na tem testu pade: njen kontrast je 1,80 : 1, zahtevano pa je vsaj 4,5 : 1.&lt;/p&gt;
&lt;p&gt;Deli, za katere gradnik nima ustreznika, na primer tloris tovarne, ostanejo del strani; za dva od njih odločitev o prevzemu gradnika zapiše, zakaj ostajata zunaj njega. Gradnik nima temne teme in noben produkt je ne potrebuje, zato po našem &lt;a href=&quot;/sl/novosti/harvest-rule/&quot;&gt;pravilu žetve&lt;/a&gt; ne spada v gradnik; 13 testov zagotavlja, da barve besedila in gumbov v temni temi strani ohranijo kontrast vsaj 4,5 : 1. Prav tako gradnik nima čipa za filtriranje, zato stikala, s katerimi filtrirate tloris tovarne in novice, ostajajo kontrolniki strani, zgrajeni iz oblikovnih žetonov gradnika, dokler čipa ne bo potreboval kateri od produktov.&lt;/p&gt;
&lt;h2&gt;Tailwind v plasteh gradnika&lt;/h2&gt;
&lt;p&gt;Gradnik določa sedem kaskadnih plasti (cascade layers); zadnja, &lt;code&gt;product&lt;/code&gt;, je namenjena lastnemu CSS strani. Tailwind, s katerim gradimo stran, CSS izpiše zunaj vseh plasti, tak CSS pa premaga vsako plast ne glede na specifičnost: Tailwindova ponastavitev slogov bi povozila sloge gumbov gradnika. Zato gradnja Tailwind požene dvakrat: njegovo ponastavitev postavi v plast gradnika za ponastavitev, vse drugo pa v plast &lt;code&gt;product&lt;/code&gt;. Nato lahko gradnjo ustavijo tri preverbe: plasti morajo slediti v vrstnem redu gradnika, zunaj plasti ne sme biti nobenega pravila razen &lt;code&gt;@font-face&lt;/code&gt;, vsak lokalni &lt;code&gt;url()&lt;/code&gt; pa mora kazati na datoteko, ki jo je zapisala gradnja. Vsakega od teh pogojev smo namenoma prekršili in vsakič je preverba gradnjo ustavila s svojim sporočilom.&lt;/p&gt;
&lt;p&gt;Ista gradnja teče med izdelavo slike Docker na veji &lt;code&gt;main&lt;/code&gt;, namestitev pa čaka na to sliko: prvi cevovod je pridobil gradnik, zgradil sliko in namestitev končal 83 sekund po združitvi spremembe.&lt;/p&gt;
&lt;p&gt;CSS gradnika tu torej deluje brez njegovih komponent React: dva zagona postavita Tailwindov CSS v plasti gradnika, gradnja pa se ustavi, če kako pravilo ostane zunaj njih ali se njihov vrstni red spremeni.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Predpomnilnik slojev za gradnjo slik in kanarček, ki je ujel njegovo prvo izdajo</title>
    <link href="https://microsaaskit.dev/sl/novosti/delivery-kit-build-cache/"/>
    <id>https://microsaaskit.dev/sl/novosti/delivery-kit-build-cache/</id>
    <updated>2026-10-20T00:00:00Z</updated>
    <published>2026-10-20T00:00:00Z</published>
    <summary>Gradnik za CI/CD 1.4 gradnji slike omogoča, da sloje vzame iz registra. Prva izdaja na pravih izvajalnikih ni delovala; Probe jo je ujel v zahtevi za združitev, preden jo je pripel drug produkt.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/delivery-kit-build-cache-sl.png&quot; alt=&quot;Števili 91 in 33: sekunde za gradnjo Probove slike API na veji main, najprej brez predpomnilnika, nato ob ponovnem zagonu s sloji iz predpomnilnika v registru.&quot;&gt;&lt;/p&gt;&lt;p&gt;Skupni izvajalniki (runnerji) v GitLabu vsako opravilo začnejo s praznim Dockerjem. Gradnja slike z gradnikom za CI/CD je zato ob vsakem zagonu znova obnovila pakete NuGet in od začetka prevedla API, tudi kadar se ni spremenila nobena datoteka zaledja.&lt;/p&gt;
&lt;h2&gt;Predpomnilnik je v registru&lt;/h2&gt;
&lt;p&gt;Gradnik za CI/CD 1.4.0, ki smo ga izdali 20. oktobra 2026, komponenti &lt;code&gt;image-build&lt;/code&gt; doda vhodni parameter &lt;code&gt;cache&lt;/code&gt; z dvema vrednostma: privzeto &lt;code&gt;none&lt;/code&gt; in &lt;code&gt;registry&lt;/code&gt;. Z vrednostjo &lt;code&gt;registry&lt;/code&gt; gradnja teče z orodjem buildx na gonilniku &lt;code&gt;docker-container&lt;/code&gt; in sloje bere iz &lt;code&gt;&amp;lt;image&amp;gt;:buildcache&lt;/code&gt; v registru vsebniških slik projekta. Nazaj jih zapiše samo privzeta veja. Gradnja v zahtevi za združitev predpomnilnik prebere, v register pa ne potisne ničesar, zato ne more zamenjati slojev, na katere se zanaša &lt;code&gt;main&lt;/code&gt;. Produkt, ki parametra ne nastavi, ne opazi nobene spremembe.&lt;/p&gt;
&lt;p&gt;Predpomnilnik od datoteke Dockerfile zahteva eno stvar: obnovljeni paketi morajo ostati v sloju slike. Imenik, priklopljen z &lt;code&gt;RUN --mount=type=cache&lt;/code&gt;, se v register nikoli ne izvozi, zato bi naslednji korak ostal brez paketov, kadar bi sloj z obnovo prišel iz predpomnilnika. Probe, produkt, ki ga vzdržujemo zato, da vsako izdajo gradnika prevzame prvi, je iz tega razloga opustil priklope predpomnilnika za NuGet.&lt;/p&gt;
&lt;h2&gt;Ujeta na pravem izvajalniku&lt;/h2&gt;
&lt;p&gt;Različica 1.4.0 je prestala teste na delovni postaji, Probova prva gradnja pa se je pet minut po izdaji končala z napako. Opravila gradnika se z Dockerjem povezujejo prek TLS, &lt;code&gt;docker buildx create&lt;/code&gt; pa nastavitev TLS iz okolja ne sprejme. Noben drug produkt je še ni pripel. Različica 1.4.1, izdana 14 minut po različici 1.4.0, graditelja ustvari v kontekstu Dockerja, narejenem iz istih nastavitev.&lt;/p&gt;
&lt;p&gt;Do takrat je cevovod gradnika komponento &lt;code&gt;image-build&lt;/code&gt; le vključil in preveril, da jo GitLab sprejme, njenega skripta pa ni nikoli zagnal. Novo opravilo &lt;code&gt;delivery:image-build-test&lt;/code&gt; ta skript zažene na Dockerju s TLS, kakršnega imajo opravila produktov, in z registrom, zagnanim v istem Dockerju. Preveri, ali privzeta veja predpomnilnik zapiše, ali ga nov graditelj prebere, ali ga druga veja prebere in v register ne potisne ničesar ter ali gradnja brez predpomnilnika še deluje. S predlogo različice 1.4.0 se 7 od 10 preverjanj konča z napako.&lt;/p&gt;
&lt;p&gt;Prva gradnja slike API na Probovi veji &lt;code&gt;main&lt;/code&gt; je trajala 91 sekund in zapisala predpomnilnik. Ponovni zagon iste potrditve, najugodnejši primer, je trajal 33 sekund, koraka &lt;code&gt;dotnet restore&lt;/code&gt; in &lt;code&gt;dotnet publish&lt;/code&gt; pa sta prišla iz predpomnilnika v registru. V Probovi datoteki Dockerfile je sloj z obnovo odvisen samo od datotek projektov in nastavitev gradnje, zato bi ga potrditev, ki spremeni samo kodo, morala uporabiti znova.&lt;/p&gt;
&lt;p&gt;Kdor želi predpomnilnik uporabiti, pripne različico 1.4.1, nastavi &lt;code&gt;cache: registry&lt;/code&gt; na slikah s počasno obnovo, oznako slike &lt;code&gt;buildcache&lt;/code&gt; izvzame iz pravila za čiščenje registra in iz datoteke Dockerfile najprej odstrani priklope predpomnilnika za pakete.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Varnostna preverjanja, ki jih produkt prevzame z gradnikom za CI/CD</title>
    <link href="https://microsaaskit.dev/sl/novosti/security-checks-from-the-kit/"/>
    <id>https://microsaaskit.dev/sl/novosti/security-checks-from-the-kit/</id>
    <updated>2026-10-19T00:00:00Z</updated>
    <published>2026-10-19T00:00:00Z</published>
    <summary>Različici 1.1 in 1.2 gradnika za CI/CD dodata pregled skrivnosti in ranljivih paketov NuGet ter preverjanje, da izbrani naslovi ostanejo zaprti. Reputo in Leadgener sta jih prevzela isti dan.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/security-checks-from-the-kit-sl.png&quot; alt=&quot;Terminal: Reputova namestitev na gradniku za CI/CD 1.3.0 prestane preverjanje zdravja in potrdi, da skrbniška konzola strežnika za identiteto, njegov realm master in stran Swagger vrnejo 404.&quot;&gt;&lt;/p&gt;&lt;p&gt;Pregled skrivnosti, preverjanje paketov NuGet in preverjanje naslovov, ki morajo po namestitvi ostati zaprti, smo 19. oktobra 2026 prenesli iz cevovodov naših produktov v gradnik za CI/CD. Produkt, ki začne z Reputovim cevovodom, ima vsa tri preverjanja že od prvega cevovoda. Vstopno preverjanje uporabniškega vmesnika je &lt;code&gt;npm audit&lt;/code&gt; poganjalo že prej.&lt;/p&gt;
&lt;h2&gt;Tri preverjanja v gradniku&lt;/h2&gt;
&lt;p&gt;Gradnik za CI/CD 1.1.0 doda komponento &lt;code&gt;secret-scan&lt;/code&gt;, ki z orodjem gitleaks pregleda nove potrditve v cevovodu: pri zahtevi za združitev njene potrditve, na veji pa vse od njenega prejšnjega stanja. Ne čaka na nobeno drugo opravilo, zato gradnje nikoli ne zadržuje. Komponenta &lt;code&gt;dotnet-test&lt;/code&gt; takoj po obnovi paketov zažene &lt;code&gt;dotnet list package --vulnerable --include-transitive&lt;/code&gt; in pade ob ranljivosti visoke ali kritične stopnje. Pregled uporabi isto obnovo, zato traja le nekaj sekund in ne zahteva druge. Izklopi se z vhodnim parametrom &lt;code&gt;vulnerability_scan: false&lt;/code&gt;, ki ga dokumentacija gradnika dovoli samo z razlogom in datumom v cevovodu produkta.&lt;/p&gt;
&lt;p&gt;Različica 1.2.0, izdana isti dan, komponenti &lt;code&gt;deploy&lt;/code&gt; doda vhodni parameter &lt;code&gt;closed_urls&lt;/code&gt;, seznam naslovov, ki morajo po namestitvi vrniti 401, 403 ali 404. Odgovor 2xx ali 3xx preverjanje takoj označi kot neuspešno, brez ponovnih poskusov.&lt;/p&gt;
&lt;h2&gt;Prevzeto na dan izdaje&lt;/h2&gt;
&lt;p&gt;Reputo in Leadgener sta popoldne prešla na različico 1.1.0. Oba cevovoda sta zagnala pregled skrivnosti in pregled paketov NuGet; noben pregled ni ničesar našel.&lt;/p&gt;
&lt;p&gt;Zvečer sta oba produkta na gradniku za CI/CD 1.3.0 v &lt;code&gt;closed_urls&lt;/code&gt; navedla tri naslove: skrbniško konzolo strežnika za identiteto, njegov realm master in stran Swagger. Vsaka namestitev zdaj dokaže, da ostanejo zaprti: Reputova namestitev v razvojno okolje ob 17.43 UTC in Leadgenerjeva ob 17.47 UTC sta vse tri zabeležili kot zaprte (404).&lt;/p&gt;
&lt;p&gt;Preverjanje je v gradniku, pravila pa ne, in to namerno: kaj naslov zapre, se od produkta do produkta razlikuje (pravilo v prehodu, nastavitve API-ja), ali je zaprt, pa je povsod isto vprašanje. Nov produkt, ki prevzame Reputov cevovod, z njim podeduje tudi vse tri naslove, zato se njegova prva namestitev konča z napako, če kaj od tega, kar jih zapira, manjka.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Toolkit 1.0.3 je manj kot uro po izdaji tekel v vseh treh produktih v uporabi</title>
    <link href="https://microsaaskit.dev/sl/novosti/toolkit-1-0-3-rollout/"/>
    <id>https://microsaaskit.dev/sl/novosti/toolkit-1-0-3-rollout/</id>
    <updated>2026-10-19T00:00:00Z</updated>
    <published>2026-10-19T00:00:00Z</published>
    <summary>En skript pred izdajo z novo različico toolkita zgradi vsak produkt, drugi odpre zahteve za nadgradnjo. Različica 1.0.3 je 54 minut po objavi že tekla v vseh treh produktih v uporabi.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/toolkit-1-0-3-rollout-sl.png&quot; alt=&quot;Število 54 z napisom: minute od objave toolkita 1.0.3 do zadnje od treh namestitev v produkcijo.&quot;&gt;&lt;/p&gt;&lt;p&gt;Vsak produkt toolkit pripne v eni vrstici, izdaja pa nima nobenega učinka, dokler produkt v tej vrstici ne spremeni različice. Do 19. oktobra 2026 smo to delali ročno: ob izdaji smo pripeto različico popravili v vsakem produktu posebej in šele iz njegovega cevovoda izvedeli, ali se še zgradi.&lt;/p&gt;
&lt;h2&gt;Dva skripta, pred izdajo in po njej&lt;/h2&gt;
&lt;p&gt;Skript &lt;code&gt;factory/check_consumers.py&lt;/code&gt; vsak aktiven produkt iz registra tovarne, ki pripenja toolkit, zgradi s kopijo toolkita namesto z objavljenimi paketi, še preden karkoli izdamo. Skript &lt;code&gt;factory/propose_upgrade.py&lt;/code&gt; nato odpre zahtevo za nadgradnjo v vsakem produktu, ki pripenja starejšo različico. Spremeni samo pripeto različico, v opisu vsake zahteve pa so opombe k vsem izdajam, novejšim od pripete različice, zato tisti, ki zahtevo združi, vidi, kaj mora produkt ob nadgradnji narediti.&lt;/p&gt;
&lt;p&gt;Toolkit 1.0.3 je odpravil edino mesto, kjer se je paket iz nižje plasti skliceval na paket iz višje: &lt;code&gt;Tenancy.Runtime&lt;/code&gt; ni več odvisen od &lt;code&gt;Organizations.Api&lt;/code&gt;. Knjižnico Stripe poleg tega pripne na točno določeno različico. Pred izdajo je &lt;code&gt;check_consumers.py&lt;/code&gt; s to spremembo zgradil vseh pet produktov.&lt;/p&gt;
&lt;h2&gt;Potek dneva&lt;/h2&gt;
&lt;p&gt;Vseh 19 paketov različice 1.0.3 je bilo objavljenih ob 16.00 UTC. Prvi pravi zagon skripta &lt;code&gt;propose_upgrade.py&lt;/code&gt; je v repozitorije Gostlyja, MojRazpisa in SnapMinda potisnil veje, zahtev za združitev pa ni odprl, ker je izvorni projekt vzel iz mape, v kateri je tekel. Popravek zahteve ustvari prek API-ja z imenom projekta in ponovnemu zagonu dovoli, da dokonča, kar je prejšnji začel: ponovni zagon je vse tri odprl ob 16.04. Reputo in Leadgener sta izdajo prevzela vsak v svoji zahtevi, skupaj z novimi varnostnimi pregledi gradnika za CI/CD. Do 16.09 je bilo združenih vseh pet zahtev.&lt;/p&gt;
&lt;p&gt;Namestitev v produkcijo še vedno sproži lastnik s pritiskom na gumb. MojRazpis in SnapMind sta z različico 1.0.3 v produkciji tekla od 16.39, Gostly, pri katerem gre sprememba najprej na razvojno vejo, pa od 16.54. Od objave do zadnje namestitve v produkcijo je minilo 54 minut, v registru tovarne pa je izdaja zapisana z datumom, ko je dosegla vse produkte v uporabi.&lt;/p&gt;
&lt;p&gt;Nič ni zahtevalo, da se pet produktov nadgradi hkrati: vsaka zahteva je imela svoj cevovod, produkt, ki zahteve ne združi, pa ostane na stari različici. Različica 1.0.3 ni bila varnostna izdaja. Po isti poti bo potoval varnostni popravek: najprej ga bomo zgradili v vseh produktih, nato ga bomo predlagali vsakemu posebej.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Gradnik za CI/CD: en cevovod in ena namestitev namesto dveh ročno vzdrževanih kopij</title>
    <link href="https://microsaaskit.dev/sl/novosti/delivery-kit/"/>
    <id>https://microsaaskit.dev/sl/novosti/delivery-kit/</id>
    <updated>2026-10-15T00:00:00Z</updated>
    <published>2026-10-15T00:00:00Z</published>
    <summary>Reputo in Leadgener sta imela cevovod in namestitev v dveh kopijah, ki sta se razšli. Gradnik za CI/CD 1.0.0 ju nadomesti s šestimi komponentami in sliko ops; oba sta nanj prešla na dan izida.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/delivery-kit-sl.png&quot; alt=&quot;Terminal: prvi obnovitveni test Leadgenerja na gradniku za CI/CD 1.0.0 preveri kontrolne vsote varnostne kopije, jo obnovi v začasen vsebnik, najde 25 tabel z enakim številom vrstic in 3.391 datotek z ujemajočim se SHA-256 ter se konča z OK.&quot;&gt;&lt;/p&gt;&lt;p&gt;Reputo in Leadgener, naša produkta v razvoju, smo gradili, testirali in nameščali z dvema kopijama istega cevovoda in istih skriptov za namestitev, ki smo ju prenašali ročno. Do 15. oktobra sta se kopiji razšli. Skripta za namestitev (116 in 111 vrstic) sta se razlikovala v 47 vrsticah, skripta, ki na strežniku zaženeta vsebnike (64 in 82 vrstic), pa v 66. Del razlik so imena produktov in komentarji, del pa delovanje: produkta sta varnostno kopijo delala vsak na svoj način. Popravek v eni kopiji ni prišel do druge, &lt;a href=&quot;/sl/novosti/leadgener-first-days/&quot;&gt;Leadgenerjev prvi cevovod&lt;/a&gt; pa je pri kopiranju že izgubil zastavico za gradnjo.&lt;/p&gt;
&lt;h2&gt;Šest komponent in slika vsebnika ops&lt;/h2&gt;
&lt;p&gt;Gradnik za CI/CD 1.0.0 smo izdali 15. oktobra 2026. Za gradnjo in namestitev naredi to, kar so paketi NuGet naredili za zaledje in gradnik Keycloak za identiteto: vsebuje šest komponent CI/CD za GitLab (testi zaledja, vstopno preverjanje uporabniškega vmesnika, vzporedni testi uporabniškega vmesnika, gradnja slik, namestitev in obnovitveni test) ter sliko vsebnika ops, v kateri tečeta namestitev in obnovitveni test. Produkt vsako komponento vključi v pripeti različici &lt;code&gt;@delivery-v1.0.0&lt;/code&gt;. Različice &lt;code&gt;latest&lt;/code&gt; ni, dnevnik sprememb pa vsako spremembo označi glede na to, česa se dotakne: &lt;code&gt;[contract]&lt;/code&gt;, &lt;code&gt;[behaviour]&lt;/code&gt; ali &lt;code&gt;[pipeline]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Različica 1.0 je zvest prenos obeh cevovodov; zasnova navaja vsako spremembo delovanja z razlogom. Varnostna kopija sledi Leadgenerjevi zasnovi: izvoz baze s kontrolnimi vsotami in številom vrstic vsake tabele v bazi aplikacije. Gradnik spremeni eno stvar: vrstice prešteje znotraj istega posnetka stanja, iz katerega nastane izvoz. Produktu ostanejo njegovi vhodni parametri, datoteke Compose in kavlji za korake, ki jih potrebuje samo on, na primer za pripravo realma v Keycloaku.&lt;/p&gt;
&lt;h2&gt;Dokazano na obeh produktih še isti dan&lt;/h2&gt;
&lt;p&gt;Pred izdajo je Reputo prevzel gradnik, pripet na določeno potrditev toolkita. Primerjalno poročilo je cevovod pred prevzemom in po njem primerjalo opravilo za opravilom, zahteva za združitev pa pojasni vsako razliko. Število uspešnih testov se ni spremenilo: 2.298 testov zaledja in 2.591 testov uporabniškega vmesnika. Na veji &lt;code&gt;main&lt;/code&gt; je namestitev iz gradnika naredila varnostno kopijo obeh baz, prek Reputovega kavlja pripravila Keycloak in prestala preverjanje zdravja, obnovitveni test pa je to kopijo obnovil v začasen vsebnik: 33 tabel, vsaka z enakim številom vrstic kot v varnostni kopiji.&lt;/p&gt;
&lt;p&gt;Reputo je nato pripel različico 1.0.0, Leadgener pa je prešel še isti večer. Njegov prvi obnovitveni test na gradniku je preveril 25 tabel, prek lastnega kavlja pa še, da je vseh 3.391 datotek, na katere kaže baza, na mestu in da se njihove kontrolne vsote ujemajo. Iz obeh produktov smo skripte za namestitev odstranili, Reputov &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; pa se je skrčil z 290 na 172 vrstic.&lt;/p&gt;
&lt;p&gt;Spremembo skupnih opravil, namestitve, varnostne kopije ali obnovitvenega testa zdaj naredimo enkrat, v gradniku; kar potrebuje samo en produkt, ostane v njegovih vhodnih parametrih in kavljih.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Gradnik za oblikovni sistem 1.1.0: nov videz, izdan enkrat, pripet dvakrat</title>
    <link href="https://microsaaskit.dev/sl/novosti/design-system-1-1-refresh/"/>
    <id>https://microsaaskit.dev/sl/novosti/design-system-1-1-refresh/</id>
    <updated>2026-10-14T00:00:00Z</updated>
    <published>2026-10-14T00:00:00Z</published>
    <summary>Oblikovni sistem 1.1.0: nov videz v 33 slogovnih datotekah gradnika, HTML ostaja enak. V kodi aplikacije je Reputo spremenil tri svoje datoteke CSS, Leadgener svoje slogovne datoteke in tabelo.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/design-system-1-1-refresh-sl.png&quot; alt=&quot;Terminal: od različice 1.0.1 do 1.1.0 gradnika za oblikovni sistem se njegov CSS spremeni v 33 datotekah; v mapi frontend/src spremeni Reputova zahteva za združitev 3 datoteke, Leadgenerjeva 7.&quot;&gt;&lt;/p&gt;&lt;p&gt;Gradnik za oblikovni sistem 1.0 je ohranil videz, ki so ga naši produkti že imeli: pisavo Arial, oglate vogale, obrobe gumbov in vnosnih polj debeline 2 px, besedilo z velikimi tiskanimi črkami na značkah in ploščicah KPI ter temno nogo strani. Želeli smo, da bi bili videti kot sodobni produkti SaaS. Z dvema kopijama oblikovnega sistema bi to pomenilo dvakrat isto preoblikovanje; s &lt;a href=&quot;/sl/novosti/shared-design-system/&quot;&gt;skupnim gradnikom&lt;/a&gt;, ki ga imamo od 13. oktobra, je to ena sama izdaja.&lt;/p&gt;
&lt;h2&gt;Nov videz, iste komponente&lt;/h2&gt;
&lt;p&gt;Gradnik za oblikovni sistem 1.1.0 smo izdali 14. oktobra 2026. Arial je zamenjala pisava Inter, ki je del paketa in se nikoli ne nalaga iz omrežja CDN za pisave. Vogali so rahlo zaobljeni: 3 px pri značkah, 4 pri kontrolnikih in 6 pri karticah. Obrobe gumbov in vnosnih polj so tanjše, 1 px, kartice imajo mehko senco, noga strani pa je svetla plošča.&lt;/p&gt;
&lt;p&gt;HTML in zgradba strani sta ostala enaka; nobene lastnosti komponent nismo odstranili ali preimenovali. Videz je del jedra: produkt še vedno nastavi le svojih dvanajst barvnih vlog, saj bi z vlogami za pisavo, zaobljenost ali senco produkti znova začeli odstopati drug od drugega. Kar gradnik zagotavlja, se ni spremenilo: okvir fokusa, površine za dotik velikosti 44 px, kontrast in toni stanj, ki jih poleg barve loči tudi oblika simbola.&lt;/p&gt;
&lt;p&gt;Med različicama 1.0.1 in 1.1.0 se je v gradniku spremenilo 33 slogovnih datotek (dodanih 466 vrstic, odstranjenih 146) in vseh 384 referenčnih posnetkov.&lt;/p&gt;
&lt;h2&gt;Kaj so spremenili produkti&lt;/h2&gt;
&lt;p&gt;Reputo in Leadgener pripneta gradnik vsak v eni vrstici datoteke &lt;code&gt;package.json&lt;/code&gt; svojega uporabniškega vmesnika, iz katerega se zgradijo tudi strani za prijavo. Reputo je pripeto različico z 1.0.0 dvignil na 1.1.0 uro po tem, ko smo sprejeli zahtevo za združitev gradnika, zato je dobil tudi popravke iz 1.0.1. V kodi aplikacije, v mapi &lt;code&gt;src&lt;/code&gt; uporabniškega vmesnika, so se spremenile tri datoteke (dodanih 20 vrstic, odstranjenih 7): Reputove kartice preverjanj, incidentov in zapisov DNS zdaj berejo nove žetone gradnika za zaobljenost in senco kartic.&lt;/p&gt;
&lt;p&gt;Leadgener je 1.1.0 pripel dve uri pozneje. V kodi aplikacije njegove slogovne datoteke zdaj namesto fiksno vpisane vrednosti 700 berejo žetone gradnika za debelino pisave. En zaslon je potreboval spremembo kode: tabela priložnosti ima devet stolpcev, zato uporablja novo možnost &lt;code&gt;stackBelow=&amp;quot;wide&amp;quot;&lt;/code&gt;. Ko je sama ožja od 1160 px, vsako vrstico prikaže kot seznam poimenovanih polj, datum in uro pa izpiše kot dva ločena dela.&lt;/p&gt;
&lt;p&gt;Na toolkitu nov videz pomeni manjšo različico: pripnete jo, opravite preverjanja, ki jih dnevnik sprememb navaja za to izdajo, in znova pregledate zaslone; tabela, preširoka za svoj okvir, dobi eno lastnost.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Register tovarne: kaj ima pripeto vsak produkt in ali se to ujema z repozitorijem</title>
    <link href="https://microsaaskit.dev/sl/novosti/factory-registry/"/>
    <id>https://microsaaskit.dev/sl/novosti/factory-registry/</id>
    <updated>2026-10-13T00:00:00Z</updated>
    <published>2026-10-13T00:00:00Z</published>
    <summary>Ena datoteka navaja, katere različice gradnikov ima pripete vsak produkt in katera potrditev teče v produkciji. Skript jo primerja z repozitoriji in GitLabom ter ob neujemanju konča z izhodno kodo 1.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/factory-registry-sl.png&quot; alt=&quot;Terminal: preverjanje registra (skrajšan izpis) javi DRIFT za pripeto različico gradnika Keycloak v Reputu in Leadgenerju in konča z izhodno kodo 1.&quot;&gt;&lt;/p&gt;&lt;p&gt;Produkt ima naše gradnike pripete v svojem repozitoriju: različico toolkita v &lt;code&gt;Directory.Build.props&lt;/code&gt;, gradnik Keycloak v Dockerfilu, gradnik za oblikovni sistem pa v &lt;code&gt;frontend/package.json&lt;/code&gt;. Do 11. oktobra ni bilo nikjer zapisano, kateri produkt uporablja katero različico in ali je skupna sprememba že prišla v produkcijo.&lt;/p&gt;
&lt;h2&gt;En zapis, ki ga preverjamo&lt;/h2&gt;
&lt;p&gt;Register produktov &lt;code&gt;factory/products.toml&lt;/code&gt; smo dodali 11. oktobra 2026. Za vsak produkt navaja fazo, lastnika, integracijsko in produkcijsko vejo, različice v &lt;code&gt;kits.nuget&lt;/code&gt;, &lt;code&gt;kits.keycloak&lt;/code&gt; in &lt;code&gt;kits.design_system&lt;/code&gt;, za produkt v produkciji pa še opravilo za namestitev in potrditev (commit), ki je nameščena v produkciji.&lt;/p&gt;
&lt;p&gt;Skript &lt;code&gt;factory/check_registry.py&lt;/code&gt; ta zapis primerja z repozitorijem vsakega produkta na &lt;code&gt;origin/&amp;lt;branch&amp;gt;&lt;/code&gt;, nikoli z delovno kopijo, zato delo, ki še ni potisnjeno, ne šteje. Z &lt;code&gt;--fetch&lt;/code&gt; najprej osveži vse lokalne kopije, z &lt;code&gt;--gitlab&lt;/code&gt; pa GitLab vpraša, katero potrditev je namestilo zadnje uspešno opravilo za namestitev. Vsaka ugotovitev je ena vrstica z oceno. &lt;code&gt;DRIFT&lt;/code&gt; pomeni, da se register in repozitorij ne ujemata, napačen pa je lahko kateri koli od njiju. &lt;code&gt;FAIL&lt;/code&gt; označuje tveganje za obratovanje, na primer kopijo toolkita v repozitoriju namesto paketov, ciljno ogrodje, ki mu bo podpora potekla v manj kot 90 dneh, ali pripeto različico oblikovnega sistema, ki ni enaka tisti v registru. Če najde vsaj en &lt;code&gt;FAIL&lt;/code&gt; ali &lt;code&gt;DRIFT&lt;/code&gt;, skript konča z izhodno kodo 1.&lt;/p&gt;
&lt;h2&gt;Kaj je preverjanje našlo 13. oktobra&lt;/h2&gt;
&lt;p&gt;Glava registra zahteva, da register posodobimo v isti zahtevi za združitev kot spremembo, zaradi katere zapis drži. Za pripeto različico gradnika to pravilo ne more veljati: spremeni se v repozitoriju produkta, register pa v našem. V register smo 12. oktobra za Reputo in Leadgener vpisali gradnik Keycloak 1.0.1. Še isti večer sta oba prešla na 2.0.0. Naslednji dan sta register spremenili dve zahtevi za združitev, a teh vrstic ni popravila nobena.&lt;/p&gt;
&lt;p&gt;Preverjanje 13. oktobra je med drugimi ugotovitvami izpisalo tudi ti dve vrstici:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;DRIFT  reputo       main: Keycloak kit pins [&amp;#39;2.0.0&amp;#39;], registry says 1.0.1
DRIFT  leadgener    main: Keycloak kit pins [&amp;#39;2.0.0&amp;#39;], registry says 1.0.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pripeti različici oblikovnega sistema, vpisani v register nekaj ur prej, sta se v obeh produktih ujemali z registrom. Popravek je ena vrstica na produkt v &lt;code&gt;products.toml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Za ekipo, ki gradi na toolkitu, register preverja pravilo, ki smo ga postavili za svoje nadgradnje: nadgradnja je končana, ko teče v produkciji, ne že ob združitvi zahteve zanjo. Z &lt;code&gt;--gitlab&lt;/code&gt; preverjanje pri produktu v produkciji prebere različico toolkita iz potrditve, ki jo je GitLab nazadnje namestil, in opozori, če ta ni enaka različici v registru. Register za vsak produkt hrani različice gradnikov, ki jih pripenja njegova integracijska veja, en zagon preverjanja pa pokaže, kje se zapis in repozitorij razhajata.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Gradnik Keycloak: ena pripeta slika, tema za vsak produkt</title>
    <link href="https://microsaaskit.dev/sl/novosti/keycloak-kit/"/>
    <id>https://microsaaskit.dev/sl/novosti/keycloak-kit/</id>
    <updated>2026-10-13T00:00:00Z</updated>
    <published>2026-10-13T00:00:00Z</published>
    <summary>Gradnik Keycloak je ena slika, pripeta na povzetek (digest). Vsebuje pravila, ki morajo veljati v vsakem realmu (zahtevki v žetonu, obvezen sprejem pogojev uporabe), in slovenska sporočila Keycloaka.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/keycloak-kit-sl.png&quot; alt=&quot;Diagram: gradnik Keycloak uporabljata Reputo in Leadgener; vsak na isto pripeto sliko doda svojo temo za prijavo.&quot;&gt;&lt;/p&gt;&lt;p&gt;Vsak produkt prijavlja uporabnike prek svojega Keycloaka, paketi API iz toolkita pa zaupajo temu, kar ta Keycloak zapiše v žeton. Reputo in Leadgener sta sliko prej gradila iz &lt;code&gt;quay.io/keycloak/keycloak:26.0&lt;/code&gt;, torej iz oznake, ki se premakne z vsako popravno različico. Zato sta lahko dve gradnji iz iste potrditve (commit) vsebovali različni različici Keycloaka.&lt;/p&gt;
&lt;h2&gt;Kaj gradnik vsebuje in česa ne&lt;/h2&gt;
&lt;p&gt;Odločili smo se 11. oktobra 2026: gradnik Keycloak je ena osnovna slika, ki vsebuje le tisto, kar mora biti enako v Keycloaku vsakega produkta. To so Keycloak, pripet na povzetek; orodje &lt;code&gt;jq&lt;/code&gt;, pripeto na kontrolno vsoto; 32 Keycloakovih sporočil za prijavo v slovenščini; in dva ukaza, ki se v vsebniku izvedeta prek &lt;code&gt;docker exec&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setup&lt;/code&gt; pripravi, kar API prebere iz žetona: občinstvo (audience), vloge realma, zbrane v zahtevku &lt;code&gt;roles&lt;/code&gt;, ki ga bere ASP.NET, in deklarirani atribut &lt;code&gt;organization_id&lt;/code&gt;, ki bi ga Keycloak 26 sicer brez opozorila zavrgel.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;require-terms&lt;/code&gt; sprejem pogojev uporabe nastavi kot zahtevano dejanje za vsakega uporabnika, zato Keycloak žetona pred sprejemom ne izda. Shrani se le čas sprejema.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Privzetih vrednosti produktov gradnik ne vsebuje: ime realma, identifikatorji odjemalcev in izvori (origins) so v ovojnem skriptu produkta, &lt;code&gt;setup&lt;/code&gt; pa se ustavi, preden kar koli spremeni, in navede vsako manjkajočo spremenljivko. Tudi teme za prijavo ne vsebuje, ker tema na skupni oblikovni sistem doda znamko svojega produkta. Dockerfile produkta v prejšnji fazi zgradi JAR s temo, nato pa:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;FROM &amp;lt;kit image&amp;gt;:&amp;lt;X.Y.Z&amp;gt;@sha256:&amp;lt;digest&amp;gt;
COPY --from=theme /app/keycloak-theme/dist_keycloak/reputo-keycloak-theme.jar /opt/keycloak/providers/
RUN /opt/keycloak/bin/kc.sh build --db=postgres --health-enabled=true
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Testiran, pripet, nadgrajen po izbiri&lt;/h2&gt;
&lt;p&gt;Vsaka zahteva za združitev, ki spremeni gradnik, nad zgrajeno sliko požene šest zbirk testov. Ena od njih vsako slovensko sporočilo primerja s Keycloakom v sliki: ključ mora v Keycloaku obstajati, ograde pa morajo ostati enake.&lt;/p&gt;
&lt;p&gt;Oznake &lt;code&gt;latest&lt;/code&gt; ni, objavljena različica pa se nikoli ne prepiše. Reputo in Leadgener sta imela 13. oktobra pripeto isto različico z istim povzetkom. Dnevnik sprememb označi, kaj različica zahteva od produkta: &lt;code&gt;[keycloak]&lt;/code&gt; (najprej varnostna kopija podatkovne baze), &lt;code&gt;[contract]&lt;/code&gt; (spremenil se je ukaz, spremenljivka ali pot) ali &lt;code&gt;[behaviour]&lt;/code&gt; (pripravljeni realm je drugačen). Vsaka sprememba različice Keycloaka pomeni novo glavno (major) različico gradnika, ker Keycloak svojo podatkovno bazo migrira samo v eno smer. Do 13. oktobra je izšlo pet različic gradnika; kako je nastal, opisuje &lt;a href=&quot;/sl/novosti/harvest-rule/&quot;&gt;objava o pravilu žetve&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Za ekipo, ki gradi na toolkitu, to pomeni, da pravila identitete pridejo s sliko: žeton vsebuje, kar API preverja, in Keycloak ga ne izda, dokler uporabnik ne sprejme pogojev. Strani za prijavo in vrednosti realma ostanejo vaše.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>En oblikovni sistem, plast znamke za vsak produkt</title>
    <link href="https://microsaaskit.dev/sl/novosti/shared-design-system/"/>
    <id>https://microsaaskit.dev/sl/novosti/shared-design-system/</id>
    <updated>2026-10-13T00:00:00Z</updated>
    <published>2026-10-13T00:00:00Z</published>
    <summary>Kopiji oblikovnega sistema sta se razšli v nekaj dneh. Od 13. oktobra imata Reputo in Leadgener pripet en sam gradnik za oblikovni sistem, sama pa skrbita le za svojo znamko in svoje komponente.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/shared-design-system-sl.png&quot; alt=&quot;Diagram: gradnik za oblikovni sistem uporabljata Reputo in Leadgener; vsak doda le svojo plast znamke, prenos pa je bil z obema produktoma primerjan piksel za pikslom.&quot;&gt;&lt;/p&gt;&lt;p&gt;Naš oblikovni sistem je nastal v Reputu: oblikovni žetoni v CSS, komponente React, pravila linterja, ki zaslonom ne dovolijo lastnega oblikovanja, in katalog. Leadgener je 8. oktobra prekopiral njegovih 209 datotek in zamenjal barvno paleto. Štiri dni pozneje se je 26 datotek, skupnih obema kopijama, razlikovalo po vsebini, 14 pa jih je imela le ena. Nekatere razlike so bile Leadgenerjeve lastne komponente, ena pa popravek, ki je ostal tam, kjer je nastal: ožji notranji odmik zavihkov, s katerim trije zavihki na 375 px širokem zaslonu telefona ostanejo v eni vrstici. V Reputu so se zavihki še vedno prelamljali.&lt;/p&gt;
&lt;h2&gt;Jedro je skupno, znamka ni&lt;/h2&gt;
&lt;p&gt;Po našem &lt;a href=&quot;/sl/novosti/harvest-rule/&quot;&gt;pravilu žetve&lt;/a&gt; smo videz in uporabniško izkušnjo namenoma kopirali. Oblikovni sistem smo 12. oktobra iz tega pravila izvzeli. Jedro sistema določa kakovost vmesnika, zato se med produkti ne sme razlikovati: okvir fokusa, površine za dotik velikosti 44 px, kontrast, toni stanj, ki jih poleg barve loči tudi oblika simbola, ter lestvici velikosti pisave in razmikov. Iz njega je nastal gradnik za oblikovni sistem: paket npm, ki ga izdajamo kot druge gradnike, z datiranim razdelkom v dnevniku sprememb in zaščiteno oznako.&lt;/p&gt;
&lt;p&gt;Produktu ostane plast znamke: &lt;code&gt;brand.css&lt;/code&gt; z natanko dvanajstimi barvnimi vlogami, znak in lastne komponente s predpono produkta. Testi produkta kličejo &lt;code&gt;assertBrand&lt;/code&gt;, ki javi napako, če kakšna vloga manjka, če datoteka nastavi katero koli drugo lastnost gradnika, če vloga ne doseže najmanjšega kontrasta po WCAG 2.1 ali če bi barvo za dejanja lahko zamenjali z barvo uspeha, opozorila ali napake. Ogrodje aplikacije, tema za prijavo in predstavitvena stran ostanejo kopije, vendar v Reputu in Leadgenerju najprej uvozijo slogovno datoteko gradnika, nato &lt;code&gt;brand.css&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Najprej primerjano, nato izdano&lt;/h2&gt;
&lt;p&gt;Gradnik 1.0.0 je zvest prenos Leadgenerjeve kopije. Vsak vnos kataloga smo zajeli pri širinah 375, 768 in 1366 px ter gradnik z obema produktoma primerjali piksel za pikslom. Razen vnosov, ki so navedeni kot drugačni že po zasnovi, je edina sprememba izrisa popravek zavihkov, ki zdaj doseže tudi Reputo. Njegovih 384 posnetkov je postalo referenca za vsako zahtevo za združitev, ki gradnik spremeni.&lt;/p&gt;
&lt;p&gt;Pred objavo opravilo za izdajo zahteva, da se v registru preveri preizkusno objavljen kandidat iz iste kode, nato pa teste ponovno požene nad potrditvijo združitve (merge commit): za 1.0.0 jih je bilo 615. Reputo in Leadgener sta prevzela kandidata, svoj katalog in vseh devet strani teme za prijavo primerjala s tem, kar sta izrisala prej, in isti dan pripela 1.0.0.&lt;/p&gt;
&lt;p&gt;Če gradite na toolkitu, so barve vašega produkta ena datoteka, ki jo gradnik preveri: paleta s prešibkim kontrastom pade na testu znamke, še preden pride na zaslon. Popravek, kot je odmik v zavihkih, nastane enkrat, v gradniku, ne v vsaki kopiji.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Keycloak 26.0 → 26.8: kaj nas je presenetilo in kam smo to zapisali v gradniku</title>
    <link href="https://microsaaskit.dev/sl/novosti/keycloak-26-upgrade/"/>
    <id>https://microsaaskit.dev/sl/novosti/keycloak-26-upgrade/</id>
    <updated>2026-10-12T00:00:00Z</updated>
    <published>2026-10-12T00:00:00Z</published>
    <summary>Keycloak v gradniku smo v eni izdaji nadgradili za osem manjših različic. Kar nas je presenetilo, je zdaj v testu ali dnevniku sprememb; Reputo in Leadgener sta zamenjala le pripeto različico.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/keycloak-26-upgrade-sl.png&quot; alt=&quot;Terminal: vrstica FROM v Dockerfilu se premakne s Keycloaka 26.0.8 na 26.8.0, zbirka testov za sporočila pade, ker 26.8 prinaša še en JAR s temami, in uspe, ko prebere natanko enega.&quot;&gt;&lt;/p&gt;&lt;p&gt;Gradnik Keycloak 1.x je bil pripet na 26.0.8, ki za 26.8 zaostaja za osem manjših različic, in ni dobil nobenega popravka iz teh različic. Če bi vsak produkt nadgrajeval sam, bi vsak v svojem cevovodu naletel na ista presenečenja.&lt;/p&gt;
&lt;h2&gt;Ena nadgradnja, v gradniku&lt;/h2&gt;
&lt;p&gt;Gradnik Keycloak 2.0.0 s Keycloakom 26.8.0 smo izdali 12. oktobra 2026. V Dockerfilu gradnika sta to dve vrstici: &lt;code&gt;FROM&lt;/code&gt; s povzetkom (digest) in vrstica &lt;code&gt;LABEL&lt;/code&gt;, ki ponovi različico. Zbirka testov strukture zdaj preveri, ali se &lt;code&gt;LABEL&lt;/code&gt; ujema z vrstico &lt;code&gt;FROM&lt;/code&gt;. Kar nas je presenetilo, smo zapisali v test ali dnevnik sprememb.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Test, ki ni prebral ničesar.&lt;/strong&gt; Keycloak 26.8 poleg JAR-a s temami prinaša še &lt;code&gt;keycloak-themes-vendor-*.jar&lt;/code&gt;. Test sporočil je iskal &lt;code&gt;keycloak-themes-*.jar&lt;/code&gt;; vzorec je zajel obe datoteki, zato test ni kopiral nobene in je bilo videti, da Keycloak ne pozna nobenega od 32 slovenskih ključev. Prevod je bil v redu, test ne. Zdaj sprejme natanko en JAR in sam javi napako, če prebere manj kot 100 angleških ključev.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nove privzete vrednosti realma.&lt;/strong&gt; Realm, ki ga pripravi gradnik, se od tistega iz različic 1.x razlikuje le po Keycloakovih privzetih vrednostih za nov realm, kot kaže primerjava referenčnih izvozov realma. Med njimi so tri nova zahtevana dejanja, zahteva po shranjenem ključu (resident key) in preverjanju uporabnika pri prijavi WebAuthn brez gesla, odsotnost glave &lt;code&gt;X-XSS-Protection&lt;/code&gt; in odjemalec &lt;code&gt;realm-management&lt;/code&gt;, ki je v skrbniškem API-ju le za branje. Priprava realma se ni spremenila in sprejem pogojev uporabe ostaja privzeto zahtevano dejanje. Keycloak obstoječi realm migrira in ga ne ustvari znova, zato se njegove vrednosti lahko razlikujejo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Teme za prijavo.&lt;/strong&gt; Od 26.7 se predloge izvajajo s privzetimi nastavitvami FreeMarkerja 2.3.32, od 26.5 pa Keycloak HTML prikaže le še v sporočilu &lt;code&gt;termsText&lt;/code&gt;; prav to sporočilo lahko gradnik 2.1.0 nastavi tako, da vsebuje povezavi do pogojev uporabe in politike zasebnosti. Pred izdajo smo na novi sliki zgradili Reputovo temo: strani za prijavo in pogoje sta se prikazali brez napak v predlogah.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dnevnik sprememb navaja še: PostgreSQL 14 ali novejši, enkratne povezave za zahtevana dejanja, zavrnjene preusmeritvene naslove URI s parametrom &lt;code&gt;state&lt;/code&gt; ali &lt;code&gt;code&lt;/code&gt; ter korake za nadgradnjo iz gradnika 1.x.&lt;/p&gt;
&lt;p&gt;Reputo in Leadgener sta prešla isti dan, vsak s svojo zahtevo za združitev, ki spremeni le pripeto različico gradnika in komentar ob njej. Še isti večer smo 26.8.0 namestili v obe razvojni okolji.&lt;/p&gt;
&lt;p&gt;Ekipa, ki uporablja gradnik Keycloak, dobi nadgradnjo Keycloaka kot različico gradnika, ki je te teste že prestala, spremembe pa so zapisane v dnevniku sprememb. Na vas je, da pred prvim zagonom nove različice naredite varnostno kopijo baze Keycloaka, spremenite pripeto različico, na novi sliki zgradite svojo temo za prijavo, če jo imate, in v razvojnem okolju enkrat pregledate strani za prijavo, registracijo in pogoje.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Izdali smo okvarjen gradnik Keycloak 1.0.0</title>
    <link href="https://microsaaskit.dev/sl/novosti/keycloak-kit-1-0-0/"/>
    <id>https://microsaaskit.dev/sl/novosti/keycloak-kit-1-0-0/</id>
    <updated>2026-10-12T00:00:00Z</updated>
    <published>2026-10-12T00:00:00Z</published>
    <summary>Vsi testi so uspeli na sliki, ki je nismo objavili, objavljena pa ni mogla zagnati lastne priprave realma. Od 1.0.1 testi tečejo na sliki iz istega orodja kot objavljena, nato še na objavljeni.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/keycloak-kit-1-0-0-sl.png&quot; alt=&quot;Terminal: testi različice 1.0.0 na sliki iz docker build se končajo s FAILS=0, namestitev Reputa v razvojno okolje se ustavi s Permission denied, različica 1.0.1 pa po nalaganju prestane preverjanje dovoljenj.&quot;&gt;&lt;/p&gt;&lt;p&gt;Cevovod CI gradnika Keycloak je 11. oktobra 2026 na potrditvi različice 1.0.0 pognal vse svoje zbirke testov in javil &lt;code&gt;FAILS=0&lt;/code&gt;. Nato je opravilo za izdajo sliko naložilo v register. Štirinajst minut pozneje se je namestitev Reputa v razvojno okolje ustavila pri pripravi realma:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bash: /opt/microsaas/keycloak/setup: Permission denied
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Napaka in zakaj je testi niso ujeli&lt;/h2&gt;
&lt;p&gt;Imenik &lt;code&gt;/opt/microsaas/keycloak&lt;/code&gt; je imel dovoljenja 644. Brez bita za izvajanje vanj Keycloakov uporabnik (uid 1000) ni mogel vstopiti, zato se nista mogla zagnati ne &lt;code&gt;setup&lt;/code&gt; ne &lt;code&gt;require-terms&lt;/code&gt;. Dockerfile tega imenika ni ustvaril izrecno: nastal je kot nadrejeni imenik pri ukazu &lt;code&gt;COPY --chmod=644&lt;/code&gt; za datoteko s slovenskimi sporočili, njegova dovoljenja pa določi BuildKit, ki izvaja gradnjo.&lt;/p&gt;
&lt;p&gt;Različico 1.0.0 sta zgradila dva BuildKita. Testno opravilo je pognalo &lt;code&gt;docker build&lt;/code&gt; z BuildKitom, vgrajenim v Docker: imenik je dobil 755. Opravilo za izdajo je uporabilo buildx s privzeto sliko &lt;code&gt;moby/buildkit&lt;/code&gt; (brez pripete različice; takrat je bila to v0.33.1): imenik je dobil 644. Ista potrditev, isti Dockerfile, dve sliki. Vse zbirke testov so uspele na sliki, ki je nismo izdali, izdane pa ni preveril noben test.&lt;/p&gt;
&lt;p&gt;Razvojno okolje Reputa je delovalo naprej, ker je realm shranjen v podatkovni bazi. Različico 1.0.0 sta pripela le Reputo in Leadgener, ki še nista v produkciji.&lt;/p&gt;
&lt;h2&gt;Testiramo to, kar izdamo&lt;/h2&gt;
&lt;p&gt;Sprejeli smo pravilo: testiramo prav tisti artefakt, ki ga izdamo, zgrajen z orodjem, ki ga tudi objavi. Glavni popravek smo združili isti večer, različico 1.0.1 pa objavili naslednje jutro. V CI se je spremenilo tole:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;En BuildKit, pripet na različico in povzetek (digest) v &lt;code&gt;release/builder.sh&lt;/code&gt;, zgradi sliko za teste in sliko za register. Na povzetek je pripet tudi frontend, ki tolmači Dockerfile.&lt;/li&gt;
&lt;li&gt;Dockerfile vse imenike gradnika ustvari z dovoljenji 755, preden vanje kopira datoteke, zato ta niso več odvisna od orodja za gradnjo.&lt;/li&gt;
&lt;li&gt;Zbirka testov strukture kot uid 1000 preveri, da je mogoče vstopiti v vsak imenik ter prebrati ali zagnati vsako datoteko.&lt;/li&gt;
&lt;li&gt;Po nalaganju opravilo za izdajo prenese sliko, ki jo vrne register, in testira prav njo. Od različice 1.0.2 vsako pot pod &lt;code&gt;/opt/microsaas&lt;/code&gt; z dovoljenji in lastnikom v slikah za amd64 in arm64 primerja z vnaprej določenim seznamom, oznako različice pa ustvari šele, ko preverjanje obeh slik uspe.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Za ekipo, ki gradi na toolkitu, to pomeni: vsaka različica gradnika Keycloak od 1.0.2 naprej je bila testirana na sliki, ki jo je zgradil isti BuildKit kot objavljeno sliko, po objavi pa še enkrat preverjena na sliki, ki jo prenesete, za obe platformi. Povzetek slike vzamete iz opomb ob izdaji, različica, ki po nalaganju ne prestane preverjanja, pa nima ne opomb ne oznake: v dnevniku sprememb je označena kot okvarjena, popravek pa izide kot naslednja popravna različica.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Predstavitvena stran brez zahtev strežnikom tretjih oseb pred privolitvijo</title>
    <link href="https://microsaaskit.dev/sl/novosti/landing-no-third-parties/"/>
    <id>https://microsaaskit.dev/sl/novosti/landing-no-third-parties/</id>
    <updated>2026-10-12T00:00:00Z</updated>
    <published>2026-10-12T00:00:00Z</published>
    <summary>Dokler obiskovalec ne dovoli analitike, microsaaskit.dev ne pošlje zahtev strežnikom tretjih oseb; pisave in ikone gosti sama. Pajkom brez JavaScripta je namenjen llms.txt, jezika povezuje hreflang.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/landing-no-third-parties-sl.png&quot; alt=&quot;Število 0 in napis: zahtev strežnikom tretjih oseb pred privolitvijo, zabeleženih v Chromu brez grafičnega vmesnika in z novim profilom; domača stran prejšnje različice jih je poslala najmanj 11.&quot;&gt;&lt;/p&gt;&lt;p&gt;Do 12. oktobra je stran microsaaskit.dev, še preden je obiskovalec prebral prvo besedo, prenesla pisavo IBM Plex iz storitve Google Fonts, Font Awesome iz omrežja CDN, Tailwind kot skript, ki je sloge prevajal v brskalniku, in Google Analytics. Zadnjo različico pred spremembo smo znova zgradili in njeno domačo stran naložili v Chrome brez grafičnega vmesnika (headless): ob prvem obisku je, ne da bi obiskovalca kaj vprašala, poslala 11 zahtev petim strežnikom tretjih oseb; zahteve za Google Analytics, ki smo jo pri meritvi blokirali, nismo šteli.&lt;/p&gt;
&lt;h2&gt;Kaj smo spremenili&lt;/h2&gt;
&lt;p&gt;Google Analytics se zdaj naloži šele, ko obiskovalec izbere »Dovoli analitiko«. Gumb »Zavrni« je tik ob njem, enako velik in enako oblikovan, povezava »Nastavitve piškotkov« v nogi pa pasico odpre znova. Pisave zdaj gostimo sami: dve družini IBM Plex v podmnožicah latin in latin-ext, 14 datotek, ki jih gradnja prekopira iz paketov Fontsource. Namesto Font Awesome stran uporablja ikone Lucide in Simple Icons (logotipi znamk); gradnja jih v vsako stran vgradi kot eno zbirko SVG (sprite) in se konča z napako, če stran uporabi ikono, ki je v zbirki ni. Tailwind se prevede ob gradnji.&lt;/p&gt;
&lt;p&gt;Istega dne sta nastali dve statični strani, angleška na &lt;code&gt;/&lt;/code&gt; in slovenska na &lt;code&gt;/sl/&lt;/code&gt;, povezani z atributom &lt;code&gt;hreflang&lt;/code&gt;; &lt;code&gt;/&lt;/code&gt; je privzeta (&lt;code&gt;x-default&lt;/code&gt;), &lt;code&gt;sitemap.xml&lt;/code&gt; pa pri vsaki strani navaja obe jezikovni različici. Tloris tovarne nariše JavaScript; brez njega je besedilo tlorisa le blok JSON. Pajku, ki JavaScripta ne izvaja, zato &lt;code&gt;llms.txt&lt;/code&gt; ponudi ista dejstva v Markdownu, ustvarjena iz istih datotek &lt;code&gt;en.json&lt;/code&gt; in &lt;code&gt;factory-data.js&lt;/code&gt; kot stran.&lt;/p&gt;
&lt;h2&gt;Seznam zahtev&lt;/h2&gt;
&lt;p&gt;Dokaz ni izvorna koda, temveč seznam zahtev v brskalniku. Na živi strani smo naložili &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;/sl/&lt;/code&gt; in obe obvestili o zasebnosti, iz lokalne gradnje pa še strani z novostmi, v Chromu brez grafičnega vmesnika, z novim profilom in brez privolitve, ter prek protokola DevTools zabeležili vsako zahtevo. Vse zahteve so šle na izvor (origin), s katerega je bila stran naložena, od 7 do 16 na stran. Slovenske strani so prenesle še datoteke pisav latin-ext, za č, š in ž.&lt;/p&gt;
&lt;p&gt;V lokalni gradnji smo nato kliknili »Dovoli analitiko«. Pojavila sta se dva strežnika: eden streže skript gtag, na drugem je končna točka za zbiranje podatkov, vsak z eno zahtevo na stran. Ko smo v »Nastavitvah piškotkov« izbrali »Zavrni«, piškotkov &lt;code&gt;_ga&lt;/code&gt; ni bilo več, ponovno naložena stran pa je zahteve spet pošiljala samo na svoj izvor.&lt;/p&gt;
&lt;p&gt;Za ekipo, ki gradi na toolkitu: pasica za privolitev je trditev, seznam zahtev pa njen test. Preden objavite predstavitveno stran svojega produkta, jo naložite z novim profilom brskalnika in brez privolitve ter preglejte seznam strežnikov. Če vsebino strani nariše JavaScript, iz istega vira ustvarite še besedilno različico, kot je tu &lt;code&gt;llms.txt&lt;/code&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Pravilo žetve: kdaj koda postane gradnik</title>
    <link href="https://microsaaskit.dev/sl/novosti/harvest-rule/"/>
    <id>https://microsaaskit.dev/sl/novosti/harvest-rule/</id>
    <updated>2026-10-11T00:00:00Z</updated>
    <published>2026-10-11T00:00:00Z</published>
    <summary>Koda postane gradnik šele, ko jo potrebuje drugi produkt in se med produkti ne sme razlikovati. Produkti različico gradnika pripnejo in njegove kode ne spreminjajo. Primer je gradnik Keycloak.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/harvest-rule-sl.png&quot; alt=&quot;Diagram: Reputo in Leadgener predata svoji kopiji skupnemu gradniku Keycloak; prenos je zvest, enakost pa dokazujejo izvozi realma.&quot;&gt;&lt;/p&gt;&lt;p&gt;Produkt najprej v svojem repozitoriju zgradi, kar potrebuje. Vprašanje je, kdaj del te kode postane gradnik. Če kodo v gradnik prenesemo prezgodaj, načrtujemo za produkte, ki jih še ni. Če prepozno, se kopije razhajajo: isti popravek priprave Keycloaka je 10. oktobra prišel v Reputo in Leadgener z dvema zahtevama za združitev, po eno za vsako kopijo.&lt;/p&gt;
&lt;h2&gt;Dva pogoja, oba nujna&lt;/h2&gt;
&lt;p&gt;Kodo prenesemo v gradnik samo, kadar isto delovanje potrebuje tudi drugi produkt in se to delovanje ne sme razlikovati, ker gre za varnost, pravne zahteve, obratovanje ali pogodbo vmesnika API. Če drži le prvi pogoj, drugi produkt kodo prekopira in odtlej sam skrbi za svojo kopijo. Zato ogrodje aplikacije, tema za prijavo in predstavitvena stran ostajajo kopije. V šestih mesecih morata gradnik uporabljati vsaj dva produkta, sicer ga vrnemo v produkt, iz katerega izhaja.&lt;/p&gt;
&lt;p&gt;Za produkt velja druga polovica pravila: kode gradnika ne spreminja. Pripne različico, spremembo gradnika pa naredimo v gradniku in jo izdamo kot novo različico. Za pakete NuGet ima vseh pet produktov v datoteki CI isto preverbo:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;test ! -e libs/microsaas-toolkit || { echo &amp;quot;libs/microsaas-toolkit is back; change the toolkit in its own repository&amp;quot;; exit 1; }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Kako je nastal gradnik Keycloak&lt;/h2&gt;
&lt;p&gt;Reputo in Leadgener sta imela vsak svojo kopijo skripta za pripravo realma, dolgo 347 oziroma 348 vrstic. Skript nastavi, kar mora biti enako v vsakem realmu, na primer izklopljeno samoregistracijo in PKCE z metodo S256 za odjemalce v brskalniku. Kopija v Leadgenerju je nastala 8. oktobra; tri dni pozneje sta se kopiji poleg privzetih vrednosti posameznega produkta razlikovali še v komentarjih in opisu ene vloge.&lt;/p&gt;
&lt;p&gt;Pripravo realma smo v gradnik Keycloak prenesli 11. oktobra 2026, in to zvesto: iz enakih vrednosti nastane enak realm, čiščenja kode pa v istem koraku ni bilo. Na novi namestitvi Keycloaka smo zagnali najprej skripte vsakega produkta, nato gradnik, in za vsak produkt primerjali normalizirana izvoza realma. Bila sta enaka do zadnjega bajta, razen opisa tiste vloge. To odstopanje je skupaj z razlogom zapisano v datoteki odstopanj.&lt;/p&gt;
&lt;p&gt;Nato je vsak produkt kopijo zamenjal s svojo zahtevo za združitev. Skript se je skrčil na ovojni skript, ki vsebuje le privzete vrednosti produkta: v Reputu ima 46 vrstic, v Leadgenerju 47. Sliko gradnika ima vsak produkt pripeto na različico in povzetek (digest).&lt;/p&gt;
&lt;p&gt;Gradnik Keycloak je torej koda, ki je že tekla v dveh produktih in je prenesena tako, da deluje enako kot tam. To dokazujejo testi, katerih rezultat pregledovalec vidi kot razliko v datotekah. Kadar gradnik ne naredi, kar potrebujete, ga ne popravljate v svojem produktu. Zaprosite za novo nastavitev, ki pride v manjši izdaji (minor) in privzeto ohrani dosedanje delovanje, to izdajo pa pripnete, ko se odločite sami. Kar potrebuje samo vaš produkt, ostane vaše.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Leadgener iz praznega repozitorija: 45 ur do razvojnega okolja</title>
    <link href="https://microsaaskit.dev/sl/novosti/leadgener-first-days/"/>
    <id>https://microsaaskit.dev/sl/novosti/leadgener-first-days/</id>
    <updated>2026-10-10T00:00:00Z</updated>
    <published>2026-10-10T00:00:00Z</published>
    <summary>Leadgener je začel nastajati 8. oktobra 2026 iz našega referenčnega produkta. Po 45 urah je prva namestitev prestala preverjanja zdravja, vmes pa smo delali predvsem na njegovi domeni.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/leadgener-first-days-sl.png&quot; alt=&quot;Število 45 in napis: toliko ur je minilo od prve Leadgenerjeve potrditve do prvega nameščenega razvojnega okolja; toolkit in ogrodje zaledja sta bila na mestu po 12 minutah.&quot;&gt;&lt;/p&gt;&lt;p&gt;Leadgener išče in spremlja poslovne priložnosti v javnih virih. Iz praznega repozitorija je začel nastajati 8. oktobra 2026; še ga gradimo, zato teče samo v razvojnem okolju. Nov produkt je mogoče presoditi šele, ko je nameščen in zaščiten z lastno prijavo.&lt;/p&gt;
&lt;h2&gt;Kopija referenčnega produkta, nova barvna paleta&lt;/h2&gt;
&lt;p&gt;Leadgenerjev ADR-02, sprejet prvi dan, določa Reputo, naš &lt;a href=&quot;/sl/novosti/reputo-on-the-toolkit/&quot;&gt;referenčni produkt&lt;/a&gt;, za verodostojni vir glede tehnologije, vzorcev in komponent. Spremeni se samo barvna paleta, vsako drugo odstopanje pa potrebuje svoj ADR.&lt;/p&gt;
&lt;p&gt;Prva potrditev (commit) je vsebovala samo produktne dokumente. Deset sekund pozneje je v repozitorij prišel toolkit, kopiran brez sprememb: 167 datotek in 11.414 vrstic. Po dvanajstih minutah je sledilo ogrodje zaledja po Reputovih vzorcih, z moduli za najemnike, uvajanje in organizacije, brez obračunavanja.&lt;/p&gt;
&lt;p&gt;Naslednjih šest ur je bilo namenjenih Leadgenerjevi domeni: zajemu objav iz javnih virov, dokumentom in slovarju ključnih besed, oceni na podlagi dokazov z izbirnim ponudnikom modela ter zaslonom za pregled rezultatov. Po 23 urah smo iz Reputa prenesli še namestitev: datoteko CI, datoteke Dockerfile, datoteko Compose in skripte za namestitev.&lt;/p&gt;
&lt;h2&gt;Kako je minilo 45 ur&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Po 30 urah je nastal projekt na GitLabu; do takrat je repozitorij namenoma ostal samo lokalen.&lt;/li&gt;
&lt;li&gt;Po 31 urah so se na veji main testi končali uspešno, nato je ukaz &lt;code&gt;dotnet restore&lt;/code&gt; pri gradnji slik vsebnikov obstal: po desetih minutah je javil napako &lt;code&gt;NU1301&lt;/code&gt;, pol ure pozneje pa je še vedno poskušal znova. Reputo je na isto težavo naletel 2. oktobra in jo odpravil z &lt;code&gt;docker build --network host&lt;/code&gt;: omrežni most v Docker-in-Docker ima večji MTU kot omrežje izvajalnika (runner). Pri prenosu se je zastavica izgubila. Vrnila jo je ena zahteva za združitev, slike pa so bile zgrajene devet minut po njeni združitvi.&lt;/li&gt;
&lt;li&gt;Po 45 urah se je zagnalo ročno opravilo &lt;code&gt;deploy:dev&lt;/code&gt;, ki je čez noč čakalo 13,5 ure. V 1 minuti in 50 sekundah je zagnalo sedem vsebnikov, ustvarilo realm Keycloak in prestalo šest preverjanj zdravja: API-ja, aplikacije, realma, teme za prijavo in dveh predstavitvenih strani.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Za ekipo, ki na toolkitu začenja nov produkt, Leadgenerjev primer kaže približno dva dni do nameščenega razvojnega okolja, večina dela v teh dneh pa je bila namenjena samemu produktu. Še isti dan je Leadgener kopijo toolkita zamenjal s paketi NuGet, pripetimi na eno različico. Datoteka CI in skripti za namestitev so ostali preneseni iz referenčnega produkta, Leadgenerjev prvi cevovod pa kaže, koliko to stane: referenčna datoteka CI je zastavico imela, skupaj s komentarjem, ki jo pojasnjuje, pri prenosu pa sta se izgubila oba. Preden prvič potisnete v main, svoj cevovod primerjajte z referenčnim.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>19 paketov, ena različica</title>
    <link href="https://microsaaskit.dev/sl/novosti/toolkit-one-version/"/>
    <id>https://microsaaskit.dev/sl/novosti/toolkit-one-version/</id>
    <updated>2026-10-10T00:00:00Z</updated>
    <published>2026-10-10T00:00:00Z</published>
    <summary>Pet ločenih kopij naših modulov SaaS smo zamenjali z 19 paketi NuGet, ki imajo isto različico. Vsak produkt jo pripne v eni vrstici in se nadgradi, ko se sam odloči.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/toolkit-one-version-sl.png&quot; alt=&quot;Število 19 z napisom: paketi NuGet, ena različica, brez obveznih skupnih nadgradenj.&quot;&gt;&lt;/p&gt;&lt;p&gt;Pred izdajo 1.0.0 je imel vsak od naših petih produktov svojo kopijo skupnih modulov SaaS za najemnike, uvajanje, organizacije, pravice do funkcij, merjenje porabe, obračunavanje in skrbniški API. Kopije so bile prenesene v repozitorij vsakega produkta, najstarejša pa je za najnovejšo zaostajala približno osem mesecev. Ko smo pisali navodila za nadgradnjo na prvo izdajo, je Gostly potreboval en seznam sprememb, MojRazpis in SnapMind pa daljši. Popravek v eni kopiji je prišel do drugih le, če ga je kdo prenesel ročno.&lt;/p&gt;
&lt;h2&gt;Ena različica za vse pakete&lt;/h2&gt;
&lt;p&gt;Skupno kodo smo 10. oktobra 2026 označili z &lt;code&gt;v1.0.0&lt;/code&gt; in jo objavili kot 19 paketov NuGet &lt;code&gt;MicroSaas.Toolkit.*&lt;/code&gt; z eno samo različico. Nastavitve gradnje so v eni datoteki &lt;code&gt;Directory.Build.props&lt;/code&gt;, cevovod ob oznaki pa vsem projektom poda &lt;code&gt;-p:Version=X.Y.Z&lt;/code&gt;, zato se tudi paketi med seboj sklicujejo na isto različico. Opravilo za objavo se ustavi, če &lt;code&gt;CHANGELOG.md&lt;/code&gt; za to različico nima razdelka ali jo še označuje kot neizdano, in prešteje zapakirane pakete:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;[ &amp;quot;$count&amp;quot; -eq 19 ] || { echo &amp;quot;expected 19 packages, packed $count&amp;quot;; exit 1; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Register paketov je nastavljen tako, da iste različice ne sprejme dvakrat, zato 1.0.0 pomeni enako kodo v vsakem produktu.&lt;/p&gt;
&lt;p&gt;V produktu je različica ena sama lastnost v njegovi datoteki &lt;code&gt;Directory.Build.props&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;MicroSaasToolkitVersion&amp;gt;1.0.0&amp;lt;/MicroSaasToolkitVersion&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vsak &lt;code&gt;PackageReference&lt;/code&gt; na pakete toolkita prebere to lastnost. Produkti uporabljajo različne podmnožice paketov: Leadgener 6 od 19; Reputo 16; Gostly, MojRazpis in SnapMind po 17.&lt;/p&gt;
&lt;h2&gt;Kaj to stane in česa ne pomeni&lt;/h2&gt;
&lt;p&gt;Cena je zapisana v naši zasnovi: produkt ne more prevzeti popravka v modulu Organizations brez sprememb v modulu Billing iz iste izdaje. Pri enem vzdrževalcu je eno zaporedje različic cenejše od devetnajstih, dnevnik sprememb pa to ceno pokaže vnaprej. Dnevnik vsako spremembo, ki zahteva poseg, označi z &lt;code&gt;[migration]&lt;/code&gt;, &lt;code&gt;[contract]&lt;/code&gt; ali &lt;code&gt;[behaviour]&lt;/code&gt; in za vsako izhodišče navede, kaj mora produkt spremeniti pred nadgradnjo.&lt;/p&gt;
&lt;p&gt;Ena različica ne pomeni skupnih nadgradenj. Nobena izdaja ne zahteva, da se dva produkta nadgradita hkrati. Vsak produkt je na 1.0.0 prešel s svojo zahtevo za združitev (merge request) v svojem repozitoriju. Vseh pet smo združili isti dan, ker so vsi produkti opuščali svoje kopije, ne zato, ker bi to zahtevala izdaja. Produkt, ki bo želel naslednjo izdajo, jo bo prevzel s spremembo ene vrstice, ko se bo za to odločil sam.&lt;/p&gt;
&lt;p&gt;Za ekipo, ki gradi na toolkitu, to pomeni: pripnete eno številko, pred nadgradnjo preberete razdelke dnevnika sprememb med svojo in novo različico ter se nadgradite, ko vam ustreza, ne ko ustreza nam. Če dva produkta uporabljata različni izdaji toolkita, je to povsem sprejemljivo, ker si delita kodo, nikoli pa delujoče instance.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Reputo na toolkitu: kaj je prišlo prvi dan in kaj smo zgradili sami</title>
    <link href="https://microsaaskit.dev/sl/novosti/reputo-on-the-toolkit/"/>
    <id>https://microsaaskit.dev/sl/novosti/reputo-on-the-toolkit/</id>
    <updated>2026-10-02T00:00:00Z</updated>
    <published>2026-10-02T00:00:00Z</published>
    <summary>Reputo malemu podjetju pove, ali njegova e-pošta pride do prejemnikov in kaj naj popravijo informatiki. Prvo jutro je bilo 34 od 42 poti API iz toolkita, naslednjih 12 dni smo porabili za produkt.</summary>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://microsaaskit.dev/news/reputo-on-the-toolkit-sl.png&quot; alt=&quot;Število 34 z napisom: od 42 poti API jih je prvi dan prišlo iz toolkita; 12 dni od prve potrditve do prve namestitve v razvojno okolje.&quot;&gt;&lt;/p&gt;&lt;p&gt;Reputo je namenjen vodji marketinga v malem podjetju, ki svoje kampanje pošilja samostojno. V preprostem jeziku mu pove, ali e-pošta podjetja prihaja do prejemnikov, kaj je narobe in kaj naj spremenijo informatiki. Teče v razvojnem okolju, v produkciji pa še ni.&lt;/p&gt;
&lt;p&gt;Za temi odgovori stoji večnajemniška storitev SaaS: organizacije, člani, naročniški paketi, omejitve porabe in skrbniški vmesnik za upravljavca. Za nič od tega kupec ne plača, vse pa mora delovati, preden se prijavi prva stranka.&lt;/p&gt;
&lt;h2&gt;Prvi dan: toolkit&lt;/h2&gt;
&lt;p&gt;Prva potrditev (commit) Reputa 20. septembra 2026 je vsebovala jedro za preverjanje domen, na novo zgrajeno iz prejšnjega dela, in kopijo našega toolkita v samem repozitoriju. Še isto jutro je API tekel na pravi bazi PostgreSQL in ponujal 42 poti. Štiriintrideset jih je prišlo iz toolkita, iz modulov za uvajanje, organizacije, pravice do funkcij, merjenje porabe, obračunavanje in skrbniški API. Od 12 tabel v prvi migraciji jih je bilo 11 iz toolkita.&lt;/p&gt;
&lt;p&gt;Reputov &lt;code&gt;AppDbContext&lt;/code&gt; je izpeljan iz razreda &lt;code&gt;OrganizationDbContextBase&lt;/code&gt; iz toolkita, zato vsaka entiteta, ki pripada organizaciji, dobi filter po najemniku; nanj se zanašajo tudi poizvedbe po spremljanih domenah. Na strani SaaS je bila Reputova lastna koda tisti dan le povezava modulov v &lt;code&gt;Program.cs&lt;/code&gt;, naročniški paketi Free, Pro in Business s kvotami ter kljuka (hook), ki vsaki novi organizaciji ob nastanku dodeli paket Free.&lt;/p&gt;
&lt;h2&gt;Dvanajst dni: produkt&lt;/h2&gt;
&lt;p&gt;Naslednjih dvanajst dni smo posvetili Reputovi lastni kodi okoli tega jedra: zbirnim poročilom DMARC, ki jih Reputo pobira iz poštnega predala, razčlenjenim po ponudnikih, ki so pošto prejeli; incidentom z obvestili po e-pošti v slovenščini; povezavam z Google Postmaster in Microsoft SNDS ter zaslonom. Vejo &lt;code&gt;main&lt;/code&gt; smo prvič namestili v razvojno okolje 2. oktobra. Pri prvem poskusu se Keycloak ni zagnal; drugi, manj kot pol ure pozneje, je prestal preverjanja API-ja, aplikacije in realma Keycloak.&lt;/p&gt;
&lt;p&gt;Za ekipo, ki na toolkitu začenja nov produkt, je pravo merilo, za kaj porabi prve tedne. V Reputu so bili najemniki, člani, pravice do funkcij, omejitve porabe in skrbniške končne točke v API vključeni že prvo jutro, dvanajst dni do razvojnega okolja pa smo porabili za preverjanja, poročila in opozorila, za katera bi plačal kupec.&lt;/p&gt;
</content>
  </entry>
</feed>
