Jak postawiłem wersję developerską PlanBudowlany na homelabie

Od kilku miesięcy rozwijam własny projekt SaaS — Plan Budowlany — platformę do zarządzania projektami budowlanymi. W tym wpisie opiszę, czym jest projekt, jak wygląda środowisko developerskie postawione na homelabie, jak korzystam z agentów AI w codziennej pracy oraz kilka ciekawych decyzji technicznych, które po drodze podjąłem.

Czym jest Plan Budowlany?

Plan Budowlany to platforma SaaS do zarządzania projektami budowlanymi. Kierownicy budów, deweloperzy i generalni wykonawcy mogą tam prowadzić:

  • Zadania i podzadania — z przypisaniem, statusem, terminami i zależnościami
  • Tablicę Kanban — widok kart dla całego zespołu
  • Kosztorysy — śledzenie wydatków per projekt
  • Pliki i dokumenty — z kategoryzacją i przechowywaniem w chmurze
  • Dziennik budowy — automatyczny log zdarzeń z osi czasu
  • Komunikację — powiadomienia email i WhatsApp
Dashboard Plan Budowlany
Główny widok dashboardu
Tablica Kanban
Tablica Kanban — widok zadań w kolumnach

Stack technologiczny

Starałem się postawić na sprawdzone, nowoczesne technologie z ekosystemu .NET i cloud-native:

