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


Stack technologiczny
Starałem się postawić na sprawdzone, nowoczesne technologie z ekosystemu .NET i cloud-native:
| Warstwa | Technologia |
|---|---|
| Backend | .NET 10 (C#), Clean Architecture, CQRS |
| Frontend | Vue.js 3 + Vite |
| Baza danych | PostgreSQL 16 + EF Core |
| Event Store | Marten (PostgreSQL-based) |
| Messaging | Kafka (Confluent Cloud na prod) |
| Async tasks | Hangfire |
| Storage | Azure Blob Storage + opcjonalnie Google Drive |
| Orchestration | Kubernetes (DOKS na prod, k3s na dev) |
| Auth | OpenIddict (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.


Środowisko developerskie — homelab
Projekt działa na trzech środowiskach:
| Środowisko | Hosting | Gateway |
|---|---|---|
| Local | Docker Compose | Localhost |
| Dev/Test | k3s (homelab) | Cloudflare Tunnel |
| Prod | DigitalOcean DOKS | DO 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.jsoni 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.

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.

Onboarding z rolami i zaproszeniami

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.