WarstwaTechnologia
Backend.NET 10 (C#), Clean Architecture, CQRS
FrontendVue.js 3 + Vite
Baza danychPostgreSQL 16 + EF Core
Event StoreMarten (PostgreSQL-based)
MessagingKafka (Confluent Cloud na prod)
Async tasksHangfire
StorageAzure Blob Storage + opcjonalnie Google Drive
OrchestrationKubernetes (DOKS na prod, k3s na dev)
AuthOpenIddict (OAuth2/OIDC)

Architektura — od mikrousług do modularnego monolitu

Projekt startował jako zestaw mikrousług (API, Communication Service, Storage Service). Po kilku miesiącach podjąłem decyzję (ADR-007) o konsolidacji do modularnego monolitu — jednego deploymentu z logicznie oddzielnymi modułami:

  • Identity Module — uwierzytelnianie i zarządzanie użytkownikami
  • Task Module — zadania, podzadania, kanban
  • Cost Module — kosztorysy
  • Storage Module — pliki i dokumenty
  • Communication Module — emaile i powiadomienia

Każdy moduł stosuje Clean Architecture z warstwami Domain → Application (CQRS Commands/Queries) → Infrastructure → Presentation. Do komunikacji między handlerami używam lekkiego, własnego IMediator.

Event Sourcing z Marten

Wszystkie zdarzenia domenowe trafiają do Marten (event store na bazie PostgreSQL). Projekcje Martena budują read modele — np. TaskListReadModel czy ConstructionLogProjection (dziennik budowy). Kluczowa decyzja: używam inline projections zamiast async, żeby uniknąć eventual consistency między komendą a odczytem. Frontend dostaje świeże dane natychmiast po mutacji.

Lista zadań
Lista zadań z statusami i priorytetami
Szczegóły zadania
Szczegóły zadania — historia, komentarze, podzadania

Środowisko developerskie — homelab

Projekt działa na trzech środowiskach:

ŚrodowiskoHostingGateway
LocalDocker ComposeLocalhost
Dev/Testk3s (homelab)Cloudflare Tunnel
ProdDigitalOcean DOKSDO Load Balancer

Na co dzień pracuję lokalnie z Docker Compose — jeden plik docker-compose.yaml podnosi PostgreSQL, API i frontend. Do testowania integracji z zewnętrznymi serwisami (Kafka, Cloudflare) mam osobny klaster k3s z dostępem przez Cloudflare Tunnel. Pozwala mi to mieć realistyczne środowisko bez płacenia za chmurę podczas developmentu.

Deployment na k3s i prod obsługuje GitHub Actions: PR → testy jednostkowe + integracyjne → merge do develop → auto-deploy na k3s. Merge do main → auto-deploy na DOKS. Obrazy Docker lądują na Docker Hub pod tagiem sha-<commit> i latest.

Agenci AI w codziennej pracy

Używam Claude Code jako głównego narzędzia developerskiego, ale nie jako prostego asystenta do pisania kodu. Zbudowałem zestaw customowych skills (agentów z określonymi zadaniami), które automatyzują powtarzalne procesy:

  • k8s-log-triage — agent diagnozuje błędy w podach Kubernetes, analizuje logi z Azure App Insights, tworzy issues na GitHub i wysyła raporty na Discorda
  • generate-feedback-report — pobiera feedback użytkowników z Firebase Firestore i generuje miesięczny raport Markdown z podziałem na błędy i sugestie
  • generate-changelog-post — czyta changelog.json i automatycznie generuje wpis o nowej wersji na landing page
  • feature-dev — prowadzi przez proces implementacji nowej funkcji: eksploracja kodu → projekt architektury → review → implementacja
  • brainstorming — przed każdą większą decyzją techniczną przeprowadza ustrukturyzowaną sesję, proponuje 2-3 podejścia z trade-offami

Dzięki temu zamiast pisać ręcznie raporty czy debugować logi, wydaję komendę i dostaję gotowy wynik. To realnie oszczędza kilka godzin tygodniowo.

Ciekawe case’y techniczne

Dual-write storage: Azure Blob + Google Drive

Pliki użytkowników trafiają na Azure Blob Storage (primary, EU region, RODO-compliant) z opcjonalną synchronizacją do Google Drive użytkownika. Strategia dual-write daje redundancję i pozwala użytkownikom mieć kopię plików we własnym Drive’ie. Limit to 1 GB na workspace w fazie beta.

Kosztorysy
Moduł kosztorysów i śledzenia wydatków

Hangfire zamiast Kafki do wewnętrznych tasków

Kafka świetnie sprawdza się do komunikacji między serwisami, ale dla wewnętrznych asynchronicznych zadań (wysyłka emaili, powiadomień WhatsApp) okazała się zbyt ciężka operacyjnie. Zastąpiłem ją Hangfire — prostszym, sprawdzonym narzędziem do background jobs. Kafka pozostała tylko do event streamingu między modułami.

Komunikacja
Moduł komunikacji i powiadomień

Onboarding z rolami i zaproszeniami

Onboarding
Ekran onboardingu nowego użytkownika

Workspace oparty jest na ścisłej autoryzacji — każde żądanie API wymaga nagłówka X-Workspace-Id. Użytkownicy mogą być zapraszani do workspace’ów z rolami Owner/User/DemoUser. DemoUser to specjalny tryb — pełen dostęp do podglądu, zero możliwości modyfikacji. Przydatne do prezentacji klientom.

Chcesz przetestować?

Jeśli jesteś kierownikiem budowy, deweloperem nieruchomości lub po prostu ciekawi Cię projekt — zapraszam na planbudowlany.online. Możesz założyć konto i samodzielnie przetestować aplikację. Feedback mile widziany!

Sam projekt rozwijam solo w wolnym czasie, więc iteracje są spokojne — ale konsekwentne. Jeśli masz pytania o architekturę, stack lub sposób pracy z agentami AI — napisz w komentarzu.

LifeLike – TDD

Po tygodniu na Islandii wypadłem z obiegu i wprawy w pisaniu bloga.
Jednak po powrocie, trzeba ruszyć pełną parą. Tematem dzisiejszego postu są Testy i początek wprowadzenia TDD do projektu. Coś, co mi się przyda do projektów prywatnych jak i służbowych.
Tak więc zacznijmy!
Czytaj dalej „LifeLike – TDD”

Odkrywanie kawy

UWAGA:

WPISY NA TEMAT KAW SĄ DOSTĘPNE NA http://kawowipodroznicy.pl

Zapraszam 🙂

Pierwsza Kawa

Do napisania tego postu oraz nowego cyklu na blogu zainspirowało mnie parę wydarzeń, między innymi WroBlog 2016, wizyty w paru kawiarniach oraz eksperymentowanie z Aeropressem. Wpis ten powstaje w oparciu o moje własne doświadczenia, naukę i porady znajomych.

DSC_4482
Wtedy jeszcze nie wiedziałem, że przedawkowanie kofeiny to takie zło

Historia

Moja przygoda z kawą zaczęła się wraz z pierwszą wizytą we Wrocławiu (wcześniej po prostu unikałem picia kawy). Moją pierwszą latte wypiłem we Wrocławskiej kawiarni  Vinyl Cafe, miejscu z domowym klimatem i muzyką z płyt winylowych w tle. Nie był to czas, w którym zwracałem uwagę, skąd pochodziła kawa, ale właśnie akurat wtedy przestałem pić colę, a kawa była jedynym napojem, który dosładzałem cukrem (trzcinowym… so hipsta)

Latte W Bergamo
Latte W Bergamo

Parę miesięcy później, podczas przeprowadzki do Wrocławia, zaczęły się moje pierwsze eksperymenty z kawą  (w postaci latte w proszu z mlekiem proszku).  Wyglądało to jak latte, ale smakowało znacznie gorzej niż w kawiarniach.  Zacząłem odwiedzać McCafe (to tu zaczynała się kultura, czyli tam gdzie kończyły się tłumy po Wieś Burgera:) ). Wizyty były na porządku dzienny, gdy mieszkało się w okolicach rynku (chadzam tam do teraz, ze względu na dobre Chai Latte i miłą, obeznaną i ładną obsługę ). Do kawalerki na ulicy Kazimierza Wielkiego przybyła też pierwsza kawiarka. Wciąż raczkujący kawosz, nabywałem i eksperymentowałem z kawami smakowymi z sieciówek (5 o’clock oraz Świat Kawy i Herbaty). Przyznam, że ich kawa miętowa i Chilli Chocolate z odpowiednią spienionym mlekiem potrafiły sprawić, że nie myślałem już o słodzeniu kawy, bo sama w sobie miała dobry smak. Przestałem też używać cukru pijąc kawę w kawiarniach. Nie były mi obce eksperymenty z przyprawami i innymi dodatkami; raz wychodziły, innym razem nie do końca. Największy przełom w odkrywaniu bogactwa kawy nastąpił gdy zacząłem zaopatrywać się w ziarna z lokalnych palarni (gdzie swoją drogą kawę parzą dobrze, ale kawy dobrej zaparzyć już nie potrafią, przynajmniej w oficjalnym punkcie). Wtedy nie miałem jeszcze młynka, więc prosiłem o zmielenie na miejscu (wybaczcie, jeszcze nie znałem różnicy między ziarnami mielonymi wcześniej, a tymi zmielonymi na chwilę przed zaparzeniem). Mimo tego wyczuwałem już całkiem sporą różnicę w smaku. Zdarzyło mi się również mieć przygodę z hipsterskim Bulletproof, czyli  latte na oleju kokosowym. Następnym krokiem na drodze do ciemnej strony mocy była fascynacja włoską kawą, którą miałem okazję wypić w Bergamo, gdzie kawa była delikatniejsza, aromantyczna a dobrze spienione mleko doskonale podkreślało smak kawy. Zacząłem szukać w kawie czegoś więcej. Wpadłem po uszy w temat i chcę podzielić się swoją wiedzą,  na temat kaw.

Sprzęt

 

Zestaw małego Kawosza
Zestaw małego Kawosza

Któregoś dnia, pod wpływem chwili, zamówiłem w sklepie internetowym CoffeeDesk (akurat trafiłem na dzień darmowej dostawy)  Aeropress i Rhynoware (młynek). Po naprawdę wielu próbach dzielę się z Wami swoimi  przemyśleniami, radami i oraz przepisami na kawę  parzoną na gorąco oraz na zimno.

Mój Zestaw, który zakupiłem się składa się z :

Aeropress (kryptonim: strzykawka), który swoją drogą mimo prostoty mechanizmu, nie ma na rynku odpowiedników od konkurencji (chyba że na chińskim aliexpress pod nazwą Airpress,który znajdziecie za podobną cenę). Urządzenie jest proste w budowie. Działanie niemal podobne, do strzykawki, gdzie zamiast igły, plastikowa tuba zakończona jest przykręcanym plastikowym filtrem, na którym umieszczony jest papierowy lub metalowy filtr. Z racji użytego materiału, Aeopress jest niemal odporny na wszelkie upadki, ubicia i inne niewielkie eksperymenty, które źle się mogą w kuchni skończyć.

Filtry papierowe (można dokupić za kolejne grosze  lub zakupić specjalne metalowe filtry).

– Plastikowego mieszadełka i  Plastikowej łyżeczki (w sumie, rączką od łyżeczki) też <- tego  nie ogarniam co to, ale średnio po polsku  😛

– Lejek, aby wsypać kawę do strzykawki, a nie obok

– Młynek do kawy  (Rhynoware)

– Termometr do wody

DSC_4550

Ciekawe Kawiarnie

Na koniec 1 części wpisu z cyklu kawowego, zaprezentuję 2 polecane kawiarnie. W ramach zwiedzania, w następnych częściach pojawią inne przybytki warte odwiedzenia.

  1. Vinyl Cafe – Wrocław, Ulica Kotlarska 35.  – O niej wspominałem już w mojej historii Kawowej.  Poza dobrą kawą, polecam również spróbować ich napój imbirowy. Najbardziej w tej kawiarni przyciąga kolekcja vinyli, które towarzyszą przy delektowaniu się dobrą kawą.  Można też poczytać książkę oraz pograć w gry planszowe

    Latte w Vinyl Cafe
    Latte w Vinyl Cafe
  2. Motoracer Garage Coffee– Wrocław, Ulica Swojczycka 82 – Kawiarnię odkryłem, gdy ekspres do kawy, który mamy w firmie padł.  Kawiarnia posiada naprawde świetną atmosferę. Co 2 tydzień w piątki organizowane są tam spotkania. Co najważniejsze, mają bardzo dobrą kawę. Przy okazji, są moim prywatnym  lokalnym dealerem kaw z palarni. Szczególnie polecam u nich Flat White.  Warto odwiedzić ze  względu na miłą obsługę, dobry klimat oraz warsztat z starymi motocyklami.  Miejsce, do którego chce się wracać, choćby tylko dla tego, by poobserwować, porozmawiać i popić do tego dobrą kawę.  W tej kawiarni, dostałem też dobre rady, na temat parzenia kaw, za pomocą metod alternatywnych.

    Latte w Motoracer Caffe
    Espresso Cortado w Motoracer Caffe

[vrview img=”https://szymonmotyka.pl/wp-content/uploads/2016/09/360_0160_Stitch_XHC.jpg” ]

Podsumowanie

Jeśli się spodobał wpis, zapraszam na część drugą, która będzie na temat przyrządzania kawy w aeropressie. Za pomoc w artykule dziękuje Agnieszce, za korekcje językowe i dobre rady

 

Palava Trip + Gear 360

Hej, tym razem pragnę się podzielić relacją z trasy na czeskie Morawy. Wpis jednak będzie obciążony filmami i zdjęciami w 360 za pomocą Samsung Gear 360 lub z telefonu S7 Edge, bo nawet nie miałem czasu wyciągnąć aparatu, choć parę zdjęć zrobiłem. Dodatkowo trochę Żywca oraz bohaterskości i przygód dnia codziennego.

Zapraszam więc na relację z Palava Trip

Czytaj dalej „Palava Trip + Gear 360”

Bergamo

Wstęp

Hej, na starcie pragnę wspomnieć, ze teraz na blogu będę męczyć tymi  wielkimi i małymi tripami. Tak jest z Bergamo, małym miasteczkiem. Takim Modlinem dla Mediolanu, czy Oslo Rygge dla Oslo, z tą ogromną różnicą, że jeśli nie znajdziecie transportu do stolicy, to macie co w tym mieście robić, podziwiać a także spacerować. A jest gdzie 🙂

Do  Bergamo wybraliśmy się w 6 (o jedną osobę za dużo, by wypożyczyć środek transportu 😀 )

PREQUEL:

Warszawa.. Padbar… Pokemony   oraz nowy obiektyw, który dostarczył dużą część zdjęć do obecnego wpisu, aaa i Kac Bergamo. I wszystko byłoby spoko, gdyby nie fakt.. że nowy Warszawski Padbar stracił totalnie klimat… Ale Pokemony wciąż dobre!

Poke Elita w komplecie
Poke Elita w komplecie

Dzień 1.

To jest najważniejsze. Samo wyjście z lotniska, które otoczone było pasmem gór zrobiło ogromne wrażenie na wycieczkowiczkach.  Wiecie… wychodzicie z samolotu … a tu góry  i miasto na szczycie (o tym później). Z lotniska do miasta dostaliśmy się pieszo  z drobnymi przygodami… (tzn nikt z nas nie zauważył podziemnego tunelu dla pieszych, dopóki nie przeszliśmy na jego 2 stronę  przez drogę, rondo, drogę szybkiego ruchu  i poboczem).   Mały bonus .. w Bergamo naprawdę ciężko o sklepy spożywcze i zimną wodę w butelce. Dolna część miasta przypominała obrazki, zdjęcia czy jakiekolwiek sceny, w których widzimy Włoskie klimaty.

McDonald

Pierwsze kulturalne miejsce, które znaleźliśmy był.. McDonald, w którym   nie mieli mrożonej kawy, a panie przyjmujące zamówienia .. pojęcia o języku Angielskim.

McCafe w Bergamo
McCafe w Bergamo

Z ciekawych dodatków: McDonald w Bergamo zmienił Fast Food na Slow Food , a łazienki …  lepiej mieć kogoś, kto  wpisze kod do drzwi od zewnątrz, gdy będziemy chcieli się wydostać …

Wspinaczka

Jak wspominałem wcześniej, Bergamo nie jest samym lotniskiem, czy jak to niektórzy odkreślają „Bramą do Mediolanu”. Jest to połączenie 2 części :Starej (tej wyższej) oraz nowoczesnej dolnej. Z racji, że nasz meldunek był dopiero o 15, a do Bergamo dotarliśmy wcześnie rano, ruszyliśmy do tej górnej części (prawie jak Praga, tylko tutaj w włoskich klimatach). Schodki, strome ścieżki, oraz pierwsze, piękne widoki, które zaczynały się u podnóża:

DSC_2645

Na górę prowadziły co najmniej 2 drogi : Schody i kolejka 🙂

Ale już pierwszy checkpoint oczarował widokami:

It's K.. Bjutiful
It’s K.. Bjutiful

Miejsce, w którym widać było nowe miasto, pasma górskie, oraz ogromną motywację by wrócić tu po zmroku.  Miejsce też przerwy i próby zamówienia zimnej kawy  (cieszę się, że ten lód znalazł się jednak w kawie, przy tym poziomie języka angielskiego w Bergamo).   Wiecie, nie mówię dobrze po Angielsku,  ale tutaj to nawet z liczbami czy podstawowymi  łącznikami mają problem. Zamówienie 2 kaw po angielsku bywało zareagowane przez oczy jak 5 złotych).  W każdym razie.. Kawusia zacna, zwłaszcza przy tym upale i tych widokach. A co ważniejsze, to dopiero początek wspinaczki na  Stare Miasto i punkty widokowe.

Plus mały bonus z góry:

DSC_2819

 

Dzień 2.

Bardziej transportowy i poza miastowy był ów dzień.

Dotarcie na miejsce, względnie bliskiego miejsca, bo na 2 koniec jeziora wymagało od 2-3h   w zależności od środków transportu.  Bergamo->Sarnico->Iseo->Salzamo.  Linia E z Bergamo (3.7 Euro) Potem 5 euro (w 2 strony) oraz na końcu pociąg.

DSC_3092

Trochę żałowałem w tym dniu, że nie miałem żadnego środka transportu … jak motocykl 🙂 lub chociaż samochód . Jedyny minus  wycieczek powyżej 5 osób (zawsze mogliśmy tą 6 osobę wrzucić do bagażnika). Dodajmy do tego tłumy na kładce i wszelkich głównych ulicach Salzamo (swoją drogą miasteczko wygląda, jakby żyło dla siebie poza okresem, w którym jest kładka do miasta na wyspie pośrodku jeziora).

DSC_3195 (1)
Espresso z namiotu na upale z pięknym widokiem.. Warto było

DSC_3157 (1)

Upały, przeźroczyste jezioro  z górami w tle oraz dostęp do pizzy i past… mógłbym mieszkać w takich warunkach (nawet jakoś te upały bym wytrzymał).

No wiecie, moto, mała willa z basenem i winogronami (+ winnica)  na które chyba jestem uczulony 🙂  i praca zdalna. Blisko lotnisko do polski i jest raj.
Byle nie okres w którym jest kładka, kolejki .. nawet do pociągów 🙂

Wieczorem Włoska Restauracja (Swoją drogą, ciężko było znaleźć miejsce, zwłaszcza dla 6 osób nawet o 22 w środku tygodnia.  Troce żałuje ze nie spróbowałem jeszcze prawdziwie włoskiej Pasty, ale włoska Capriociosa różni się od tej, którą podają u nas w Polsce. chodzi o fakt, że nie jest oparta na szynce włoskiej.

Po kolacji zamiast wrócić do domu, wróciłem na nocne zdjęcia z długim czasie naświetlenia, do miejsca z 1 dnia, czyli do Starego Bergamo. Za obróbkę tych zdjęć, odpowiedzialna jest Asia Szymańska z  Mageek, która odprawiła paro klikową Magię w Lightroomie i ładne zdjęcia zrobiły się niesamowicie ładne, a magia Bergamo utrwalona równie pięknie, jak widok z góry na miasto:

BERGAMO 2016 DSC_3281 DSC_3280 DSC_3279 DSC_3270

Swoją drogą, na górze były koncerty, ale już nie pamiętam z jakiej okazji 🙂 w każdym razie podziękowania dla Barierokowiczów za udostępnienie kawałku muru dla mnie i mojego aparatu, po to, aby powyższe zdjęcia powstały 😉

3 Dzień był powrotem 🙂

Podsumowanie w punktach:

  1. Włosi, a przynajmniej Ci w Bergamo mieszkający Włosi, są tragiczni w Angielskim. Nawet zamówienie 2 kaw bez pokazania tego na palcach było zareagowane oczami jak 5 ojro.
  2. Są bardzo spokojnymi kierowcami… kiedy widzisz w Polsce Ferrari i inne sportowe pojazdy na światłach, to jest duża szansa, że ruszą chociaż z piskiem opon…tam nie 🙂 tak jakby wszyscy jeździli na Eco 🙂
  3. Jest sporo  jednośladów, a użytkownicy Moto Wrocław musieli by wrzucić zdjęcia 90% ludzi z komentarzami, jak oni są źle ubrani, że zdrapki itp 🙂
  4. Są  mili
  5. Mają świetną kawę,  do której tylko parę kawiarni w Polsce ma szansę się zbliżyć  jakością i sposobem tworzenia.
  6. Mają niesamowite piękne kobiety 🙂
  7. I piękne jeziora
  8. I gorszą komunikację niż w Polsce czasami 🙂
  9. Warto mieć gotówkę, nie zawsze znajdziecie bankomat i nie wszędzie zapłacicie kartą 😉

Bonus z Żywca:

Żeby nie było, że cudze chwalę,a swoim gardzę. To po powrocie z Bergamo  pojechałem do Żywca, gdzie zostałem „Porwany” na  Hale Lipowską 🙂

Bergamo 2016

Dzięki więc ekipie z Tweetup Geek na Italii. znaczy na wyjeździe oraz tej z Żywieckich Gór 🙂

I na  koniec galeria zdjęć, które się też w artykule nie pojawiły.

 

p.s Jakby ktoś chciał na moto tam jechać lub ponownie lecieć , to jestem chętny do towarzystwa 🙂