🌾 AGRO 360 — Instrukcja: user flow SaaS

Żywy dokument projektowy. Kompleksowy flow przekształcenia obecnej aplikacji single-tenant w SaaS dla wielu gospodarstw.

Wersja: 2.0 Data: 2026-05-25 Status: ✅ Kompletny, do walidacji Przemka Autor: Adam + Claude · weryfikator: Przemek

0. Mapa całości, konwencje, glosariusz Meta

Sekcja zerowa dodana po audycie v1.1. Przeczytaj zanim wjedziesz w detale. Zawiera: jeden diagram pokazujący cały user flow end-to-end, podsumowanie audytu spójności (gdzie są luki do zaadresowania), konwencje czytania dokumentu i słownik terminów branżowych.

0.1 Mapa całego user flow — end-to-end

Pełna podróż klienta od pierwszego kontaktu (reklama) do retencji po latach. Każdy etap odsyła do dedykowanej sekcji. To jest kanoniczna sekwencja — wszystkie pozostałe diagramy w dokumencie są jej fragmentami.

flowchart TD
    subgraph ACQ["🎯 AKWIZYCJA — sekcja 2"]
      A1[Reklama / SEO /
polecenie] --> A2[Landing
agro360.pl] A2 --> A3{CTA
'Wypróbuj'?} end subgraph SIGN["✍️ REJESTRACJA — sekcja 3"] A3 -->|Tak| B1[Formularz
email + hasło] B1 --> B2[Weryfikacja
email] B2 --> B3[Auto-login
+ start trialu 30d] end subgraph ONB["🚀 ONBOARDING — sekcja 4"] B3 --> C1{Pierwsza wizyta?} C1 -->|Nowy user, brak
zaproszenia| C2[Wizard 5 kroków:
farma → pole → uprawa
→ zabieg → zaproszenie] C1 -->|Zaproszony user| C3[Mini-onboarding:
tutorial roli,
tour gospodarstwa] C2 --> C4[💡 AHA MOMENT
koszt/ha widoczny] C3 --> D1 C4 --> D1 end subgraph CORE["📦 CODZIENNE UŻYCIE — sekcja 5, 6, 11"] D1[Dashboard +
switcher gospodarstw] --> D2[Loop:
zabiegi · magazyn ·
faktury · koszty · raporty] D2 --> D3{Współpraca?} D3 -->|Tak| D4[Zaprasza
pracownika /
agronoma] D3 -->|Nie| D2 D4 --> D2 end subgraph CONV["💳 KONWERSJA — sekcja 8"] D2 -.->|dzień 23 trialu| E1[Banner '7 dni'] E1 --> E2[Wpięcie karty] E2 -->|dzień 30| E3{Auto-charge
OK?} E3 -->|Tak| F1[Klient płacący
Pro 49 zł/mies] E3 -->|Nie| E4[Dunning:
1d/3d/5d/7d retry] E4 -->|Sukces| F1 E4 -->|Fail 7d| E5[Read-only
mode] E5 -->|Wpięcie nowej karty| F1 E5 -.->|60d| E6[Konto
zawieszone] end subgraph RET["🔁 RETENCJA & EKSPANSJA — sekcja 6, 8"] F1 --> G1[Codzienne użycie] G1 --> G2{Sygnał
at-risk?} G2 -->|Nie| G1 G2 -->|Tak| G3[Health score
alert → success] G3 --> G1 G1 --> G4[Upsell:
roczny plan /
Enterprise] end subgraph EXIT["🚪 OFFBOARDING — sekcja 9, 11"] G1 -.->|user chce wyjść| H1[Anulowanie:
krótka ankieta,
działa do końca okresu] H1 --> H2[Dane zachowane
12 mies] H2 -.->|Reactivate| F1 H2 -.->|Eksport + usuń| H3[RODO export
+ hard delete] end A3 -->|Nie| Z1[Newsletter /
retargeting] Z1 -.-> A2 style A1 fill:#e8f0e0,stroke:#4a7c2c style C4 fill:#fff3d6,stroke:#c08a2a style F1 fill:#4a7c2c,stroke:#2d5016,color:#fff style E5 fill:#fff3d6,stroke:#c08a2a style E6 fill:#ffe9e9,stroke:#e88a8a style H3 fill:#ffe9e9,stroke:#e88a8a

Definicja „aha moment"

Aha moment = pierwszy zabieg wpisany w wizardzie onboardingowym, po którym system pokazuje wyliczony koszt zł/ha i potwierdza odjęcie z magazynu.

Mierzona metryka: time_to_aha = czas od kliknięcia „Załóż konto" do pierwszego workHistory.created z wyliczonym kosztem. Target: < 15 min. Jeśli > 30 min — alert do success, prawdopodobny churn w trialu.

0.2 Audyt spójności — co wymaga decyzji

Wynik przeglądu całego dokumentu pod kątem: spójność user flow, logiczne luki, sprzeczności między sekcjami, braki w obsłudze edge case'ów. Każdy punkt ma 📝 Audit notatkę inline w odpowiedniej sekcji. Wszystkie to decyzje do podjęcia przed implementacją.

✅ Wszystkie 19 problemów RESOLVED w v2.0

Każdy punkt rozstrzygnięty inline w odpowiedniej sekcji (oznaczenie „decyzja v2.0, audit #N RESOLVED"). Krótkie podsumowanie decyzji:

  1. ✅ s.1 — Liczby biznesowe dodane (s.1.6.1): LTV 1176 zł (Pro) / 3564 zł (Agronom), max CAC 392 / 1188 zł, payback 8 / 12 mies, break-even ~150 płatnych Pro.
  2. ✅ s.1 — Marta = płaci sama (Agronom Pro 99 zł/mies), osobny plan z dostępem do N farm. Klienci-rolnicy płacą Pro 49 zł osobno (s.1.6.2).
  3. ✅ s.2 — MVP online-only, hero zmieniony („w polu, na telefonie, prosto"). Offline-first przeniesiony do fazy 2 (Q4 2026), transparentnie w FAQ.
  4. ✅ s.3 — Flow wpięcia karty w 3 momentach: D+23 (proaktywny banner) / D+28-30 (eskalacja) / Zawsze (link w ustawieniach). Detal w s.3.6.
  5. ✅ s.3 — Trial = pełny Pro przez 30 dni Z JEDNYM ogranicznikiem: brak pakietu kontrolerskiego PDF. To killer feature → naturalny upgrade trigger gdy „za 3 dni kontrola ARiMR".
  6. ✅ s.4 — Dodany Wariant B onboardingu (3 ekrany dla zaproszonego usera) w s.4.10: powitanie spersonalizowane → tour roli → quick win.
  7. ✅ s.4 — Dodana sub-sekcja 4.11: post-onboarding journey, 9 zaprojektowanych touchpoints w 30 dni trialu z konkretnymi triggerami i treścią.
  8. ✅ s.5 — Sekcja przeformułowana na greenfield: tabela 5.1 = katalog modułów MVP, 5.4 (kopiujemy logikę), 5.5 (przeprojektowujemy UX), 5.6 (całkiem nowe), 5.7 (bugi do nie-powtórzenia).
  9. ✅ s.6 — Limity podzielone na 3 kategorie (s.6.5.1): Operatorzy (3 łącznie), Agronomi-goście (bez limitu, sami płacą), Księgowi (1 gratis). Czytelnie i fair.
  10. ✅ s.6 — Flow przekroczenia (s.6.5.2): soft block w UI z 3 opcjami (Upgrade / Usuń istniejącego / Anuluj). Backend 402.
  11. ✅ s.6 — Dashboard agronoma dodany jako pełna sub-sekcja 6.8: lista klientów, inbox rekomendacji, cross-farm raporty, masowy eksport pakietów kontrolerskich.
  12. ✅ s.7 — Decyzja: Subscription per Farm, Trial per User account przy pierwszej rejestracji (s.7.6.1). Drugie gospodarstwo = własna subskrypcja bez trialu.
  13. ✅ s.8 — Multi-farm billing logic w s.7.6.2: user z 2 gospodarstwami = 2 subskrypcje, ekran „Subskrypcje" jako lista, faktura per gospodarstwo z NIPem gospodarstwa.
  14. ✅ s.9 — Lock-in rozwiązany (s.9.6): ekran „Najpierw załatwmy gospodarstwa" z opcjami per gospodarstwo (Przekaż / Usuń też / Opuść). Zgodne z RODO Art. 17.
  15. ✅ s.11 — Spójność offline-first zsynchronizowana: s.1, s.2, s.11, s.12 mówią to samo (MVP online-only, faza 2 = offline-first PWA).
  16. ✅ s.12 — Faza 1 przeformułowana na greenfield: 27 zadań × 5-7 dni = 14-16 tyg dla solo, 8-10 tyg dla pary. Stack zmieniony na React+TS+Vite+Tailwind+shadcn.
  17. ✅ s.12 — Design system dodany do stacku (Tailwind + shadcn + Lucide + Inter + CSS tokens z palety prototypu).
  18. ✅ s.10 — Metryki kanału Agronom dodane do admin dashboardu (s.10.3.1): aktywni agronomi, MRR z Agronom Pro, klienci per agronom, churn diff, NPS, kupony.
  19. ✅ s.10 — Sub-sekcja 10.8 dodana: 3 środowiska (local dev / staging / production), test accounts na prod z flagą is_internal, smoke testy Playwright po deployu.

Status dokumentu: v2.0 — kompletny, gotowy do walidacji przez Przemka (rolnika-autora prototypu). Patrz sekcja 13.

0.3 Konwencje dokumentu — jak czytać

ElementZnaczenie
OKSekcja kompletna, do walidacji przez user research
WIPSekcja częściowa, w trakcie pisania
TODOPlaceholder, do wypełnienia
Spójność z apkąIstniejąca apka jako referencja domenowa pokrywa ten obszar — wiemy że logika działa
🐛 Bug / niespójnośćKonkretny problem do naprawy (najczęściej w istniejącej apce, jeśli będziemy z niej coś brać)
⚠️ Warn / decyzjaOtwarty problem prawno-techniczno-biznesowy, wymaga decyzji przed implementacją
💡 PomysłOpcjonalne usprawnienie, nie blokuje MVP. Backlog na fazę 2/3
📝 AuditRecenzja spójności dokumentu — luka w logice, sprzeczność, brak flow. Lista zbiorcza w 0.2
Tabela ze zieloną głowąStandardowa porównawcza / decyzyjna
Mermaid diagramFlow / sekwencja / ERD — renderowane przez CDN, wymaga internetu
kodNazwa funkcji / pola / endpointa
agro360-mvp2.html (l. XXXX)Referencja do istniejącej apki jako prototypu domenowego. Po decyzji „budujemy od nowa" — to inspiracja, nie code base do migracji.
Status istniejącej apki w kontekście dokumentu Apka agro360-mvp2.html jest prototypem domenowym — pokazuje że logika biznesowa rolnicza (mieszaniny ŚOR, koszty, magazyn, kalkulatory) została przemyślana i działa. Code SaaS piszemy od zera, ale UI/UX i decyzje branżowe z istniejącej apki to nasza biblioteka wiedzy. Każde odwołanie do numeru linii (l. XXXX) to pointer dla developera/projektanta: „idź zobacz jak to było zrobione, zachowaj logikę, napisz po nowemu".

0.4 Glosariusz terminów

Skróty branżowe (rolnictwo) i techniczne (SaaS) używane w dokumencie:

ARiMR
Agencja Restrukturyzacji i Modernizacji Rolnictwa — instytucja kontrolująca dopłaty UE, wymaga rejestru zabiegów ŚOR
PIORiN
Państwowa Inspekcja Ochrony Roślin i Nasiennictwa — kontroluje stosowanie ŚOR
ŚOR
Środki Ochrony Roślin — fungicydy, herbicydy, insektycydy
WG / SC / EC / SL
Formulacje ŚOR: WG (granulki wodne), SC (zawiesina koncentratowa), EC (koncentrat emulsyjny), SL (koncentrat do rozcieńczania). Determinują kolejność wlewania do opryskiwacza.
MTZ
Masa Tysiąca Ziaren — parametr nasion do obliczenia normy wysiewu
MATIF
Marché à Terme International de France — paryska giełda kontraktów terminowych na zboża, referencyjna cena dla PL
e-Wniosek
System ARiMR do składania wniosków o dopłaty — wymaga XML w określonym formacie
NPK
Azot-Fosfor-Potas — główne składniki nawozów, podawane jako % w formule (np. Polifoska 6-20-30)
MTH
Motogodziny — jednostka pracy maszyny (1h pracy ciągnika ≈ 0.8 MTH przy obciążeniu)
SaaS
Software as a Service — model dystrybucji oprogramowania jako subskrypcji
MRR / ARR
Monthly / Annual Recurring Revenue — kluczowe metryki SaaS
ARPU
Average Revenue Per User — przeciętny przychód na klienta
LTV / CAC
Lifetime Value / Customer Acquisition Cost — wartość klienta vs koszt jego pozyskania
NPS
Net Promoter Score — metryka lojalności klientów
Churn
Procent klientów anulujących subskrypcję w okresie
Dunning
Sekwencja prób ponownej płatności + emaili gdy płatność się nie udała
RBAC
Role-Based Access Control — uprawnienia oparte na rolach
RLS
Row Level Security — w PostgreSQL: polityki filtrujące wiersze per user
PWA
Progressive Web App — strona zachowuje się jak natywna apka (offline, install, push)
OCR
Optical Character Recognition — odczytywanie tekstu ze skanu (faktury)
RODO / GDPR
Rozporządzenie o Ochronie Danych Osobowych (PL) / General Data Protection Regulation (EU)
2FA / TOTP
Two-Factor Authentication / Time-based One-Time Password
Membership
W naszym modelu: relacja User ↔ Farm z konkretną rolą (np. „Marta jest agronomem w gospodarstwie Tomka")
Tenant
W SaaS: izolowana jednostka klienta. U nas Tenant = Farm (gospodarstwo)
Aha moment
Pierwsza chwila gdy user widzi konkretną wartość produktu — u nas: koszt zł/ha po wpisaniu pierwszego zabiegu (def. w 0.1)

0.5 Wymagania niefunkcjonalne (NFR)

Brakowało tego w v1.0 — dodaję zbiorczo dla wszystkich modułów:

WymaganieTargetPomiar
Time to First Byte (apka)< 800 ms p95Real User Monitoring
First Contentful Paint (landing)< 1.5 s na 4GLighthouse / WebPageTest
API response time (read)< 200 ms p95APM / Sentry Performance
API response time (write)< 500 ms p95APM
Uptime SLO99.5% (≈ 3.6h downtime/mies)UptimeRobot / Better Stack
Wsparcie przeglądarekChrome / Safari / Firefox / Edge — ostatnie 2 wersjeBrowserStack regress
Wsparcie mobileiOS 15+ / Android 10+ (≈ > 95% rynku PL)Analytics user agent
Dostępność (a11y)WCAG 2.1 AA — kontrast, klawiatura, screen readeraxe-core w CI
BezpieczeństwoOWASP Top 10 audited, HTTPS only, CSP headers, regularne pentesty EnterpriseOWASP ZAP, ręczne pentesty rocznie
RODOHosting EU, eksport < 24h, usunięcie < 30d, DPA dla wszystkich processorówAudit prawny rocznie
Backup / RPORPO 1h (max strata 1h danych) / RTO 4h (max czas przywracania)DR drill kwartalnie
JęzykMVP: tylko PL. Faza 3: EN, opcjonalnie UA (rolnicy ukraińscy w PL)
Lokalizacja danychDaty DD.MM.YYYY, waluta PLN, jednostki ha/kg/t/l (zgodnie z apką)
Sekcja 0 = źródło prawdy Wszystkie diagramy, definicje i konwencje z sekcji 0 mają pierwszeństwo przed treścią sekcji 1-12. Jeśli gdziekolwiek w dokumencie pojawi się sprzeczność z sekcją 0 — to znak że ta sekcja wymaga aktualizacji.

1. Persona i kontekst biznesowy Gotowe

Zanim zaprojektujemy jakikolwiek ekran SaaS, musimy mieć jasność: dla kogo to robimy, jaki problem rozwiązujemy i jak na tym zarabiamy. Ta sekcja jest fundamentem — wszystkie kolejne decyzje (cennik, onboarding, role, ficzery) będą się do niej odwoływać.

Status: to są tezy wstępne, nie kontrakt. Wymagają walidacji — najlepiej przez rozmowę z 5-10 realnymi rolnikami z grupy docelowej zanim zaczniemy budować.

1.1 Persona główna — „Rolnik-gospodarz"

Tomek, 42 lata

Właściciel gospodarstwa rodzinnego
Gospodarstwo
60-150 ha, uprawy polowe (zboża, rzepak, buraki, kukurydza)
Lokalizacja
Wielkopolska / Kujawy / Lubelskie — region intensywnego rolnictwa
Tech savvy
Smartfon (Android), Excel na poziomie podstawowym, korzysta z portali typu Agrofakt, Top Agrar
Sprzęt
Własny ciągnik + opryskiwacz, kombajn często wynajmowany lub w spółce sąsiedzkiej
Pracownicy
0-2 osoby na stałe + sezonowi na żniwa
Dochody
Główne źródło utrzymania rodziny, marże ciasne, każdy kosz zł/ha ma znaczenie
Pain points
Papierowy rejestr zabiegów ŚOR (wymóg prawny, kontrole ARiMR), brak realnej wiedzy ile kosztuje każdy hektar, niespójne dane w głowie / Excelu / notesie
Motywacja
Spokój podczas kontroli, lepsze decyzje zakupowe (kiedy kupić nawóz), świadomość kosztów per uprawa

1.2 Persona drugorzędna — „Agronom-doradca"

Marta, 35 lat

Agronom obsługujący 10-30 gospodarstw
Rola
Niezależny doradca lub pracownik firmy chemicznej / nasiennej
Pain points
Każdy klient ma dane w innym systemie / nie ma ich wcale, nie da się porównywać, dużo telefonów „a co dałeś na buraki w zeszłym roku?"
Wartość AGRO 360
Dostęp gościnny do gospodarstw klientów (z ich zgodą) — historia zabiegów, wnioski, rekomendacje w jednym miejscu
Implikacja
Potrzebujemy modelu user należy do wielu gospodarstw, nie odwrotnie

1.3 Persona trzecia (edge) — „Duży gracz"

Krzysztof, 55 lat — gospodarstwo 500+ ha

Zarządca / właściciel spółki rolnej
Charakterystyka
Kilku pracowników, własna księgowa, traktor z autopilota, może już używa konkurenta (np. SatAgro, FarmFacts, eDWIN)
Status
Nie naszą primary persona — mają większe budżety i wymagania (integracje, raporty na zewnątrz, multi-user z rolami). Możemy ich obsłużyć dopiero w wersji „Enterprise", nie w MVP SaaS.

1.4 Problem do rozwiązania

Dziś typowy rolnik z grupy docelowej radzi sobie z dokumentacją gospodarstwa w sposób fragmentaryczny:

ObszarJak jest dziśCo boli
Rejestr ŚORPapierowy zeszyt, czasem PDF do druku z portaluWpadki podczas kontroli ARiMR, kary 1-5 tys. zł
KosztyFaktury w segregatorze, „mniej więcej wiem"Brak wiedzy ile zł/ha realnie kosztuje pszenica vs buraki
Magazyn nawozów/ŚOR„Liczę co jest, jak wchodzę do magazynu"Zaskoczenie brakiem w szczycie sezonu, zakupy na ostatnią chwilę po wyższych cenach
Historia pólW głowie + zeszyt sąsiadaTrudno wrócić do „co siałem 3 lata temu na polu X"
Mieszaniny ŚORPamięć, telefon do agronomaNiepoprawna kolejność = zapchany opryskiwacz, strata środków

1.5 Value proposition

AGRO 360 to cyfrowy notatnik gospodarstwa, który prowadzi się sam. Wpisujesz raz pracę polową — system odlicza z magazynu, liczy koszt na hektar, dokleja do rejestru ŚOR i przygotowuje raport pod kontrolę. Bez Excela, bez papieru, bez „muszę to jeszcze ogarnąć wieczorem".

Trzy obietnice, które różnicują nas od konkurencji (eDWIN, SatAgro, FarmFacts):

  1. Prostota „chłopskiego rozumu" — nie ERP rolniczy, tylko jeden ekran = jedna decyzja. Onboarding w 5 minut.
  2. Polskie realia od pierwszego dnia — numery zezwoleń ARiMR, formulacje (WG/SC/EC/SL), zł/ha, dostawcy lokalni. Nie tłumaczenie z niemieckiego.
  3. Działa na telefonie w polu — szybki interfejs zoptymalizowany pod jedną rękę i słońce w oczy. Pełne offline-first dochodzi w fazie 2 (Q4 2026) — patrz s.12. Na MVP: online, ale błyskawiczne.

1.6 Model przychodów — teza wstępna

Trzy modele do rozważenia, z plusami i minusami:

ModelPrzykładPlusMinus
Flat per gospodarstwo 49 zł/mies za gospodarstwo, niezależnie od ha Prosty, przewidywalny, łatwo zakomunikować Małe i duże gospodarstwa płacą tyle samo — nie zarabiamy na dużych
Per hektar 2 zł/ha/mies (min 50 zł) Sprawiedliwy, skaluje się z wartością klienta Trudniejszy do komunikacji, klient kalkuluje przed użyciem
Tier-based (Free / Pro / Enterprise) Free do 5 pól / Pro 49 zł / Enterprise indywidualnie Klasyczny SaaS, low-friction onboarding (Free), upsell przez ograniczenia Więcej do utrzymania (3 wersje), trzeba zdecydować co dać za darmo
Decyzja v2.0: Tier-based z Free trial 30 dni → Pro 49 zł/mies za gospodarstwo (flat) → Agronom Pro 99 zł/mies (osobny plan dla doradców z N klientami) → Enterprise indywidualnie (gospodarstwa > 300 ha lub multi-farm). Trial = pełen Pro z jednym ogranicznikiem: brak generowania pakietu kontrolerskiego PDF (killer feature = upgrade trigger).

1.6.1 Liczby biznesowe — hipotezy do walidacji

Założenia finansowe na podstawie benchmarków SaaS B2B + specyfika rolnictwa (sezonowość, długie cykle decyzyjne):

MetrykaHipotezaWyliczenie
ARPU (Avg Revenue Per User)49 zł/mies dla Pro, 99 zł dla Agronom ProCena planu × dominujący plan
Średnia retencja24 miesiące (Pro), 36 mies (Agronom)Rolnictwo = mała mobilność, gdy raz wpisuje dane, nie chce migrować
LTV (Lifetime Value)1 176 zł (Pro), 3 564 zł (Agronom)ARPU × retencja w miesiącach
Max CAC (Customer Acquisition Cost)392 zł (Pro), 1 188 zł (Agronom)LTV / 3 — standard SaaS
Payback period8 mies (Pro), 12 mies (Agronom)Akceptowalne dla SaaS
Trial → paid conversion25-35%SaaS B2B benchmark z trialem bez karty: 20-40%
Monthly churn< 5%Niższy niż konsumencki SaaS (8-10%), wyższy niż enterprise (1-2%)
Break-even (gospodarstw)~150 płatnych ProPokrycie kosztów ~7350 zł MRR (Supabase + Stripe + emaile + domena + ZUS solo founder)

Co to oznacza: żeby AGRO 360 było opłacalne dla solo foundera (Adam) potrzebujemy 150 płatnych klientów w ~12 mies. Przy CAC 392 zł budżet marketingowy max ~60 000 zł na akwizycję pierwszych 150. To prawdopodobne przez polecenia + content SEO + 1-2 kampanie Facebook z targetowaniem rolniczym.

1.6.2 Status persony Marta (agronom) — decyzja

Marta to klient płacący, NIE darmowy kanał. Osobny plan Agronom Pro (99 zł/mies) z dostępem do N gospodarstw klientów (z ich zgodą per gospodarstwo). Marta nie konsumuje slotów w planach klientów-rolników. Klienci-rolnicy płacą za swoje Pro osobno. To dwa równoległe kanały przychodu.

Mechanika:

1.7 Ścieżka klienta — od poznania do retencji

flowchart LR
    A[Reklama FB / polecenie
sąsiada / Google] --> B[Landing page
agro360.pl] B --> C{Decyzja:
wypróbować?} C -->|Tak| D[Rejestracja
email + hasło] C -->|Nie| Z[Newsletter /
retargeting] D --> E[Onboarding wizard
dodaj 1. pole] E --> F[Pierwsza praca polowa
wpisana w 5 min] F --> G{Aha moment?
koszt/ha widoczny} G -->|Tak| H[Codzienne użycie
tydzień 1-4] G -->|Nie| Y[Churn w trialu] H --> I[Koniec trialu 30 dni] I --> J{Konwersja na
płatny plan?} J -->|Tak| K[Klient płacący
49 zł/mies] J -->|Nie| Y K --> L[Retencja
codzienne użycie] L --> M[Upsell:
zaproś agronoma /
dodaj pracownika] style A fill:#e8f0e0,stroke:#4a7c2c style K fill:#4a7c2c,stroke:#2d5016,color:#fff style Y fill:#fff3d6,stroke:#c08a2a style G fill:#fff3d6,stroke:#c08a2a
Audit #1 — brakuje liczb biznesowych Persony są opisane jakościowo, ale brak liczb krytycznych dla decyzji „budujemy": LTV (oczekiwana wartość klienta na całe życie — przy 49 zł/mies × 24 mies retencji = 1176 zł?), CAC (ile możemy wydać na pozyskanie — sensowne < LTV/3), Payback period (po ilu miesiącach klient się zwraca). Bez tych założeń model przychodów (1.6) to wishful thinking. Do uzupełnienia po pierwszych 5-10 rozmowach walidacyjnych.
Audit #2 — niejasny status persony Marta (agronom) W 1.2 Marta jest opisana jako persona drugorzędna, w 6.0 jako kanał afiliacji. Brak decyzji: czy Marta sama płaci za swoje konto SaaS, czy gospodarstwa-klienci płacą i Marta korzysta jako gość? To kluczowa decyzja dla modelu cenowego (s.8). Jeśli Marta nie płaci, jak rozliczamy jej slot „agronom" w limicie planu Pro? Jeśli płaci, jakim planem (osobny „Agronom 99 zł/mies" z dostępem do N gospodarstw)?

1.8 Otwarte pytania do walidacji

2. Akwizycja: landing page Gotowe

Landing page to jedna strona statyczna (osobny deployment, np. agro360.pl) — nie część aplikacji. Cel: w 10 sekund odpowiedzieć „dla kogo to jest" i przekonwertować na rejestrację. Optymalizowane pod mobile (rolnik na traktorze ze smartfonem).

2.1 Struktura strony — sekcje po kolei

1. Header (sticky)

Logo „AGRO 360" + linki: Funkcje · Cennik · Kontakt · Zaloguj się · [Wypróbuj za darmo] (zielony CTA)

2. Hero — pierwszy ekran

  • H1: „Twoje gospodarstwo. W jednym miejscu. Bez papieru."
  • Sub: „Rejestr ŚOR pod kontrolę ARiMR, koszty per hektar, magazyn zawsze aktualny. W telefonie, w polu, prosto."
  • CTA prim: [Wypróbuj 30 dni za darmo →] (bez karty kredytowej)
  • CTA sec: [Zobacz demo - 2 min]
  • Visual: Screenshot dashboardu owner / mockup telefonu w polu (autentyczny rolnik, nie stock photo)
  • Social proof bar: „Już 1247 gospodarstw korzysta" (kiedy będzie prawdą) / „Beta - dołącz pierwsi" (na starcie)

3. „Dla kogo to jest" (3 kafelki)

  1. 🚜 Rolnik 20-200 ha — głównie sam, czasem z pracownikiem. Chcesz ogarnąć ŚOR i koszty.
  2. 🌾 Gospodarstwo rodzinne — ojciec + syn, jeden komputer, jeden telefon, jedno źródło prawdy.
  3. 👩‍🌾 Agronom-doradca — obsługujesz kilku klientów, chcesz mieć dostęp do ich danych z ich zgodą.

4. „Co dostajesz" — 4 główne ficzery z ikonami

  • 📋 Rejestr ŚOR zgodny z ARiMR — numer zezwolenia, dawki, mieszaniny, jeden klik = PDF do kontroli
  • 💰 Koszty per hektar, per uprawa — wpisujesz raz, system liczy całość
  • 📦 Magazyn który sam się odlicza — wpisujesz zabieg → magazyn aktualny
  • 📊 Ceny nawozów lokalnych dostawców — wiesz gdzie kupić taniej

5. „Jak to działa" — 3 kroki + GIF/wideo

  1. Rejestrujesz konto (1 min)
  2. Dodajesz swoje pola — z mapy lub ręcznie (5 min)
  3. Wpisujesz pracę polową → reszta dzieje się sama

6. Społeczny dowód — opinie + logo

3-4 cytaty od pilotażowych rolników (z imieniem, regionem, liczbą ha, zdjęciem). Na starcie: „Pierwsi użytkownicy mówią:" Z czasem: logo izb rolniczych / organizacji branżowych.

7. Cennik (3 kolumny — szczegóły w sekcji 3)

  • Free trial 30 dni — pełna funkcjonalność, bez karty
  • Pro 49 zł/mies — jedno gospodarstwo, 3 użytkowników, wszystkie funkcje
  • Enterprise — wycena indywidualna — wiele gospodarstw, agronom z portfelem klientów

8. FAQ

  • Czy moje dane są bezpieczne? (RODO, gdzie hosting, eksport zawsze możliwy)
  • Co jeśli nie mam zasięgu w polu? (W MVP: wpisz po powrocie do zasięgu — apka pamięta draft. Pełne offline-first: Q4 2026, transparentnie na roadmapie.)
  • Czy działa na starym telefonie? (PWA, wszystko z 2018+)
  • Czy mogę zrezygnować? (tak, w każdej chwili, dane do eksportu)
  • Czy zastąpi mi system księgowy? (nie, ale eksport do księgowej tak)
  • Czy mogę przenieść dane z Excela? (tak, import CSV w wizardzie)

9. Final CTA + footer

Powtórzony hero CTA „Wypróbuj 30 dni za darmo". Footer: RODO, regulamin, kontakt, social media, blog (jeśli będzie).

2.2 User flow akwizycji

flowchart TD
    Start([Źródło ruchu]) --> Src{Skąd?}
    Src -->|Reklama FB/Google| LP[Landing
agro360.pl] Src -->|Polecenie sąsiada| LP Src -->|Branżowy portal| LP LP --> Read{Czyta hero?} Read -->|Bounce 70%| End1([Wyjście]) Read -->|Scroll dalej| Features[Sekcje
funkcje/jak działa] Features --> Price[Cennik] Price --> Decide{Decyzja} Decide -->|CTA Wypróbuj| Reg[Rejestracja
sekcja 3] Decide -->|Demo| Demo[Wideo 2min] Decide -->|FAQ| FAQ[Czyta FAQ] Demo --> Reg FAQ --> Decide Decide -->|Wyjście| Retarget[Pixel FB
retargeting] style LP fill:#e8f0e0,stroke:#4a7c2c style Reg fill:#4a7c2c,stroke:#2d5016,color:#fff style End1 fill:#fff3d6,stroke:#c08a2a

2.3 Wymagania techniczne landingu

Spójność z apką Landing jest osobny od apki — `agro360-mvp2.html` to produkt, landing to marketing. Nie ma kolizji. Jedyna nić: link „Zaloguj się" z headera landingu → ekran login w apce (do zbudowania w sekcji 3).
Audit #3 — sprzeczność „offline-first" w hero (s.2.2) vs scope MVP (s.11/s.12) Hero landingu obiecuje „w polu, bez zasięgu" (czyli offline). FAQ też: „działa offline, sync gdy wraca sieć". Ale s.11.2 odkłada offline-first na fazę 2, a s.12.5 explicite mówi „❌ Offline-first / PWA — zaczynamy online-only". To kłamstwo marketingowe — jeśli pierwszy klient z landingu kupi i odkryje że offline nie działa, refund + zła opinia. Decyzja do podjęcia: (a) dostarczyć offline w MVP (większy scope, opóźnia launch), (b) zmienić hero na „w polu, jednym kliknięciem" bez obietnicy offline, (c) dodać disclaimer „pełne offline w Q4 2026" — najgorsza opcja. Wybór musi być spójny w s.2, s.11 i s.12.
Pomysł — kalkulator ROI w landingu Interaktywny kalkulator: „Wpisz ile masz hektarów → pokażemy ile zaoszczędzisz na lepszej ewidencji ŚOR / dokładniejszym dozowaniu nawozów". Dane można oszacować z istniejących cen (1850 zł/t saletry, etc.). Mocny lead magnet — user widzi konkretną kwotę przed rejestracją.
Pomysł — blog/poradnik jako kanał SEO „Jak prowadzić rejestr ŚOR w 2026", „Ile kosztuje hektar pszenicy", „Najczęstsze błędy w mieszaninach ŚOR". Każdy poradnik z CTA „użyj AGRO 360 żeby to zrobić automatycznie". Długoterminowo najtańszy kanał akwizycji.

3. Rejestracja i wybór planu Gotowe

Cel rejestracji: najmniejszy możliwy próg wejścia. Im więcej pól w formularzu, tym większy drop-off. Decyzja o planie odkładamy na koniec trialu — user najpierw musi zobaczyć wartość.

3.1 Model rejestracji — decyzja: „trial-first, no card"

Trzy modele rozważane, wybieramy C:

ModelKiedy karta?Trade-off
A) Reverse trialKarta na starcie, brak opłat 30 dniWyższa konwersja po trialu, znacznie niższy sign-up rate
B) Free forever (limit)Nigdy obowiązkowoNajwięcej userów, najtrudniejszy upsell, kanibalizacja
C) Trial bez kartyPo 30 dniach, opcjonalna konwersjaBalans: low friction + wymuszony moment decyzji

3.2 Ekran rejestracji

Formularz — minimum pól

  • Email (z walidacją + sprawdzenie duplikatu)
  • Hasło (min 8 znaków, indykator siły)
  • Imię (do personalizacji emaili)
  • ☐ Akceptuję regulamin i RODO (wymagane)
  • ☐ Chcę dostawać newsletter (opcjonalne, domyślnie odznaczone)
  • [Załóż konto - 30 dni za darmo]

Alternatywnie u góry: [Kontynuuj z Google] (OAuth — 1 klik, znacznie wyższy conversion)

Pomysł — pole „nr telefonu" opcjonalne Dla persony „Tomek 42 lata, smartfon" sensowne. Wykorzystać do: powiadomień SMS o niskim magazynie, wsparcia (oddzwonimy), 2FA. Ale opcjonalnie — nie blokuje rejestracji.

3.3 Flow rejestracji

flowchart TD
    Start([CTA na landingu]) --> Form[Formularz
email + hasło + imię] Form --> Submit{Submit} Submit -->|Email zajęty| Err1[Komunikat:
masz już konto?
link do loginu] Submit -->|Walidacja OK| Send[Wyślij email
weryfikacyjny] Send --> Wait[Ekran:
sprawdź skrzynkę] Wait --> Click{User klika link?} Click -->|Tak, w 24h| Verify[Konto
aktywne] Click -->|Nie w 24h| Remind[Email przypominający
po 24h] Remind --> Click Click -->|Nigdy w 7 dni| Cleanup[Konto usuwane
email się zwalnia] Verify --> Login[Auto-login
+ start trialu 30 dni] Login --> Onboard[Onboarding wizard
sekcja 4] style Form fill:#e8f0e0,stroke:#4a7c2c style Onboard fill:#4a7c2c,stroke:#2d5016,color:#fff style Err1 fill:#ffe9e9,stroke:#e88a8a

3.4 Ekran weryfikacji email

Po submitcie rejestracji

  • Headline: „Sprawdź skrzynkę 📬"
  • „Wysłaliśmy link weryfikacyjny na tomek@gmail.com"
  • „Nie widzisz emaila? Sprawdź spam." [Wyślij ponownie] (rate-limit: 1x na 60s)
  • [Zmień adres email] (gdyby błąd)

3.5 Plany cenowe — finalna forma (v2.0)

Trial (30 dni)ProAgronom ProEnterprise
Cena0 zł49 zł/mies
(490 zł/rok = 2 mies gratis)
99 zł/mies
(990 zł/rok)
Wycena indywidualna
(typ. od 0.5 zł/ha/mies)
Dla kogoKażdy nowy rolnikRolnik 20-200 ha (Tomek)Doradca z portfolio klientów (Marta)Gospodarstwa > 300 ha lub multi-farm
Liczba gospodarstw1 (własne)1 (własne)1 własne + dostęp do N klientówBez limitu
Operatorzy (właściciel + współwł. + pracownicy)3 łącznie3 łącznie3 łącznie (we własnym)Bez limitu
Agronomi-gościeBez limitu (osobny licznik)Bez limituBez limitu
Księgowa (read-only finanse)1 gratis1 gratis1 gratisBez limitu
Pola, magazyny, kalkulatory, historiaBez limituBez limituBez limituBez limitu + integracje
Rejestr ŚOR (przeglądanie)
📋 Pakiet kontrolerski PDF (ARiMR-ready)upgrade trigger✅ + XML do e-Wniosku
Eksport danych JSON / Excel
Dostęp do bazy ŚOR 100+
WsparcieEmailEmail + chatEmail + chat + priorytetDedykowany opiekun
APIRead API klientówPełne API

Logika ogranicznika trialu (audit #4 RESOLVED): Trial daje pełnię użycia (smak prawdziwego produktu), ale brak pakietu kontrolerskiego PDF. To jedyny ograniczenie i jednocześnie killer feature — w momencie gdy Tomkowi „za 3 dni kontrola ARiMR", upgrade jest naturalny i emocjonalnie uzasadniony.

Audit #4 — paradox Trial vs Pro: identyczne limity Tabela 3.5 pokazuje że Trial i Pro mają te same limity (1 farm, 3 users, wszystko bez limitu). Różni je tylko cena (0 vs 49 zł). Konsekwencje: (a) user przez 30 dni dostaje pełny produkt za darmo i nie widzi dlaczego ma płacić, (b) nie ma jasnego „upgrade trigger" w trakcie trialu (np. „dodałeś 4. usera — upgrade!"), (c) trial nie udaje wersji „lite" — to po prostu Pro za 0 zł. Decyzje do podjęcia: ograniczyć trial (np. tylko 30 zabiegów, brak eksportu PDF, brak zaproszeń) ŻEBY była widoczna różnica → naturalny upgrade prompt. Alternatywa: pozostawić tak (bet na „smak pełnego produktu = chęć zapłaty"), ale wtedy nie liczyć na limity jako conversion lever.

3.6 Flow wpięcia karty — 3 momenty (decyzja v2.0, audit #5 RESOLVED)

Trial bez karty (3.1) wymaga jasnego flow KIEDY karta się pojawia. Decyzja: trzy okazje:

flowchart TD
    Trial1[Trial dzień 1-22] --> Day23{Dzień 23}
    Day23 --> Banner1[🟡 Banner non-blocking:
'Zostało 7 dni - wpij metodę
płatności żeby przejść płynnie.
Nic nie pobierzemy do dnia 30.'] Banner1 --> Choice1{User klika?} Choice1 -->|Tak, wpina| Stored1[💳 Karta zapisana,
banner znika,
dzień 30 auto-charge] Choice1 -->|Ignoruje| Day28[Dzień 28] Day28 --> Banner2[🟠 Banner mocniejszy:
'2 dni do końca trialu.
Bez karty stracisz możliwość
wpisywania.'] Banner2 --> Day30{Dzień 30} Day30 -->|Karta wpięta| Charge[Auto-charge 49 zł] Day30 -->|Karta nie wpięta| ReadOnly[🔴 Read-only mode
+ ekran konwersji 3.6.1] ReadOnly --> Settings[Opcja 3: link
'Ustawienia → Subskrypcja'
dostępny zawsze] Settings --> Choice1 Stored1 --> Day30 style Stored1 fill:#e8f0e0,stroke:#4a7c2c style ReadOnly fill:#fff3d6,stroke:#c08a2a style Charge fill:#4a7c2c,stroke:#2d5016,color:#fff

Trzy okazje, trzy poziomy presji:

  1. Dzień 23 (proaktywne) — łagodny banner, „uniknij przerwy". Nie blokuje pracy.
  2. Dzień 28-30 (eskalacja) — banner kontrastowy, email + push.
  3. Zawsze (samoobsługa) — link Ustawienia → Subskrypcja → Wpij kartę. Dla userów którzy chcą od pierwszego dnia.

Karta pobierana przez Stripe Customer Portal (hosted) — minimum integracji, max bezpieczeństwa. Wspierane metody: BLIK, karta, Apple/Google Pay (przez Stripe + Przelewy24).

3.6.1 Konwersja na płatny — ekran po trialu (dzień 30 bez karty)

Na dzień 30 bez wpiętej karty: read-only mode (user widzi dane, ale nie może dodawać) + ekran „Przedłuż żeby pisać".

Ekran konwersji

  • Headline: „Twój trial się skończył"
  • Podsumowanie: „W trakcie trialu dodałeś: 12 pól, 47 zabiegów, oszczędziłeś szacunkowo 1240 zł na lepszej ewidencji ŚOR"
  • [Wybierz Pro 49 zł/mies →] (główny CTA)
  • [Wybierz Pro rocznie 490 zł — 2 mies gratis] (drugi CTA)
  • [Eksportuj dane i wyjdź] (mały link, ale widoczny — RODO)
Audit #5 — KRYTYCZNA LUKA: kiedy user wpina kartę? Wybraliśmy model „trial bez karty" (3.1). OK. Ale w s.8 wszystkie scenariusze dunning zakładają WPIĘTĄ kartę („Karta wygasła", „BLIK nieudany"). Brakuje flow wpięcia karty. Możliwe miejsca:
  • Dzień 23 trialu (7 przed końcem): banner „Żeby uniknąć przerwy w pracy, wpij metodę płatności już teraz". Push, nie przymus.
  • Dzień 30 trialu: ekran konwersji 3.6 — tu pierwszy obowiązkowy moment.
  • W trakcie trialu na życzenie: link w ustawieniach „Wpij kartę żeby trial przeszedł płynnie w Pro".
Decyzja: która kombinacja? Sugestia: wszystkie trzy + jasna kontrola „w każdej chwili możesz odpiąć i wyłączymy auto-charge". Bez tego flow ekran konwersji (3.6) i dunning (s.8) wiszą w powietrzu.

3.7 Login (dla wracających)

Ekran logowania

  • Email + hasło + [Zaloguj]
  • [Kontynuuj z Google] (jeśli zarejestrowany przez Google)
  • [Nie pamiętasz hasła?] → flow reset (sekcja 11)
  • [Nie masz konta? Zarejestruj się]
  • ☐ Zapamiętaj mnie (token 30 dni, tylko własne urządzenie)
Niespójność z apką — splash i wybór roli Obecnie apka startuje od splash (l. 1033) → moduleSelectfarmRoleSelect (owner/worker). W SaaS to znika — po loginie user trafia od razu do swojego gospodarstwa, a rola wynika z jego konta (nie z wyboru per session). Trzeba refaktorować boot flow apki: usunąć selectRole() (l. 3520), zastąpić sprawdzeniem currentUser.role z backendu.
Pomysł — magic link zamiast hasła Dla persony Tomek (42, smartfon, hasła pamięta źle) — alternatywą jest passwordless: wpisuje email → przychodzi link → klika → zalogowany. Mniej kłopotów z hasłami, mniej resetów. Wymaga niezawodnego dostarczania emaili (transactional mailer).
Decyzja do podjęcia — co z Apple Sign-In? Jeśli kiedyś będzie aplikacja iOS w App Store, Apple wymaga dodania „Sign in with Apple" obok Google. Na webie nie obowiązkowe. Wstępnie odkładamy do mobilnej wersji.

4. Onboarding: pierwsze gospodarstwo Gotowe

To najważniejszy ekran całego SaaS. Tu się decyduje czy user zostanie. Cel: w <10 min user widzi pierwszą wartość („aha moment") — koszt na hektar swojego pola po wpisaniu jednego zabiegu.

4.1 Filozofia onboardingu

4.2 Flow wizarda — 5 kroków

flowchart LR
    Login([Po loginie]) --> S1[Krok 1
Nazwa gospodarstwa
+ lokalizacja] S1 --> S2[Krok 2
Dodaj 1. pole] S2 --> S3[Krok 3
Przypisz uprawę] S3 --> S4[Krok 4
Wpisz 1. zabieg
opcjonalne] S4 --> S5[Krok 5
Zaproś osobę
opcjonalne] S5 --> Done[Dashboard
z banerem 'aha'] S1 -.skip.-> S2 S2 -.skip.-> S3 S3 -.skip.-> Done S4 -.skip.-> S5 style Done fill:#4a7c2c,stroke:#2d5016,color:#fff style S2 fill:#e8f0e0,stroke:#4a7c2c style S4 fill:#fff3d6,stroke:#c08a2a

4.3 Krok 1 — Nazwa gospodarstwa + lokalizacja

„Witaj! Jak nazywa się Twoje gospodarstwo?"

  • Nazwa — input, np. „Gospodarstwo Kowalskich" / „Tomek Pole" (cokolwiek user lubi)
  • Region — dropdown: Wielkopolska, Kujawy-Pomorze, Mazowsze, Lubelskie, Małopolska, Śląsk, Dolny Śląsk, Lubuskie, Podkarpacie, Świętokrzyskie, Łódzkie, Opolskie, Warmia-Mazury, Pomorskie, Podlaskie, Zachodniopomorskie (pełna lista województw)
  • Powierzchnia łączna (opcjonalne) — slider 1-1000 ha, wpływa na rekomendacje („typowo dla 60 ha:")
  • [Dalej →] / [Pomiń]

4.4 Krok 2 — Dodaj pierwsze pole

„Dodaj swoje pierwsze pole — 3 sposoby"

  1. 📍 Z mapy — klikaj kontur pola na mapie satelitarnej (długoterminowo: integracja z ARiMR / OSM)
  2. 📋 Numer działki — wpisz nr ewidencyjny, system pobiera powierzchnię i lokalizację (wymaga API rejestru gruntów)
  3. ✏️ Ręcznie — nazwa pola, powierzchnia w ha, lokalizacja słowna („za starym domem")

Pole minimum: nazwa + powierzchnia. Reszta opcjonalna.

Decyzja techniczna — który backend mapowy? Trzy opcje: (a) tylko ręczne wprowadzanie (najtaniej, gorszy UX), (b) OpenStreetMap + Leaflet (darmowe, ale brak działek ARiMR), (c) integracja z portalem ARiMR / GeoPortal (najlepszy UX, ale API może być płatne/trudne). Na MVP: (a)+(b), na Pro: (c). Patrz sekcja 12.

4.5 Krok 3 — Przypisz uprawę

„Co rośnie / będzie rosło na polu ‚Pole za starym domem'?"

  • Dropdown z popularnymi: Pszenica ozima, Pszenica jara, Jęczmień ozimy, Jęczmień jary, Żyto, Owies, Rzepak, Kukurydza, Buraki cukrowe, Ziemniaki, Łubin, Bobik, Soja, Łąka/pastwisko, Inne (wpisz)
  • Rok zbiorów: 2026 / 2025 / planowane 2027
  • [Dodaj kolejne pole] / [Skończ z polami →]

Pełna lista upraw oparta na obecnej liście w apce — patrz renderFieldForm().

4.6 Krok 4 — Pierwszy zabieg (opcjonalny)

„Chcesz wpisać ostatni zabieg, który robiłeś?" (sugerowane, ale skip-able)

Uproszczony formularz na bazie istniejącego renderWorkForm('protection') z apki. Tylko podstawy:

  • Co robiłeś? (siew / nawożenie / ochrona / inne)
  • Kiedy? (data)
  • Na którym polu? (z dodanych w kroku 2)
  • Jeśli ochrona/nawożenie: który produkt, jaka dawka (dropdown z magazynem demo + opcja „dodaj nowy")
  • [Zapisz i pokaż mi koszt!]

Po zapisaniu → AHA MOMENT:

✅ Zabieg zapisany. Koszt tej operacji: 234,50 zł (18,76 zł/ha). Tak liczone będą wszystkie kolejne. Magazyn aktualny.

4.7 Krok 5 — Zaproś osobę (opcjonalny)

„Współpracujesz z kimś?"

  • Pole email + dropdown rola: Pracownik / Agronom / Współwłaściciel
  • [Wyślij zaproszenie] / [Pomiń, zrobię później]

Szczegóły ról: sekcja 6.

4.8 Lądowanie — pierwszy dashboard

Dashboard z banerem „Co dalej?"

  • Baner u góry: „🎉 Świetnie! Twoje gospodarstwo gotowe. Następne kroki:" — lista checklist: ☐ Dodaj kolejne pola, ☐ Uzupełnij magazyn ŚOR, ☐ Skonfiguruj alerty, ☐ Zaproś pracownika
  • Reszta dashboardu = standardowy ownerDashboard z apki
Audit #6 — BRAK FLOW: pierwsze logowanie zaproszonego usera Cała sekcja 4 opisuje wizard dla foundera (zakłada własną farmę). A co widzi user którego Tomek zaprosił jako pracownika? Klika link w mailu (s.6.3), zakłada konto, loguje się — i co dalej? Nie ma własnej farmy do skonfigurowania. Nie ma kontekstu jak działa apka. Brakuje wariantu B onboardingu:
  • Powitanie spersonalizowane: „Tomek zaprosił Cię do gospodarstwa X jako pracownika"
  • Mini-tour: pokazanie tylko tych ekranów do których ma uprawnienia (matrix z s.6.6)
  • Quick win zamiast „aha moment" foundera: np. „wpisz swój pierwszy zabieg w gospodarstwie Tomka — pokażemy jak"
  • Później: opcja „chcę założyć też własne gospodarstwo" (przejście do wizarda foundera)
Bez tego zaproszony user dostaje pustkę i się wyloguje. Diagram w 0.1 już to uwzględnia (gałąź „Zaproszony user").
Audit #7 — BRAK: post-onboarding journey (dni 1-30 trialu) Wizard kończy się dashboardem z banerem „co dalej?". OK. Ale potem cisza. Co się dzieje przez 30 dni trialu? Trzeba zaprojektować edukacyjną sekwencję retencji:
  • Dzień 1 wieczór: email „Witaj w AGRO 360 — zacznij od tych 3 rzeczy"
  • Dzień 3: jeśli 0 dodatkowych zabiegów po wizardzie — push „Wpisanie zabiegu zajmuje 30 sek, pokazujemy jak"
  • Dzień 7: email „Twój pierwszy tydzień — podsumowanie i 3 funkcje których nie odkryłeś"
  • Dzień 14: email „Dodaj pracownika / agronoma — pełnia wartości"
  • Dzień 23: banner i email „Zostało 7 dni trialu — wpij kartę" (patrz audit #5)
  • Dzień 28: banner „2 dni do końca"
  • Dzień 30: ekran konwersji (3.6)
Każdy touch z konkretnym celem: edukacja → użycie → konwersja. Bez tej sekwencji 70% userów zniknie w pierwszym tygodniu bez powodu (industry standard).

4.9 Onboarding checklisty (post-wizard)

Po wizardzie checklisty się utrzymują w widgetcie na dashboardzie (collapsable), znikają gdy user wykona zadanie. Zniknięcie wszystkich = end-of-onboarding event w analytics.

4.10 Wariant B onboardingu — zaproszony user (decyzja v2.0, audit #6 RESOLVED)

Sekcje 4.2-4.9 opisują onboarding foundera (zakłada własną farmę). Drugi scenariusz: user dostał zaproszenie (s.6.3) — np. Tomek zaprosił Marka jako pracownika lub Marta zaprosiła swojego klienta. Nie pokazujemy wizarda farmy (nie ma własnej), zamiast tego dedykowany mini-onboarding 3 ekrany.

flowchart LR
    Email([Klik w zaproszeniu]) --> Reg[Skrócona rejestracja:
imię + hasło
email pre-filled] Reg --> S1[Krok 1
Powitanie spersonalizowane:
'Tomek zaprosił Cię do
Gospodarstwa Kowalskich
jako Pracownika'] S1 --> S2[Krok 2
Mini-tour roli:
'Jako Pracownik możesz:
✅ Wpisywać zabiegi
✅ Sprawdzać magazyn
❌ Nie zobaczysz Faktur'] S2 --> S3[Krok 3
Quick win:
'Spróbuj wpisać
zabieg testowy.
Tomek zobaczy notyfikację.'] S3 --> Dash[Dashboard
workerDashboard] style S2 fill:#e8f0e0,stroke:#4a7c2c style Dash fill:#4a7c2c,stroke:#2d5016,color:#fff

Krok 1 — Powitanie spersonalizowane

  • Headline: „Cześć, [Marek]! 👋"
  • „[Tomek Kowalski] zaprosił Cię do Gospodarstwa Kowalskich jako Pracownika."
  • Krótko o gospodarstwie: „60 ha, woj. wielkopolskie, 4 pola, uprawy: pszenica, rzepak, kukurydza"
  • [Akceptuję dostęp →] / [Odrzuć zaproszenie]

Krok 2 — Mini-tour roli

  • Headline: „Co możesz robić jako Pracownik"
  • Zielona lista: konkretne uprawnienia (z matrix s.6.6) — Wpisywać zabiegi · Sprawdzać magazyn · Generować raporty operacyjne · Dodawać rekomendacje
  • Szara lista: czego nie zobaczysz — Faktur · Kosztów · Billingu
  • „Tomek zachowuje pełną kontrolę nad gospodarstwem"
  • [Rozumiem, dalej →]

Krok 3 — Quick win

  • „Spróbuj wpisać jeden zabieg testowy — to zajmie 30 sekund"
  • Mini-formularz: data (dziś auto) + pole z dropdown gospodarstwa + typ (np. „kontrola") + krótka notatka
  • [Zapisz testowy zabieg]
  • Po zapisie: „🎉 Świetnie! Tomek dostał notyfikację. Tak będzie wyglądać Twoja codzienna praca."
  • [Wejdź do dashboardu →]

Po Wariancie B: user trafia do swojego workerDashboard (lub odpowiedniego dla roli — agronomDashboard / accountantDashboard). Onboarding checklisty z 4.9 też się pojawiają, ale w skróconej wersji (np. tylko „Zaktualizuj swój profil" + „Wpisz pierwszy realny zabieg").

Edge case: user zaakceptował zaproszenie do gospodarstwa Tomka, ale chce też założyć własne. Z dashboardu → switcher gospodarstw (s.6.4) → [+ Załóż własne gospodarstwo] → przechodzi do Wariantu A (wizard foundera 4.2-4.9).

4.11 Post-onboarding journey — sekwencja 30 dni trialu (decyzja v2.0, audit #7 RESOLVED)

Wizard kończy „aha momentem". Dalej zaczyna się zaprojektowana sekwencja retencji — 7 zaplanowanych touchpoints w 30 dni trialu, każdy z konkretnym celem: edukacja → użycie → konwersja.

DzieńKanałTriggerTreść / Cel
D+0 wieczórEmailPo wizardzie„Witaj w AGRO 360. Zacznij od tych 3 rzeczy" — 3 najprostsze quick wins (uzupełnij magazyn ŚOR z bazy / dodaj kolejne pole / wypróbuj kalkulator MTZ)
D+3Email + PushJeśli 0 nowych zabiegów po wizardzie„Wpisanie zabiegu zajmuje 30 sekund — pokazujemy jak" + 60-sek wideo (lub GIF)
D+7EmailZawsze„Twój pierwszy tydzień w AGRO 360 — podsumowanie i 3 funkcje których nie odkryłeś". Personalizowane wg aktywności (np. „dodałeś 5 zabiegów, zobacz Analizę kosztów").
D+14Email + In-app bannerZawsze„Pełnia wartości = współpraca. Zaproś syna / pracownika / agronoma" — link bezpośrednio do flow zaproszeń (s.6.3)
D+21EmailJeśli niski engagement (< 3 zabiegów łącznie)Wysyłany ręcznie przez success (lub auto): „Cześć Tomek, widzimy że może coś nie działa — zadzwońmy 15 min?" + Calendly link
D+23Email + BannerZawsze„Zostało 7 dni trialu — wpij metodę płatności żeby przejść płynnie" (patrz s.3.6 — pierwsze okno karty)
D+28Email + Banner + PushJeśli karta nie wpięta„2 dni do końca trialu. Bez wpięcia karty stracisz możliwość wpisywania zabiegów" — pierwsze straszenie utratą
D+30Email + Ekran konwersjiZawszeEkran 3.6.1 — „Twój trial się skończył" + podsumowanie wartości („wpisałeś 47 zabiegów, oszacowane oszczędności 1240 zł")
D+33EmailJeśli nie skonwertowałLast call: „Tęsknimy. 50% rabatu na pierwszy miesiąc jeśli wrócisz w 7 dni" — kupon Stripe

Metryki sukcesu sekwencji:

Wszystkie touchpoints konfigurowalne w admin panelu (s.10) jako szablony email/push z możliwością A/B testów.

Spójność z apką — co już istnieje Apka ma już:
  • saveSettingsFarm() (l. 6412) — zapis nazwy gospodarstwa, regionu, telefonu → użyjemy w kroku 1
  • showFieldForm() / saveField() (l. 5728/5805) → wykorzystamy w kroku 2 (uproszczony)
  • renderWorkForm('protection') (l. 8086) → w kroku 4, ale w drastycznie skróconej wersji
  • sorDatabase (l. 7338) — 12 preparatów seed → dostępne od razu po onboardingu
Większość kroków to fasada nad istniejącymi funkcjami — nie trzeba budować formularzy od zera.
Bug do naprawy — fieldWorkHistory nie persystuje Obecnie fieldWorkHistory (l. 7864) to zmienna globalna w pamięci — po reload znika. W SaaS to krytyczne — pierwszy zabieg w onboardingu MUSI przeżyć reload. Wymaga: (a) doraźnie zapis w localStorage przed migracją, (b) docelowo POST do backendu. To samo z invoicesRegister i costsRegister.
Pomysł — import z Excela w wizardzie Krok 2.5 (opcjonalny): „Masz pola w Excelu? Wgraj plik, dopasujemy kolumny." Akceptujemy CSV/XLSX z kolumnami: nazwa, ha, uprawa, lokalizacja. Drag-and-drop. Skraca onboarding dużego gospodarstwa z 30 min do 2 min.
Pomysł — onboarding video pop-up Po pierwszym loginie 60-sekundowy filmik tłumaczący „co tu zrobisz w 5 minut". Nagrany przez prawdziwego rolnika (autentyczność > produkcja). Zamykalny i nie wraca.

5. Core usage — katalog modułów MVP (greenfield) Gotowe v2.0

Po decyzji Adama: budujemy od nowa. Prototyp Przemka (agro360-mvp2.html, ~9700 linii vanilla JS) jest biblioteką wiedzy domenowej — dowodzi że logika biznesowa rolnicza (mieszaniny ŚOR, koszty zł/ha, magazyn auto-odliczanie, kalkulatory MTZ) jest przemyślana i działa. SaaS buduje się od zera w nowoczesnym stacku (s.12), z prototypu kopiujemy logikę i decyzje branżowe, nie kod.

Audit #8 RESOLVED — filozofia greenfield z referencją domenową Wszystkie odwołania (l. XXXX) w tej sekcji = pointery dla developera/projektanta: „idź zobacz w prototypie jak Przemek to rozwiązał, zachowaj decyzję merytoryczną, napisz po nowemu w React + TS". Prototyp NIE jest code base do migracji — jest dokumentacją wykonalną.

5.1 Katalog modułów MVP — referencja domenowa → backlog do zbudowania

Moduł w prototypie (linia)Rola w SaaSDecyzja MVP
splash (l. 1033)Loading screen — może zostać jako fallback ładowania danych z backendu✅ zachowujemy
moduleSelect (l. 1129)Niepotrzebny — w SaaS user trafia od razu do gospodarstwa❌ usuwamy
farmRoleSelectNiepotrzebny — rola wynika z kont użytkownika (sekcja 6)❌ usuwamy
ownerDashboard (l. 1129)Główny ekran dla roli „właściciel"✏️ refaktor (dane z backendu, nie hardcoded)
workerDashboard (l. 1404)Główny ekran dla roli „pracownik" — uproszczony widok✏️ refaktor
ownerProfilePanel (l. 1701)Profil gospodarstwa (nie usera) — sekcja 9 to user profile✏️ rozdzielić user/farm
fieldWorkPanel (l. 2519)CORE — prace polowe, najczęściej używany ekran✅ zachowujemy + bug fix (persystencja)
warehousePanel (l. 2596)CORE — magazyny zboża/ŚOR/nasion✅ zachowujemy
invoicesPanel (l. 2627)Faktury zakupu/sprzedaży✅ + bug fix (persystencja)
fieldMapPanel (l. 2655)Mapa i lista pól✏️ realne GPS zamiast mock
settingsPanel (l. 2744)Ustawienia gospodarstwa — patrz też sekcja 9 (user)✏️ rozdzielić
reportsPanel (l. 2990)Raporty PDF — ARiMR, koszty, zabiegi✏️ server-side PDF zamiast print
costsPanel (l. 3121)Analiza kosztów per uprawa/pole✅ + bug fix
paymentsPanel (l. 2501)Historia płatności gospodarstwa (wydatki) — NIE billing SaaS✅ zachowujemy (zmienić nazwę żeby nie myliło z billing — patrz s.8)
fertilizerPricesPanelCeny nawozów dostawców✏️ realne ceny zamiast hardcoded
historyPanelHistoria zabiegów✅ zachowujemy
labelSearchPanelWyszukiwanie ŚOR po etykietach✏️ rozbudować sorDatabase (12 → 100+)
calculatorPanelKalkulatory siewu/gęstości/inwestycji✅ zachowujemy
hireServicePanelZlecenie usługi (kombajn, opryskiwacz)✅ zachowujemy

5.2 Typowe ścieżki użytkownika w SaaS

flowchart TD
    Login([Login]) --> Dash[ownerDashboard]
    Dash --> P1{Co chcę zrobić?}

    P1 -->|Wpisać zabieg| FW[fieldWorkPanel]
    FW --> Type[Wybór typu:
uprawa/siew/nawóz/
ochrona/żniwa] Type --> Form[renderWorkForm] Form --> Save[saveFieldWork] Save --> Wh[Odejmij z magazynu
+ koszty] Wh --> Dash P1 -->|Sprawdzić magazyn| Mag[warehousePanel] Mag --> Sub[Sub-screen:
zboże/ŚOR/nasiona] Sub --> Dash P1 -->|Dodać fakturę| Inv[invoicesPanel] Inv --> InvSave[saveInvoice] InvSave --> CostUpd[Update costsRegister] CostUpd --> Dash P1 -->|Wygenerować raport ARiMR| Rep[reportsPanel] Rep --> PDF[Server PDF] PDF --> Download[Pobierz] P1 -->|Sprawdzić koszty| Costs[costsPanel] Costs --> Filter[Filtr: uprawa/pole/data] Filter --> Dash style Dash fill:#4a7c2c,stroke:#2d5016,color:#fff style Save fill:#e8f0e0,stroke:#4a7c2c style PDF fill:#fff3d6,stroke:#c08a2a

5.3 Najczęstszy flow — wpisanie zabiegu ochrony roślin

To 60% wartości produktu. Krok po kroku jak działa w apce dziś — i co zmieni SaaS:

Dziś (single-user, localStorage)

  1. Dashboard → kafelek „Prace polowe" → wybór „Ochrona roślin" → renderWorkForm('protection')
  2. Wybór pól (checkbox), data, godziny
  3. Uprawa pryskania (dropdown z upraw na wybranych polach)
  4. Mieszanina: addToMixture() dodaje preparaty z chemWarehouse, dla każdego dawka + nr zezwolenia
  5. renderMixtureOrder() sortuje kolejność wg formulacji (WG → SC → EC → SL)
  6. saveFieldWork(): zapis do fieldWorkHistory (in-memory!), odejmuje z magazynu, dolicza koszt

W SaaS — co się zmienia

  1. UI ten sam (nie psujemy tego co działa)
  2. Lista pól pochodzi z GET /api/farms/:farmId/fields zamiast localStorage.farmFields
  3. Lista preparatów w chemWarehouse dzielona z global sorDatabase (rozszerzonym do 100+) + custom usera
  4. saveFieldWork()POST /api/farms/:farmId/work-history, z optimistic update (offline → kolejka sync)
  5. Powiadomienie reaktywne: jeśli inny user w gospodarstwie też patrzy na ten ekran, widzi zmianę magazynu w czasie rzeczywistym (WebSocket / SSE)
  6. Walidacja anty-konflikt: jeśli dwóch users równolegle wpisuje ten sam zabieg na tym samym polu — alert

5.4 Co kopiujemy 1:1 z prototypu (logika domenowa, nie kod)

Przemek już to przemyślał i działa — w nowym buildzie zachowujemy identyczne reguły biznesowe, ale piszemy w React + TypeScript:

5.5 Co przeprojektujemy (UX/UI od nowa)

Prototyp ma znaną logikę, ale wygląd i interakcje wymagają unowocześnienia:

5.6 Co całkiem nowe (nie istnieje w prototypie)

Wszystko związane z SaaS jako modelem biznesowym:

5.7 Bugi w prototypie do nie-powtórzenia w SaaS

Trzeba świadomie nie kopiować:

Lessons learned z prototypu — nieoceniona wartość Prototyp Przemka to najlepsza możliwa specyfikacja domenowa jaką można było mieć. Decyzje agronomiczne (kolejność WG/SC/EC/SL, kalkulator MTZ, formulacje), polskie realia (numery R-XXXX/RRRR, ARiMR, województwa, dostawcy nawozów), workflow dnia codziennego rolnika — wszystko to zostało już przetestowane na żywym organizmie. Bez tego buildowalibyśmy na ślepo.

6. Współpraca i role Gotowe

Apka dziś ma proste rozróżnienie owner / worker (zmienna currentRole, l. 3464). To za mało dla SaaS. Persona „Marta-agronom" obsługuje wiele gospodarstw — potrzebujemy modelu user należy do wielu gospodarstw przez różne role.

6.1 Cztery role w gospodarstwie

RolaKto toMożeNie może
Właściciel 👑 Zakładający konto / przekazane uprawnienia Wszystko: dodawać/usuwać użytkowników, zmieniać plan, zarządzać billingiem, usunąć gospodarstwo
Współwłaściciel 🤝 Małżonek, brat, wspólnik Wszystko poza usuwaniem gospodarstwa i odbieraniem ról innym właścicielom Usunąć gospodarstwo, usunąć innego właściciela
Pracownik 👷 Operator ciągnika, syn na żniwa Wpisywać zabiegi, sprawdzać magazyn, widzieć swoje pola, generować raporty operacyjne Widzieć faktury / koszty / billing, zarządzać użytkownikami, edytować ustawienia gospodarstwa
Agronom (gość) 👩‍🌾 Doradca z zewnątrz (Marta) Czytać wszystko, dodawać rekomendacje (notki), eksportować raporty. Może być w wielu gospodarstwach. Edytować zabiegi, zmieniać magazyn, widzieć billing

6.2 Model danych — User ↔ Membership ↔ Farm

erDiagram
    User ||--o{ Membership : "ma"
    Farm ||--o{ Membership : "ma"
    Membership }o--|| Role : "jest"

    User {
        uuid id PK
        string email UK
        string name
        string phone
        timestamp createdAt
    }
    Farm {
        uuid id PK
        string name
        string region
        timestamp createdAt
        string subscriptionStatus
    }
    Membership {
        uuid id PK
        uuid userId FK
        uuid farmId FK
        enum role
        timestamp joinedAt
        timestamp invitedAt
        string status
    }
    Role {
        enum value
    }
    

Kluczowe: User i Farm to relacja many-to-many przez Membership. Jeden user może być właścicielem jednego gospodarstwa i agronomem w 5 innych. Jedno gospodarstwo ma wielu users.

6.3 Flow zaproszenia użytkownika

flowchart TD
    Owner([Właściciel]) --> Settings[Ustawienia →
Użytkownicy] Settings --> Add[+ Zaproś osobę] Add --> Form[Email + rola] Form --> Send[Wyślij
zaproszenie] Send --> Email[Email z linkiem
i 7-dniowym tokenem] Email --> Click{Klika link} Click -->|Ma już konto| LinkAccount[Doklej Membership
do istniejącego konta] Click -->|Nie ma konta| Register[Skrócona rejestracja
od razu z Membership] Click -->|Nie klika 7 dni| Expire[Token wygasa
email przypominający] LinkAccount --> Notify[Notyfikacja:
nowe gospodarstwo] Register --> Notify Notify --> InApp[User loguje się
widzi switcher gospodarstw] style Owner fill:#e8f0e0,stroke:#4a7c2c style InApp fill:#4a7c2c,stroke:#2d5016,color:#fff

6.4 Switcher gospodarstw — kluczowy UI element

Top bar (po loginie)

┌─────────────────────────────────────────────────────────────┐ │ 🌾 AGRO 360 [Gospodarstwo Kowalskich ▼] 🔔 (3) 👤 │ └─────────────────────────────────────────────────────────────┘ │ ▼ rozwijane: ┌────────────────────────────┐ │ Twoje gospodarstwa: │ │ ✓ Gospodarstwo Kowalskich │ │ (właściciel) │ │ Pole Nowaka │ │ (agronom) │ │ Spółka Sąsiedzka │ │ (pracownik) │ │ ───────────────────────── │ │ + Załóż nowe gospodarstwo │ │ + Zaakceptuj zaproszenie │ └────────────────────────────┘

Przy zmianie gospodarstwa: reload danych (lub przeładowanie strony), context (currentFarmId) aktualizowany w session i URL.

6.5 Ekran zarządzania użytkownikami

Ustawienia → Użytkownicy (widoczne tylko dla właściciela)

Imię / EmailRolaDołączyłOstatnio aktywnyAkcje
Tomek (Ty)👑 Właściciel2026-05-01teraz
Anna Kowalska
anna@mail.com
🤝 Współwłaściciel2026-05-03wczorajZmień rolę / Usuń
Marek Nowak
marek@mail.com
👷 Pracownik2026-05-102h temuZmień rolę / Usuń
Marta (agronom)
marta@mail.com
👩‍🌾 Agronom2026-05-153 dni temuCofnij dostęp
jan@mail.com⏳ Pracownik (oczekuje)zaproszony 2026-05-20Wyślij ponownie / Anuluj

[+ Zaproś osobę] Limit planu Pro: 3 użytkowników (2 wykorzystanych + Ty)

6.5.1 Limity userów w planach — finalna logika (decyzja v2.0, audit #9 RESOLVED)

Plan Pro ma limit „3 userów" — ale 4 role oraz pomysł 5. (księgowa). Decyzja: licznik dzielony na 3 kategorie:

KategoriaKto się liczyLimit ProLimit Enterprise
OperatorzyWłaściciel + Współwłaściciele + Pracownicy3 łącznieBez limitu
Agronomi-gościeKażdy Agronom z planem „Agronom Pro" zaproszony przez właścicielaBez limitu (oni płacą za siebie)Bez limitu
KsięgowiRola read-only do faktur i kosztów1 gratisBez limitu

Przykład realny dla Tomka (Pro 49 zł/mies): Tomek (właściciel) + Anna (współwłaścicielka) + Marek (pracownik) = 3 operatorzy = limit OK. Plus Marta (agronom) gratis, plus pani Kowalska (księgowa) gratis. Razem 5 osób w gospodarstwie za 49 zł.

6.5.2 Flow przy przekroczeniu limitu (decyzja v2.0, audit #10 RESOLVED)

Co się dzieje gdy właściciel chce zaprosić 4. operatora (limit 3 wykorzystany)? Soft block w UI + jasne opcje:

flowchart TD
    Click[+ Zaproś osobę] --> Form[Email + rola: Pracownik]
    Form --> Submit{Submit}
    Submit --> Check{Limit operatorów
w planie OK?} Check -->|Tak| Send[Wyślij zaproszenie] Check -->|Nie — 3/3| Block[⚠️ Modal:
'Wykorzystałeś limit 3
operatorów planu Pro'] Block --> Opts{User wybiera} Opts -->|Upgrade do Enterprise| Up[Stripe checkout
upgrade] Opts -->|Usuń istniejącego| Remove[Lista 3 obecnych
z opcją usunięcia] Opts -->|Anuluj| Cancel[Zamknij modal] Remove --> RemoveUser[Backend usuwa
membership] RemoveUser --> Send Up --> Active[Subscription upgraded] Active --> Send style Block fill:#fff3d6,stroke:#c08a2a style Send fill:#e8f0e0,stroke:#4a7c2c

Backend: POST /api/farms/:id/invitations z body {email, role} sprawdza limit per role-category. Zwraca 402 Payment Required + payload {current, limit, upgrade_url} jeśli przekroczono. Frontend renderuje modal z 3 opcjami.

Analogicznie dla limitu „1 gospodarstwo" przy próbie utworzenia 2-giego w planie Pro — modal „Drugie gospodarstwo wymaga Enterprise. [Skontaktuj się z nami] [Anuluj]".

6.6 Matrix uprawnień — co która rola widzi w UI

Funkcja / PanelWłaścicielWspółwł.PracownikAgronomKsięgowa
Dashboard👑 pełny👑 pełnyuproszczonypełny (read)tylko widget kosztów
Prace polowe — wpisać
Prace polowe — edytować cudze❌ tylko swoje
Magazyn — czytać
Magazyn — dodawać/edytować
Faktury — czytać
Faktury — dodawać
Koszty — czytać + eksport
Pola — dodawać/edytować
Raporty PDF✅ (operacyjne)✅ (finansowe)
Rekomendacje / notki
Ustawienia gospodarstwa
Zarządzanie users✅ (poza właścicielami)
Billing
Usunięcie gospodarstwa
Audit #9 — niejasne kto liczy się do limitu 3 użytkowników Plan Pro: limit 3 użytkowników (3.5, 8.2). Ale w gospodarstwie mogą być 4 typy ról + pomysł 5. (Księgowa, s.6.7). Brak explicit decyzji kto konsumuje slot:
  • Tylko „operatorzy" (właściciel + współwłaściciel + pracownik)? Agronom-gość gratis, bo to kanał akwizycji?
  • Wszyscy łącznie (4 role × N osób = limit 3)? Najprościej, ale ogranicza agronoma.
  • Per typ roli (np. 1 właściciel + 3 pracowników + 2 agronomów + 1 księgowa = bez limitu w typie)? Najbardziej fair, najtrudniej egzekwować i zakomunikować.
Rekomendacja: „operatorzy gospodarstwa" liczą się do limitu (max 3: właściciel + 2 inne), agronom-gość i księgowa są na zewnątrz limitu (osobny licznik np. „2 gości"). To wspiera kanał afiliacji Marty (s.6.7) i jest fair. Trzeba zaktualizować s.3.5 i s.8.2 spójnie.
Audit #10 — BRAK FLOW: przekroczenie limitu zaproszeń Co się dzieje gdy właściciel klika [+ Zaproś osobę] po dodaniu już 2 (limit = 3 łącznie z właścicielem)? Brak opisu UX. Powinno być:
  • Soft block w UI: formularz zaproszenia otwiera się, ale przy submicie banner „Wykorzystałeś limit 3 userów planu Pro. Opcje: [Upgrade do Enterprise] [Usuń istniejącego] [Anuluj]"
  • Backend hard block: POST /api/farms/:id/invitations zwraca 402 z payload zawierającym current_count, limit, upgrade_url
  • Edge case: co jeśli user usunięty był jedynym aktywnym pracownikiem? Czy slot natychmiast wolny? Tak — atomowo po DELETE.
Analogicznie dla limitu „1 gospodarstwo" przy próbie założenia 2-giego (s.8.9 ma alert, ale brak dokładnego flow UX).
Audit #11 — BRAK EKRAN: dashboard agronoma „moi klienci" Persona Marta (1.2) obsługuje 10-30 gospodarstw. Switcher gospodarstw (6.4) wystarczy do przełączania, ale nie do pracy w wielu jednocześnie. Brakuje:
  • Dashboard agronoma = lista wszystkich gospodarstw z metrykami: ostatnia aktywność, pending wnioski o radę, alerty (np. „Tomek dodał mieszaninę, którą warto sprawdzić")
  • Cross-farm raporty: „pokaż mi co robili moi klienci z rzepakiem w tym tygodniu" (anonimizowane zbiorczo lub per klient za zgodą)
  • Inbox rekomendacji: kolejka „muszę odpowiedzieć / dać poradę dla X klientów"
Bez tego ekranu Marta będzie używać switcheri jak menu plików — niewydajne. To powinna być osobna sub-sekcja 6.8 „Dashboard agronoma" (do dopisania w v1.2).

6.7 Audit log — kto co kiedy zmienił

Dla wszystkich zmian zapisujemy: {userId, action, resource, before, after, timestamp}. Dostępne w panelu „Ustawienia → Historia zmian" (właściciel + współwłaściciel). Kluczowe gdy ktoś zarzuca „kto skasował tę fakturę".

6.8 Dashboard agronoma — multi-farm widok (decyzja v2.0, audit #11 RESOLVED)

Persona Marta obsługuje 10-30 gospodarstw klientów. Sam switcher gospodarstw (s.6.4) to za mało — Marta potrzebuje jednego widoku z którego widzi co dzieje się u wszystkich klientów. To dedykowany dashboard po loginie dla usera z planem „Agronom Pro".

Top-level dashboard Marty

┌──────────────────────────────────────────────────────────────────┐ │ 🌾 AGRO 360 Marta · Agronom Pro 🔔(7) 👤 ▼ │ ├──────────────────────────────────────────────────────────────────┤ │ 📊 PRZEGLĄD KLIENTÓW │ │ │ │ Aktywni: 12 Pending zaproszenia: 2 At-risk: 1 │ │ │ │ ┌──────────────────────────────────────────────────────────────┐│ │ │ 🚨 WYMAGAJĄ TWOJEJ UWAGI (3) ││ │ │ ││ │ │ • Tomek (Kowalskich) — pyta o mieszaninę na rzepak ⏱ 2h temu ││ │ │ • Andrzej (Pole Górne) — zabieg z wysoką dawką ⏱ wczoraj ││ │ │ • Krzysztof (Spółka) — niski stan saletry ⏱ 3 dni ││ │ └──────────────────────────────────────────────────────────────┘│ │ │ │ ┌──────────────────────────────────────────────────────────────┐│ │ │ 📋 LISTA KLIENTÓW ││ │ │ ││ │ │ Klient Ha Ostatni zabieg Health Akcje ││ │ │ Tomek K. 62 2d temu 🟢 85% [otwórz] ││ │ │ Andrzej W. 105 wczoraj 🟡 62% [otwórz] ││ │ │ Krzysztof L. 523 5d temu 🟢 78% [otwórz] ││ │ │ Magda S. 38 2 tyg temu 🔴 24% [otwórz] ││ │ │ ... (12 łącznie) ││ │ │ ││ │ │ [+ Zaproś nowego klienta] [Eksport CSV listy] ││ │ └──────────────────────────────────────────────────────────────┘│ │ │ │ ┌──────────────────────────────────────────────────────────────┐│ │ │ 📊 CROSS-FARM RAPORTY ││ │ │ ││ │ │ • Co dziś robili moi klienci (timeline) ││ │ │ • Wszystkie zabiegi na rzepaku tygodniowo ││ │ │ • Wykorzystanie nawozów po typach (10-30 klientów) ││ │ │ • Eksport pakietu kontrolerskiego — masowo dla wszystkich ││ │ └──────────────────────────────────────────────────────────────┘│ └──────────────────────────────────────────────────────────────────┘

6.8.1 Kolejka rekomendacji (Inbox)

Centralna funkcja agronoma — wszystko co wymaga jego reakcji w jednym miejscu:

Typ alertuTriggerAkcja
Pytanie klientaRolnik napisał notatkę z @martaOdpowiedz / Wezwij na rozmowę
Niska dawka / zła kolejnośćKlient wpisał zabieg z parametrami poza normąKomentarz „rozważ X" / Akceptuj
Pogoda krytycznaPrognoza mróz/deszcz dla regionu klientaSMS do klienta z rekomendacją
Sezonowy reminderZbliża się termin agronomiczny (siew, ochrona)Wygeneruj plan zabiegów
Health score spadłKlient nie loguje się > 14 dniZadzwoń, zaproponuj pomoc

6.8.2 Cross-farm raporty (Agronom Pro feature)

Privacy: Marta widzi dane konkretnego klienta TYLKO za zgodą (s.6.7). Klient może w każdej chwili odebrać dostęp. Cross-farm raporty są zawsze pseudonimizowane gdy wyświetlane (np. „Klient #3" zamiast nazwy), z opcją odsłonięcia tylko przez Martę (audit log).

Spójność z apką — owner/worker zostaje, dochodzą 2 role Istniejące dwa dashboardy (ownerDashboard, workerDashboard) świetnie mapują się na role „Właściciel" i „Pracownik". Współwłaściciel używa ownerDashboard, agronom — nowego (sekcja 5: rozszerzenie). Mniej pracy niż się wydawało.
Niespójność — currentRole musi pochodzić z Membership, nie z wyboru Obecnie selectRole() (l. 3520) pozwala userowi wybrać czy jest właścicielem czy pracownikiem. W SaaS to jest dziura bezpieczeństwa — pracownik kliknąłby „właściciel" i widział faktury. Trzeba: (a) usunąć farmRoleSelect z bootu, (b) rolę pobierać z API GET /api/me/memberships/:farmId, (c) wymuszać role gate na poziomie backendu (frontend gating to tylko UX, nie security).
Pomysł — rola „tylko-do-odczytu" dla księgowej Persona: księgowa gospodarstwa. Potrzebuje raz w miesiącu wejść, pobrać faktury jako CSV/PDF, wyjść. Dodać 5. rolę „Księgowa" — widzi tylko Faktury + Koszty + eksporty. Nie liczy się do limitu „3 użytkowników" w Pro (bo to nie operator).
Pomysł — kanały „Marta przyprowadza nam klientów" Jeśli agronom (Marta) zaprasza swoich klientów-rolników do AGRO 360 (żeby ich obsługiwać), to świetny kanał akwizycji. Dać Marcie: (a) wewnętrzny dashboard „moi klienci", (b) kod afiliacyjny — za każde zapłacone konto 10% przychodu pierwszego roku. Konkurencja tego nie ma.
RODO — zgoda właściciela gospodarstwa na dostęp agronoma Gdy agronom widzi dane gospodarstwa, w sensie prawnym przetwarza dane osobowe rolnika. Trzeba: (a) przy zaproszeniu agronoma osobny checkbox „zgadzam się aby [imię agronoma] miał dostęp do moich danych", (b) możliwość odebrania dostępu jednym klikiem, (c) log dostępu agronoma (kiedy logował się do mojego gospodarstwa). Konsultacja z prawnikiem przed implementacją.

7. Multi-tenancy: model danych Gotowe

Fundament SaaS. Dziś apka ma jedno gospodarstwo per device w localStorage. Docelowo: N gospodarstw w jednej bazie, z twardą izolacją między nimi. Tej sekcji nie da się odpuścić — wszystkie pozostałe są od niej zależne.

7.1 Strategia izolacji — wybieramy „shared DB, tenant_id column"

StrategiaOpisPlusMinus
DB per tenantKażde gospodarstwo = osobna bazaMaks izolacja, łatwy eksport/usunięcieOperacyjnie ciężko przy 1000+ tenantach, migracje schematu mordercze
Schema per tenantWspólna baza, osobny schemat PostgreSQLŚrednia izolacja, łatwiejsze niż osobne DBNadal kosztowne migracje, limity PG na ~liczbę schematów
Shared DB + tenant_idJedna baza, każda tabela ma farm_id, RLS Postgres pilnujeOperacyjnie najprościej, migracje jedna, koszty niskieWymaga rygoru — jeden zapomniany WHERE = wyciek danych

Wybieramy shared DB + tenant_id z Row Level Security w PostgreSQL — standard branżowy dla SaaS naszej skali.

7.2 Schemat bazy — kluczowe tabele

erDiagram
    User ||--o{ Membership : ma
    Farm ||--o{ Membership : ma
    Farm ||--o{ Field : ma
    Farm ||--o{ WorkHistory : ma
    Farm ||--o{ ChemWarehouse : ma
    Farm ||--o{ SeedWarehouse : ma
    Farm ||--o{ GrainWarehouse : ma
    Farm ||--o{ Invoice : ma
    Farm ||--o{ Cost : ma
    Farm ||--o{ Subscription : ma
    Field ||--o{ WorkHistory : "dotyczy"
    User ||--o{ WorkHistory : "wpisał"
    WorkHistory }o--|| MixtureItem : "ma"
    Subscription ||--o{ Invoice_SaaS : "generuje"

    Farm {
        uuid id PK
        string name
        string region
        timestamp createdAt
        uuid ownerId FK
    }
    Field {
        uuid id PK
        uuid farmId FK
        string name
        decimal areaHa
        string crop
        json gpsPolygon
        json parcelNumbers
    }
    WorkHistory {
        uuid id PK
        uuid farmId FK
        uuid fieldId FK
        uuid createdByUserId FK
        enum type
        date workDate
        decimal cost
        json metadata
    }
    ChemWarehouse {
        uuid id PK
        uuid farmId FK
        string name
        enum category
        string registrationNo
        decimal qty
        decimal price
    }
    Subscription {
        uuid id PK
        uuid farmId FK
        enum plan
        timestamp trialEndsAt
        timestamp currentPeriodEnd
        string stripeId
    }
    

7.3 Row Level Security (RLS) — przykład polityki

Każde zapytanie SQL automatycznie filtruje po farm_id aktywnego użytkownika. Backend nigdy nie polega tylko na WHERE w aplikacji — RLS jest siatką bezpieczeństwa.

-- Policy na tabeli fields: user widzi tylko pola gospodarstw w których ma membership
CREATE POLICY field_isolation ON fields
  FOR ALL
  USING (
    farm_id IN (
      SELECT farm_id FROM memberships
      WHERE user_id = current_setting('app.current_user_id')::uuid
    )
  );

ALTER TABLE fields ENABLE ROW LEVEL SECURITY;

Backend ustawia SET app.current_user_id = '...' na początku każdego requestu (z JWT). Reszta dzieje się sama.

7.4 Mapping localStorage → tabele bazy

localStorage (dziś)Tabela (jutro)Klucz tenantUwagi
farmFieldsfieldsfarm_idMigracja 1:1, dodać gpsPolygon JSON
chemWarehousechem_warehousefarm_idCzęść danych (12 ŚOR) wydzielić do sor_catalog jako global read-only
seedWarehouseseed_warehousefarm_id1:1
grainWarehousegrain_warehousefarm_id1:1
agro360_settingsfarms (kolumny)Splittuje się: nazwa/region → farms, profil usera → users
fieldWorkHistory (in-mem!)work_historyfarm_idBUG — dziś nie persystuje. Krytyczna migracja
invoicesRegister (in-mem!)invoicesfarm_idBUG — j.w.
costsRegister (in-mem!)costsfarm_idBUG — j.w. (lub compute on-fly z work_history)
sorDatabase (hardcoded)sor_catalogGlobal, shared między wszystkimi gospodarstwami, zarządzane przez super-admina (sekcja 10)
(brak)usersNowe — konta SaaS
(brak)membershipsNowe — user ↔ farm
(brak)subscriptionsfarm_idNowe — billing
(brak)audit_logfarm_idNowe — kto co zmienił

7.5 Co jest globalne (cross-tenant) — read-only katalogi

Część danych nie należy do żadnego konkretnego gospodarstwa, tylko do całego SaaS:

Każdy z tych katalogów może mieć overrides per farm: gospodarstwo może dodać własny ŚOR (regionalny, nieobjęty katalogiem) lub własnego dostawcę nawozów.

7.6 Wybór backendu — decyzja techniczna

OpcjaCzas do MVPKoszt początkowySkalowalnośćKiedy wybrać
Supabase (PG + Auth + Realtime) 4-8 tygodni Free do 500MB, potem ~25$/mies Dobra do 10k userów, dalej trudniej MVP, mała ekipa, polski hosting przez self-host później
Firebase (Firestore + Auth) 3-6 tygodni Free spora pojemność Świetna, ale NoSQL — komplikuje raporty SQL-style Jeśli zależy nam na czasie i tolerujemy lock-in Google
Własny Node.js + PG 10-16 tygodni VPS ~50-100 zł/mies Pełna kontrola, brak limitów Gdy mamy doświadczonego backenders i czas
Pocketbase (Go, single binary) 4-6 tygodni Self-host od $5/mies Średnia, ale prosta Jeśli zależy na pełnym self-host i prostocie
Rekomendacja wstępna: Supabase na MVP. PostgreSQL pod spodem (znamy go, RLS gotowy), auth wbudowany, realtime, storage na pliki (skany faktur). Możliwość self-host później bez przepisywania. Hosting w EU (Frankfurt) zgodny z RODO.
Audit #12 — KONFLIKT: Subscription per Farm vs Trial per User Schema ERD (7.2) ma Subscription.farmId FK — subskrypcja per gospodarstwo. Ale rejestracja (s.3) tworzy konto usera z 30-dniowym trialem. Jeśli user założy 2. gospodarstwo w trakcie trialu — czy 2. też ma trial? A jak ma już płatne 1. gospodarstwo i zakłada 2. — automatycznie nowa subskrypcja 49 zł/mies czy trial dla 2.?

Dwie ścieżki do wyboru:
  • (A) Subscription per Farm (zgodne z obecnym ERD): każde gospodarstwo ma osobną subskrypcję i osobny trial. Plus: czyste rozliczenie. Minus: skomplikowane dla agronoma z 10 gospodarstwami (10 subskrypcji?).
  • (B) Subscription per User account z limitem N gospodarstw w planie: jedna subskrypcja Pro „daje" 1 gospodarstwo, Enterprise N. Plus: prościej dla usera. Minus: konflikty gdy gospodarstwo ma 3 współwłaścicieli — kto „posiada" subskrypcję?
  • (C) Hybryda: Subscription per Farm dla założyciela; Agronom-gość ma osobne konto „Agronom Pro" z dostępem do N farm (płaci raz za siebie, ale nie konsumuje slotów gospodarstw klientów).
Rekomendacja: (A) dla MVP (najprościej), (C) dla fazy 2 gdy będzie ruch agronomów. ERD i s.8 trzeba uspójnić — dziś jest A w ERD, ale s.3.5 mówi „1 farm w Pro" co sugeruje per-User limit. Wybierz jedną interpretację.

7.6.1 Subskrypcja per Farm + Trial per User account (decyzja v2.0, audit #12 RESOLVED)

Po analizie 3 opcji w pierwotnym audicie — wybieramy opcję A z poprawką:

Konsekwencje dla UI:

7.6.2 Multi-farm billing — szczegóły (decyzja v2.0, audit #13 RESOLVED)

ScenariuszCo się dzieje
User ma 1 gospodarstwo Pro1 subskrypcja, 1 faktura/mies, jedna karta
User zakłada 2-gie gospodarstwo (Pro)2 subskrypcje na tym samym Stripe Customer, 2 osobne faktury, ta sama karta domyślnie (można zmienić per gospodarstwo)
User-właściciel + zaproszony jako współwł. do innego1 jego subskrypcja własna + 0 dodatkowych (płaci tamten właściciel)
Marta (Agronom Pro) + zaproszona do 5 gospodarstw1 jej subskrypcja Agronom Pro (99 zł) + 0 zł od 5 gospodarstw (każde płaci swoje Pro osobno)
Anulowanie subskrypcji jednego gospodarstwaTylko to gospodarstwo przechodzi w read-only / suspend. Pozostałe nadal aktywne.
Transfer własności gospodarstwaSubscription metadata.owner_id zmienia się; nowy właściciel ma 7 dni na wpięcie własnej karty; jeśli nie — auto-anulowanie po obecnym okresie

7.7 Migracja danych existing user → SaaS

Co z userami którzy używają lokalnej apki dziś i ich danymi w localStorage?

  1. Apka lokalna nadal działa offline (nie blokujemy)
  2. Dodajemy w niej przycisk „Przejdź na SaaS — przenieś dane"
  3. Wykorzystujemy istniejące exportAppData() (l. 6449) — generuje JSON z całością
  4. Rejestracja na SaaS → krok 2.5 w wizardzie: „Masz dane z apki lokalnej? Wgraj plik backup"
  5. Import dzieli na tabele (fields, warehouse, history, ...), przypisuje farm_id nowo utworzonego gospodarstwa
Spójność z apką — eksport JSON jest gotowy fundament exportAppData()/importAppData() (l. 6449/6472) generują/przyjmują JSON z całością danych gospodarstwa. To idealny format wymiany przy migracji do SaaS. Trzeba tylko: (a) dodać do exportu wersję schematu, (b) w importerze SaaS mapować pola → kolumny w bazie.
Krytyczna luka — in-memory state Trzy najważniejsze zbiory danych (fieldWorkHistory, invoicesRegister, costsRegister) nie są dziś persystowane. Przed jakąkolwiek migracją trzeba je najpierw zapisać do localStorage (tymczasowy fix), potem zmigrować do backendu. Inaczej user „testuje SaaS" i traci całą historię.
RODO — hosting w EU jest must Dane osobowe rolników (imię, telefon, lokalizacja gospodarstwa) muszą być przetwarzane w EU. Supabase ma Frankfurt — OK. Jeśli wybierzemy AWS/GCP, trzeba region eu-central-1 / europe-west3. Brak Stanów. To wpływa też na rozliczenie z OCR-em (sekcja 11) i mailerem.
Pomysł — soft-delete + 30-dniowy kosz Nigdy nie kasujemy fizycznie z bazy. Zamiast tego flaga deleted_at. „Kosz" dostępny w ustawieniach 30 dni. Po 30 dniach hard delete batch jobem. Ratuje przed pomyłkami („skasowałem fakturę, jak ją odzyskać?") i ułatwia debug.
Pomysł — public read API dla katalogów sor_catalog, fertilizer_catalog są publiczne (każdy może je czytać). Wystawić jako public REST API (np. api.agro360.pl/v1/sor) — przyda się: (a) aplikacjom mobilnym, (b) potencjalnym partnerom (sklepy rolnicze), (c) SEO (każdy preparat = strona indexowana w Google).

8. Billing i subskrypcja Gotowe

Cel: jak najmniej tarcia przy pierwszej płatności i jak najmniej wsparcia. Dla persony Tomek (42, smartfon) — musi działać z BLIKa, w 3 klikach, na telefonie.

8.1 Wybór dostawcy płatności

DostawcaPlusMinusKoszt
Stripe Globalny standard, świetna dokumentacja, subskrypcje out-of-the-box, hosted checkout, faktury VAT, Customer Portal gratis Brak BLIK-a (krytyczne dla PL), brak Przelewy24 — głównie karta 1.4% + 2 zł / transakcja w EU
Przelewy24 (Przelewy24) BLIK, Apple/Google Pay, przelewy bankowe — pokrywa 95% PL Subskrypcje słabsze (recurring trzeba budować ręcznie), gorsze API 1.5-2.5% + 0.39 zł
Tpay BLIK, przelewy, dobre PL wsparcie, subskrypcje OK Mniejsza dokumentacja niż Stripe, mniejszy ekosystem 1.7% + 0 zł
Stripe + Przelewy24 (hybryda) Stripe do logiki subskrypcji (Customer, Subscription, Invoice), P24 jako payment method w Stripe (jest natywnie) Dwa SLA, dwa rozliczenia ~1.5-2% łącznie
Rekomendacja: Stripe + Przelewy24 jako payment method w Stripe. Stripe ma natywne wsparcie P24 i BLIK (przez P24) od 2024. Dostajemy najlepszy z dwóch światów: solidną logikę subskrypcji + PL metody płatności. Drugi wybór: Tpay solo, jeśli okaże się że Stripe-P24 ma jakieś niespodzianki w PL.

8.2 Plany — finalna struktura (z sekcji 3, tu z perspektywy backendu)

PlanStripe Price IDCena / intervalTrialLimity (enforced w app)
Trial0 zł, 30 dni1 farm, 3 users, wszystko inne bez limitu
Pro miesięcznyprice_pro_monthly49 zł / mies30 dni1 farm, 3 users
Pro rocznyprice_pro_yearly490 zł / rok (= 2 mies gratis)30 dni1 farm, 3 users
Enterpriseprice_enterprise_*NegocjowaneN farms, N users, API, dedicated

8.3 Flow konwersji trial → płatny

flowchart TD
    Trial[Trial dzień 1-23] -->|7 dni przed końcem| Email1[Email + banner:
'Zostało 7 dni'] Email1 --> Trial24[Trial dzień 24-29] Trial24 -->|2 dni przed końcem| Email2[Email + banner:
'Zostało 2 dni - wybierz plan'] Email2 --> Day30{Dzień 30:
karta wpięta?} Day30 -->|Tak, auto-charge| Charge[Stripe pobiera 49 zł] Day30 -->|Nie| ReadOnly[Read-only mode:
można czytać, nie pisać] Charge -->|OK| Active[Subscription active] Charge -->|Fail| RetryFlow[Retry: 1d, 3d, 5d, 7d
email + banner] RetryFlow -->|Sukces| Active RetryFlow -->|7 dni fail| ReadOnly ReadOnly --> Choice{User decyduje} Choice -->|Wybiera plan| Checkout[Checkout Stripe] Choice -->|Eksport + wyjście| Export[exportAppData JSON] Checkout --> Active Choice -->|Nic przez 60 dni| Suspend[Konto zawieszone
dane zachowane 12 mies] style Active fill:#4a7c2c,stroke:#2d5016,color:#fff style ReadOnly fill:#fff3d6,stroke:#c08a2a style Suspend fill:#ffe9e9,stroke:#e88a8a

8.4 Ekran „Subskrypcja" w aplikacji

Ustawienia → Subskrypcja (tylko właściciel)

  • Aktualny plan: Pro miesięczny — 49 zł/mies
  • Status: ✅ Aktywna
  • Następne pobranie: 25 czerwca 2026 (za 31 dni)
  • Metoda płatności: BLIK (telefon ****1234) — [Zmień]
  • [Zmień plan na roczny — zaoszczędź 98 zł/rok]
  • [Pobierz fakturę VAT za maj 2026]
  • [Historia płatności] (lista wszystkich faktur)
  • [Anuluj subskrypcję] (mały link, ale widoczny)

8.5 Anulowanie subskrypcji

Anulowanie zawsze proste (nie ukrywać, nie utrudniać — RODO + dobre obyczaje). Flow:

flowchart LR
    Click[Klik 'Anuluj'] --> Reason[Krótki form:
dlaczego? opcjonalne] Reason --> Confirm{Potwierdź} Confirm -->|Tak| Cancel[Subskrypcja kończy się
na koniec okresu rozliczeniowego] Cancel --> Until[Do końca okresu:
pełna funkcjonalność] Until --> Expire[Po końcu okresu:
read-only mode] Expire --> Retain[Dane zachowane 12 mies
możliwy reactivate] style Cancel fill:#fff3d6,stroke:#c08a2a style Retain fill:#e8f0e0,stroke:#4a7c2c

8.6 Faktury VAT

Stripe generuje faktury VAT automatycznie, ale dla polskich firm trzeba dodać:

Decyzja prawna — kto wystawia faktury? AGRO 360 musi być spółką (Sp. z o.o. / JDG) zarejestrowaną w PL, VAT-czynna jeśli przychody > 200k zł/rok. Wybór formy prawnej + księgowa wpływają na to czy Stripe Tax wystarczy, czy trzeba własny system fakturowy. Konsultacja z księgową przed startem.
Audit #13 — niespójność z s.7: brak logiki multi-farm billing Sekcja 8 opisuje plan „1 farm w Pro" jakby każdy user miał jedno gospodarstwo. Ale s.7.2 (ERD) ma Subscription.farmId, więc gospodarstwo ma subskrypcję. Pytania bez odpowiedzi:
  • User-założyciel ma 2 gospodarstwa → płaci 2× 49 zł? Czy 1× 49 zł z limitem 1 i musi upgrade do Enterprise dla 2-go?
  • Współwłaściciel został dopisany do 2-giego gospodarstwa innego usera — nie płaci dodatkowo, ale konsumuje slot „1 farm" pierwotnego właściciela?
  • Faktura VAT idzie na właściciela czy na gospodarstwo (które może mieć inny NIP)?
To powiązane z auditem #12. Najczystsza interpretacja: Subscription jest własnością Farm; właściciel gospodarstwa jest ChargeContact (osoba która płaci kartą); user z 2 gospodarstwami ma 2 osobne subskrypcje na koncie. Trzeba dopisać do s.8.2 i s.8.4 jak to wygląda w UI (np. ekran „Subskrypcje" — lista jeśli user ma > 1 gospodarstwo).
Audit (#5 powtórnie) — odesłanie Cała s.8 (dunning, retry, anulowanie) zakłada wpiętą metodę płatności, ale flow wpięcia nie istnieje. Patrz audit #5 w s.3. Bez rozwiązania tamtego, dunning w 8.3 to abstrakcja.

8.7 Webhooki Stripe — obsługiwane eventy

EventAkcja w naszym systemie
customer.subscription.createdSet subscription.status = active, set currentPeriodEnd
customer.subscription.updatedSync planu, current period end, status
customer.subscription.deletedSet status = canceled, schedule read-only po current period
invoice.payment_succeededSend confirmation email, update subscription period
invoice.payment_failedSend dunning email (1d/3d/5d/7d retry), banner w aplikacji
customer.subscription.trial_will_endSend email 3 dni przed końcem trialu (Stripe robi to 3 dni przed automatically)

8.8 Co istnieje w apce a koliduje z billingiem SaaS

Konflikt nazw — paymentsPanel w apce ≠ billing SaaS W apce paymentsPanel (l. 2501) i showPaymentsPanel() to wydatki rolnika (płatności za nawozy, paliwo, usługi). W SaaS „Płatności" / „Billing" to opłaty za SaaS. Kolizja nazewnictwa. Zmienić: paymentsPanelfarmExpensesPanel, a nowy moduł billingu nazwać subscriptionPanel (Subskrypcja).

8.9 Enforcement limitów planu

Backend egzekwuje limity per request. Frontend pokazuje przyjazne komunikaty.

LimitTrial / ProCo się dzieje przy przekroczeniu
Users w gospodarstwie3Backend rzuca 402. UI: „Limit 3 użytkowników w planie Pro. Upgrade do Enterprise lub usuń kogoś"
Liczba gospodarstw1Backend rzuca 402. UI: „Drugie gospodarstwo wymaga Enterprise. [Skontaktuj się]"
Storage (skany faktur)5 GBUpload zwraca 413. UI: „Wykorzystano 5 GB z 5 GB. Usuń stare lub upgrade"
Eksporty PDF / miesBez limitu w Pro
API callsAPI tylko w Enterprise (rate limit 1000/godz)
Spójność z apką — nic nie jest dziś związane z płatnościami Apka w ogóle nie ma pojęcia subskrypcji SaaS. To dobra wiadomość — można dodać warstwę billingu jako czysty „add-on" bez konfliktów. Tylko jedna kolizja nazewnictwa (paymentsPanel — patrz wyżej).
Pomysł — kupony i kody promocyjne Stripe ma natywny Coupon system. Wykorzystać do: (a) kodów dla agronomów (sekcja 6 — afiliacja), (b) promocji „pierwsi 100 userów = 6 mies za 1 zł", (c) kodów partnerskich (Top Agrar, izby rolnicze). Tani sposób na boost akwizycji.
Pomysł — model „per ha" jako alternatywa Dla persony Krzysztof (500+ ha) flat 49 zł/mies jest absurdalnie tani — zostawiamy pieniądze na stole. Dodać Enterprise: 0.5 zł/ha/mies (= 250 zł/mies @ 500ha). Bardziej fair. Wymaga: (a) Stripe metered billing, (b) liczenia powierzchni gospodarstwa na koniec okresu, (c) komunikacji „Twoja powierzchnia to 523 ha, opłata: 261,50 zł".
Dunning — co robić gdy płatność się nie udaje Persona Tomek może mieć skończony limit BLIK / kartę zablokowaną w żniwa. Nie kasujemy konta natychmiast! Sekwencja: (a) dzień 1: email „nie udało się pobrać", retry 3 dni później, (b) dzień 3-7: 3 retry + 3 emaile + banner, (c) dzień 7: read-only mode (dane widoczne, nie da się pisać), (d) dzień 60: konto zawieszone, dane archiwizowane 12 mies. Anti-pattern: cancel po pierwszej nieudanej płatności.

9. Ustawienia konta Gotowe

Kluczowe rozróżnienie: ustawienia konta (usera) vs ustawienia gospodarstwa (farmy). Dziś w apce wszystko jest pomieszane w settingsPanel + agro360_settings. W SaaS rozdzielamy — bo jeden user może być w wielu gospodarstwach, a jego profil jest jeden.

9.1 Struktura ustawień — dwa drzewa

⚙️ USTAWIENIA ├─ 👤 Moje konto ← per User (cross-farm) │ ├─ Profil (imię, email, telefon, język, avatar) │ ├─ Bezpieczeństwo (hasło, 2FA, sesje) │ ├─ Powiadomienia (email/SMS/push, częstotliwość) │ ├─ Połączone konta (Google OAuth) │ ├─ Moje dane (eksport RODO) │ └─ Usunięcie konta │ └─ 🏡 Gospodarstwo „Pole Kowalskich" ← per Farm (current context) ├─ Profil gospodarstwa (nazwa, region, NIP, lokalizacja) ├─ Subskrypcja (sekcja 8) ├─ Użytkownicy (sekcja 6) ├─ Pola i uprawy (sekcja 5) ├─ Domyślne ustawienia (jednostki, waluta, format daty) ├─ Integracje (księgowość, ARiMR — Enterprise) ├─ Backup i eksport ├─ Audit log └─ Usunięcie gospodarstwa (tylko właściciel)

9.2 Moje konto — profil użytkownika

Ustawienia → Moje konto → Profil

  • Avatar — upload zdjęcia (opcjonalne) lub inicjały na kolorowym tle
  • Imię i nazwisko
  • Email — zmiana wymaga weryfikacji nowego emaila
  • Telefon — opcjonalne, do 2FA i powiadomień SMS
  • Język interfejsu — PL (domyślnie), EN/UA (na przyszłość)
  • Strefa czasowa — Europe/Warsaw (domyślnie z geolokalizacji)
  • [Zapisz zmiany]

9.3 Bezpieczeństwo

Zmiana hasła

  • Stare hasło → Nowe hasło (min 8 znaków, indykator siły) → Powtórz
  • Po zmianie: wszystkie inne sesje wylogowane (z opcją „wyloguj również tę")
  • Email potwierdzający („Twoje hasło zostało zmienione. Jeśli to nie Ty — kliknij tu")

Two-Factor Authentication (2FA)

  • SMS — kod na telefon (wymaga zweryfikowanego numeru)
  • Aplikacja TOTP — Google Authenticator / Authy / 1Password
  • Kody zapasowe — 10 jednorazowych kodów do druku
  • Opcjonalne dla wszystkich, wymagane dla roli Właściciel w planie Enterprise

Aktywne sesje

UrządzenieLokalizacja (IP)Ostatnia aktywnośćAkcja
iPhone Safari (ta sesja)Poznańteraz
Chrome / WindowsPoznań2h temu[Wyloguj]
Android ChromeKonin5 dni temu[Wyloguj]

[Wyloguj wszystkie poza tą]

9.4 Powiadomienia

PowiadomienieEmailSMSPush (PWA)
Niski stan magazynowy
Zaproszenie do gospodarstwa✅ zawsze
Nowy zabieg dodany przez kogoś
Koniec trialu (7d / 2d / 0d)✅ zawsze
Płatność powiodła się / nie✅ zawsze
Cotygodniowy raport („w tym tygodniu w gospodarstwie")
Alerty pogodowe (mróz, deszcz przed opryskiem)

Każda kategoria z togglem on/off per kanał. SMS tylko gdy zweryfikowany numer + odpowiedni plan (Enterprise lub plan z dodatkiem SMS — alternatywnie limit np. 10 SMS/mies w Pro).

9.5 Moje dane (RODO Article 15 + 20)

RODO daje userowi prawo: (a) wiedzieć jakie dane mamy, (b) otrzymać je w formacie maszynowym, (c) żądać usunięcia.

Ustawienia → Moje dane

  • Pobierz wszystkie moje dane — generuje ZIP z JSON: profil, members gospodarstw, audit log mojej aktywności. Tylko moje dane jako usera, nie dane gospodarstw (te eksportuje właściciel osobno).
  • Pobierz dane gospodarstwa „Pole Kowalskich" — jeśli jestem właścicielem: pełen JSON gospodarstwa (mapa, ekonomicznie podobne do exportAppData() z apki — l. 6449)
  • Status wniosku o usunięcie — jeśli aktywny, info kiedy zakończy się grace period

9.6 Usunięcie konta — flow „double opt-out" (decyzja v2.0, audit #14 RESOLVED)

Z poprawką: żaden user nie może zostać uwięziony w SaaS. Jeśli jest jedynym właścicielem, dajemy mu wybór per gospodarstwo (przekaż / opuść / usuń).

flowchart TD
    Click[Klik 'Usuń konto'] --> Warn[Ekran:
co się stanie?
lista skutków + Twoje gospodarstwa] Warn --> HasMember{Mam jakieś
memberships?} HasMember -->|Nie| Confirm HasMember -->|Tak| Resolve[Ekran 'Najpierw załatwmy gospodarstwa':
lista wszystkich memberships
z opcją per gospodarstwo] Resolve --> Per{Per gospodarstwo} Per -->|Jestem jedynym właścicielem| Choice1[Wybierz:
• Przekaż współwłaścicielowi
• Usuń gospodarstwo wraz z kontem
• Zaproś nowego właściciela i odczekaj] Per -->|Jestem współwłaścicielem| Choice2[Wybierz:
• Tylko opuść
• Wymuś usunięcie gospodarstwa
jeśli jestem ostatnim aktywnym] Per -->|Jestem pracownikiem/agronomem/księgową| Choice3[Auto: opuszczam membership] Choice1 --> AllDone Choice2 --> AllDone Choice3 --> AllDone AllDone{Wszystkie
załatwione?} AllDone -->|Nie| Resolve AllDone -->|Tak| Confirm[Wpisz email + 'USUWAM'
żeby potwierdzić] Confirm --> Email[Email z linkiem
'Potwierdź usunięcie'] Email --> Click2[Klik w emailu w 24h] Click2 --> Soft[Soft-delete:
konto deactivated] Soft --> Grace[30 dni grace period
możliwy reactivate] Grace --> Hard[Po 30 dniach:
hard delete + anonimizacja] Hard --> AuditLog[Wpis w gov audit:
'user X deleted on Y'] style Soft fill:#fff3d6,stroke:#c08a2a style Hard fill:#ffe9e9,stroke:#e88a8a style Resolve fill:#e8f1fb,stroke:#7aa8e0

Ekran „Najpierw załatwmy gospodarstwa"

Lista wszystkich memberships usera z dedykowaną akcją per pozycja:

GospodarstwoMoja rolaStatusAkcja
Gospodarstwo Kowalskich👑 Jedyny właściciel⚠️ wymaga decyzji[Przekaż] [Usuń też gospodarstwo]
Pole Nowaka👩‍🌾 AgronomOK[Opuść]
Spółka Sąsiedzka👷 PracownikOK[Opuść]

Przycisk „Kontynuuj usuwanie konta" jest disabled dopóki wszystkie pozycje nie są załatwione.

Opcja „Usuń też gospodarstwo" wywołuje flow z s.9.9 (usunięcie gospodarstwa) — z osobnym double opt-out + emailem do wszystkich userów gospodarstwa o usunięciu przez właściciela. Cały proces zaprojektowany żeby user mógł zawsze wyjść — zgodnie z RODO Art. 17.

Co się dzieje przy hard delete: user usunięty, jego memberships usunięte, ale dane gospodarstwa (zabiegi, faktury które wpisał) zostają — z atrybucją „usunięty użytkownik" (audit log). To zgodne z RODO (legitimate interest właściciela gospodarstwa do dokumentacji).

Audit #14 — LOCK-IN: jedyny właściciel nie może usunąć konta Flow w 9.6 mówi: „Jestem właścicielem czegokolwiek → blokada, najpierw przekaż własność / usuń gospodarstwo". Problem: jeśli jestem jedynym właścicielem jednego gospodarstwa bez współwłaścicieli, nie mam komu przekazać. Pozostaje „usuń gospodarstwo" — ale flow tego nie pokazuje jako opcji w wizardzie usuwania konta. To narusza RODO Art. 17 (prawo do bycia zapomnianym).

Poprawka flow: ekran „Najpierw musimy załatwić gospodarstwa" z listą:
  • „Gospodarstwo Kowalskich" — jesteś jedynym właścicielem
    [Przekaż własność innemu userowi] [Usuń to gospodarstwo wraz z kontem]
  • „Pole Nowaka" — jesteś agronomem
    [Tylko opuść — gospodarstwo zostaje]
Dopiero po rozwiązaniu wszystkich pozycji → przechodzimy do potwierdzenia usunięcia konta. Bez tego user czuje się uwięziony i to materiał na skargę do UODO.

9.7 Ustawienia gospodarstwa

Gospodarstwo → Profil

  • Nazwa gospodarstwa
  • Region (województwo)
  • NIP / REGON (opcjonalne, do faktur VAT)
  • Adres siedziby
  • Łączna powierzchnia (auto-liczona z pól)
  • Logo gospodarstwa (na raportach PDF)

Gospodarstwo → Domyślne ustawienia

  • Waluta — PLN (domyślnie)
  • Format daty — DD.MM.YYYY (domyślnie PL)
  • Jednostki: powierzchnia ha, masa kg/t, objętość l (zgodne z apką)
  • Domyślna stawka VAT dla faktur — 8% / 23% / 0%
  • Pierwszy dzień tygodnia — Poniedziałek (PL)
  • Progi alertów magazynowych — % poniżej którego alert (domyślnie 20%)

9.8 Backup i eksport gospodarstwa

Gospodarstwo → Backup

  • Auto-backup — codziennie 23:00, 30 ostatnich + 12 miesięcznych, pobieralne
  • Eksport on-demand — wykorzystuje istniejące exportAppData() z apki, ale rozszerzone: ZIP zawiera JSON + PDF raporty + skany faktur
  • Eksport do Excela — XLSX z arkuszami: Pola, Zabiegi, Faktury, Koszty per uprawa
  • Eksport ARiMR — XML w formacie wymaganym do e-Wniosku (Enterprise)

9.9 Usunięcie gospodarstwa

Tylko właściciel. Identyczny flow jak usunięcie konta (double opt-out, 30 dni grace, hard delete + anonimizacja). Dodatkowo: wszyscy users dostają email „gospodarstwo zostało usunięte przez właściciela".

Spójność z apką — istniejące settingsPanel rozdzielić Obecnie settingsPanel (l. 2744) miesza: nazwę gospodarstwa, imię właściciela, region. W SaaS te pola należą do różnych encji (user vs farm). Refaktor: (a) oddzielić formularze, (b) imię/email/telefon → users, (c) nazwa/region/NIP → farms. Istniejące saveSettingsFarm() (l. 6412) trzeba rozbić na updateMyProfile() + updateFarmProfile().
Spójność z apką — eksport/import już jest exportAppData() i importAppData() (l. 6449/6472) realizują połowę wymogów RODO Art. 20 (portability). Wystarczy: (a) dodać do exportu sygnaturę (kto wyeksportował, kiedy), (b) wystawić jako endpoint backendu GET /api/farms/:id/export, (c) dorzucić skany faktur i PDFy.
Brakuje w apce — żadnego pojęcia hasła ani 2FA To zero do zbudowania od podstaw. Korzystamy z Supabase Auth: (a) magic link / email+hasło / OAuth Google — gotowe, (b) TOTP — wbudowane, (c) reset hasła — gotowe. Nie wymyślamy koła.
Pomysł — eksport „pakiet kontrolerski" Dedykowany przycisk: „Wygeneruj pakiet pod kontrolę ARiMR/PIORiN" — generuje PDF zawierający: rejestr ŚOR z numerami zezwoleń, mapę pól z numerami działek, paragony/faktury zakupowe, podsumowanie zużycia. Jeden klik = stres kontroli mniej. To prawdziwy killer feature dla persony Tomek.
Pomysł — „transfer własności gospodarstwa" Tomek umiera / przechodzi gospodarstwo na syna. Flow: właściciel wybiera innego współwłaściciela → „Przekaż własność" → email z potwierdzeniem do nowego właściciela → dwukrotne potwierdzenie → transfer. Stary właściciel staje się współwłaścicielem lub jest usuwany. Mało częste, ale gdy potrzebne — bardzo emocjonalne, musi działać niezawodnie.
Sukcesja — co po śmierci jedynego właściciela? Persona Krzysztof 55 lat — realna sprawa. Jeśli jedyny właściciel umiera i nie ma współwłaścicieli, gospodarstwo zostaje w stanie „limbo". Trzeba: (a) mechanizm „kontakt awaryjny" (zaufany email z prawem do reset hasła + transfer własności po weryfikacji ze skanem aktu zgonu i postanowienia spadkowego), (b) jasne zasady w regulaminie. Konsultacja z prawnikiem.

10. Admin panel (super-admin) Gotowe

Wewnętrzne narzędzie dla zespołu AGRO 360. Nigdy nie publiczne, dostępne pod osobnym subdomenem (admin.agro360.pl) z IP whitelistą + obowiązkowym 2FA. Cel: prowadzić biznes (metryki) + pomagać klientom (support).

10.1 Role w panelu admin

RolaKtoMoże
Super-adminZałożyciele, CTOWszystko: zarządzać innymi adminami, robić refund, usuwać konta klientów, mieć dostęp do danych klientów
SupportCustomer support, helpdeskCzytać dane klientów (z logiem!), impersonate (z zgodą), zmienić plan, robić refund < 200 zł
Read-onlyInwestor, księgowa, marketingTylko metryki agregowane (MRR, churn), bez dostępu do indywidualnych klientów
ContentOsoba aktualizująca katalog ŚOREdycja sor_catalog, fertilizer_catalog, crop_catalog (sekcja 7) — nic więcej

10.2 Struktura panelu — ekrany

🛠️ ADMIN PANEL ├─ 📊 Dashboard (default landing) │ ├─ MRR (Monthly Recurring Revenue) + zmiana m/m │ ├─ Liczba aktywnych gospodarstw + zmiana │ ├─ Churn rate (m/m, kwartalny, roczny) │ ├─ Trial conversion rate │ ├─ NPS score (jeśli mierzony) │ └─ Alerty: dunning failures, support ticket SLA, błędy systemu │ ├─ 🏡 Gospodarstwa │ ├─ Lista (filtry: plan, status, region, ostatnia aktywność) │ ├─ Szczegóły gospodarstwa │ │ ├─ Stan subskrypcji, MRR │ │ ├─ Lista users + role │ │ ├─ Aktywność (ostatnie zabiegi, last login) │ │ ├─ Akcje: impersonate, refund, zmień plan, zawieś, usuń │ │ └─ Audit log gospodarstwa │ └─ Eksport CSV listy │ ├─ 👥 Użytkownicy │ ├─ Lista (filtry: data rejestracji, weryfikacja, źródło) │ ├─ Szczegóły usera (memberships, sesje, działanie) │ └─ Akcje: reset hasła, wymuszone wylogowanie, usuń │ ├─ 💰 Przychody │ ├─ Wykres MRR / ARR w czasie │ ├─ Cohort retention (kwartalne) │ ├─ Lista faktur SaaS │ ├─ Refundy + dunning queue │ └─ Eksport do księgowej │ ├─ 📚 Katalogi (CRUD) │ ├─ sor_catalog (preparaty ŚOR) │ ├─ fertilizer_catalog │ ├─ crop_catalog │ └─ suppliers (dostawcy nawozów) │ ├─ 🎯 Marketing │ ├─ Kupony / kody promocyjne (Stripe sync) │ ├─ Email campaigns (templates, queue) │ └─ Lead source analytics (UTM) │ ├─ 🐛 Support │ ├─ Tickety (jeśli wbudowany helpdesk) │ ├─ Logi błędów (Sentry integration) │ ├─ Health checks (API uptime, DB load, queue lag) │ └─ Feature flags (rollout per cohort) │ └─ 🔐 Settings ├─ Lista adminów + role ├─ Audit log adminów (kto co kiedy) └─ Konfiguracja systemu (limity, feature flags)

10.3 Dashboard — kluczowe metryki

Top row — single numbers (delta vs poprzedni okres)

MetrykaWartość (przykład)Δ m/m
MRR14 740 zł+12% ✅
Aktywne gospodarstwa (płatne)301+18 ✅
Trial w toku89+24 ✅
Trial → paid conversion34%+2 pp ✅
Churn (anulowane / aktywne)3.2% / mies−0.4 pp ✅
ARPU49 zł0
Dunning failures (open)4−2 ✅

10.3.1 Metryki kanału Agronom (decyzja v2.0, audit #16 RESOLVED)

Osobny widget na dashboardzie admina — Marta i inni doradcy są drugim filarem przychodów:

MetrykaWartość (przykład)Δ m/m
Aktywni agronomi (Agronom Pro)14+3 ✅
MRR z planów Agronom Pro1 386 zł (= 14 × 99)+297 zł ✅
Średnia liczba klientów per agronom8 (mediana 6, max 24)+0.5 ✅
Rolnicy sprowadzeni przez agronomów87 (28% wszystkich Pro)+12 ✅
Conversion: zaproszenie agronoma → akceptacja klienta62%+4 pp ✅
Churn klientów z agronomem vs bez2.1% vs 3.8%
NPS agronomów52+6 ✅
Wykorzystane kupony afiliacyjne34+8 ✅

Hipoteza do udowodnienia metrykami: klienci sprowadzeni przez agronoma mają niższy churn (potwierdzone wstępnie: 2.1% vs 3.8%). Jeśli się utrzyma, to mocny argument za inwestycją w kanał (więcej kuponów, większy retainer dla agronoma).

10.4 „Impersonate" — kluczowa funkcja supportu

Klient dzwoni z problemem, support musi zobaczyć dokładnie to co widzi user. Implementacja:

flowchart TD
    Support[Admin Support] --> Search[Szukaj usera / farmy]
    Search --> Find[Wybór klienta]
    Find --> Request[Klik 'Impersonate']
    Request --> Consent{Wymagana zgoda?}
    Consent -->|Tak - zawsze poza CRITICAL| EmailUser[Email do usera:
'Support chce mi pomóc - zgadzasz się?'] EmailUser --> UserConsent{User zgadza się?} UserConsent -->|Tak, klik w emailu| Token[Token tymczasowy
ważny 30 min] UserConsent -->|Nie / brak akcji 24h| Deny[Brak dostępu] Token --> SessionLog[Session jako user
z banerem czerwonym
'IMPERSONATING - widzi user'] SessionLog --> AuditAll[Każda akcja w audit log
z atrybucją 'support@: admin X'] style Token fill:#fff3d6,stroke:#c08a2a style SessionLog fill:#ffe9e9,stroke:#e88a8a

Anti-patterns do uniknięcia:

10.5 Operacje wsparcia

OperacjaKto możeAudit / notification
Reset hasła klientaSupportEmail do klienta + log
Wymuszone wylogowanieSupportLog
Refund < 200 złSupportLog + faktura korygująca
Refund >= 200 złSuper-adminLog + faktura korygująca + Slack alert
Zmiana planu klientaSupportEmail do klienta + log
Zawieszenie kontaSuper-adminEmail + log + Slack
Usunięcie konta klientaSuper-admin (2 person approval)Email + log + Slack + backup
Eksport wszystkich danych klienta (RODO)SupportEmail + log
Edycja danych klienta (np. korekta NIPu)SupportDiff w audit log

10.6 Health i monitoring

Audit #15 — BRAK: środowiska testowe (sandbox / staging) Sekcja 10 opisuje produkcyjny admin panel, ale brakuje jak zespół testuje SaaS bez psucia danych klientów. Trzeba zdecydować:
  • Staging — kopia produkcji z syntetycznymi danymi, refresh co tydzień. Adres: app-staging.agro360.pl. Wszyscy developerzy + 2-3 power-userów beta tu testują nowe ficzery.
  • Sandbox per dev — każdy programista ma własny tenant z seed data, izolowany lokalnie. Supabase pozwala na local dev w Dockerze.
  • Test accounts na produkcji — oznaczone flagą is_internal=true, nie liczone do metryk MRR/churn w admin panelu (s.10.3), używane do smoke testów po deployu.
  • Stripe Test Mode — używamy test keys w staging + dev, prawdziwe karty tylko na prod.
Bez tego flow developer wprowadzi bug i 300 klientów straci dostęp na 2h. To powinna być sub-sekcja 10.8 do dopisania w v1.2.

10.8 Środowiska testowe (decyzja v2.0, audit #15 RESOLVED)

Trzy poziomy izolacji od produkcji — żeby zespół mógł rozwijać bez psucia danych klientów:

ŚrodowiskoAdresCelKonfiguracja
Local dev localhost:5173 Każdy developer ma własną kopię — szybkie iteracje, eksperymenty bez wpływu na innych Supabase local (Docker) + Stripe Test Mode + seed data z generatora (faker)
Staging app-staging.agro360.pl Pre-production: testy QA, demo dla klientów, walidacja przed deployem na prod Osobny projekt Supabase (refresh raz na tydzień z anonimizowanej kopii prod) + Stripe Test Mode + email do @agro360.pl tylko (sandbox provider)
Production app.agro360.pl Klienci — prawdziwe dane, prawdziwe pieniądze Supabase EU + Stripe Live Mode + Resend + monitoring 24/7

10.8.1 Test accounts na produkcji

Czasem zespół musi przetestować coś na realnej produkcji (np. webhook Stripe Live, nowy flow OAuth). Mechanizm:

10.8.2 Smoke testy po deployu

Po każdym deployu na prod, GitHub Actions uruchamia Playwright E2E na test accounts:

  1. Login działa (email + hasło, OAuth Google)
  2. Dashboard ładuje się < 2s
  3. Wpisanie zabiegu zapisuje się i odlicza z magazynu
  4. Generacja PDF pakietu kontrolerskiego nie wywala 500
  5. Stripe webhook (test event) trafia w endpoint i przetwarza

Jeśli któryś fail → automatyczny rollback do poprzedniej wersji + Slack alert.

10.7 Feature flags

Mechanizm rollout per cohort (alpha, beta, % users, plan). Implementacja: tabela feature_flags(name, value_json, audience_filter) + endpoint GET /api/me/flags. Przykłady flagów:

Spójność z apką — admin panel kompletnie poza nią Admin panel to osobna aplikacja, nie część agro360-mvp2.html. Może być stack tym samym co główna apka, ale deployment osobny (osobne repo lub osobny subdomain w monorepo). Klient SaaS nie powinien móc nawet wykryć że panel istnieje.
Bezpieczeństwo admin panelu — najwyższy priorytet Wyciek dostępu = katastrofa (dane wszystkich klientów). Minimum: (a) osobny subdomain, (b) IP whitelist (biuro + VPN), (c) obowiązkowe 2FA dla wszystkich adminów, (d) sesja max 8h, (e) każda akcja w audit log, (f) 2-person approval dla destructive (delete account), (g) regularne audyty kto ma dostęp + revoke przy odejściu z firmy.
Pomysł — „Health score" per gospodarstwo Dla każdego klienta wyliczyć score 0-100 na podstawie: częstotliwość logowania, # zabiegów ostatnio, # users aktywnych, błędy płatności, NPS jeśli mierzony. Lista „at risk" → sales/success może proaktywnie zadzwonić zanim klient zrobi churn. Standard w SaaS, niedrogi do dorobienia.
Pomysł — wbudowany helpdesk vs Intercom/Crisp Można zacząć z zewnętrznym (Crisp — darmowy plan na start, polskie wsparcie), później rozważyć wbudowany jeśli wolumen rośnie. Plus zewnętrznego: gotowe chat widget, AI assistant, mailing. Plus własnego: dane klientów u nas, brak miesięcznych opłat. Na start: Crisp.
RODO — gdy admin ogląda dane klienta, to przetwarzanie Każde wejście admina w dane konkretnego klienta to przetwarzanie danych osobowych. Wymóg: (a) zapisać po co (ticket #1234), (b) notyfikować klienta po fakcie (opcjonalnie, ale dobre praktyki), (c) w polityce prywatności jasno opisać kiedy support może czytać dane (tylko na zgłoszenie klienta). Konsultacja prawna.

11. Edge cases i error handling Gotowe

Każdy edge case nieobsłużony to wycieczka klienta do konkurencji. Ta sekcja katalogizuje wszystkie scenariusze „co jeśli" zidentyfikowane w sekcjach 1-10 plus te specyficzne dla naszej branży (offline w polu, kontrola ARiMR „za 30 minut", BLIK się skończył w żniwa).

11.1 Auth & dostęp

ScenariuszZachowanie
Zapomniane hasłoEmail z magic link (ważny 1h) → ustaw nowe hasło → auto-login. Rate limit: 3 prośby / godzinę / email.
Wpisałem zły email przy rejestracjiKonto nie zostanie zweryfikowane → wygasa po 7 dniach → email zwolniony. User może zarejestrować się ponownie z poprawnym.
Email weryfikacyjny nie dochodzi[Wyślij ponownie] z rate limit 1x / 60s. Po 3 próbach sugestia: „Sprawdź spam / dodaj noreply@agro360.pl do kontaktów / skontaktuj się z supportem"
2FA — straciłem telefonWpisanie jednego z 10 kodów zapasowych (wygenerowanych przy włączeniu 2FA). Brak kodów = ticket do supportu z weryfikacją tożsamości (dowód, selfie).
Konto przejęte (phishing)User dzwoni do supportu → support weryfikuje (telefon zapisany w profilu) → reset hasła + 2FA + audit log (sprawdzić co zrobiono z konta) → opcjonalnie reverse zmiany.
Próba logowania z innego krajuEmail „nowe logowanie z [kraj/miasto]" + opcjonalny block (Enterprise feature). Standard: pozwól ale alertuj.
Brute force loginuPo 5 nieudanych: CAPTCHA. Po 10: lockout konta na 15 min + email do właściciela.
Wygaśnięcie sesji w trakcie pisania zabieguAuto-save draftu lokalnie → po re-login wraca do tego samego formularza z danymi.

11.2 Offline i sieć

Offline-first to wartość rdzeniowa — Tomek w polu nie ma zasięgu, ale chce wpisać zabieg. Strategia:

Architektura offline (Service Worker + IndexedDB)

  1. Aplikacja jako PWA — manifest, Service Worker cache'uje JS/CSS/HTML
  2. Dane lokalnie w IndexedDB — pełna kopia gospodarstwa usera (nie tylko cache, ale source-of-truth lokalnie)
  3. Mutacje w kolejce — gdy user dodaje zabieg offline: zapis do IndexedDB + dodanie do sync_queue
  4. Sync gdy wraca sieć — Service Worker wykrywa online → wysyła kolejkę → backend zwraca konflikty → resolver (patrz 11.3)
  5. UI indykator — banner u góry: „🟢 online" / „🟡 offline — 3 zmiany w kolejce" / „🔴 sync error - sprawdź"

11.3 Kolizje danych (concurrent edits)

Persona Tomek wpisuje zabieg offline, pracownik Marek równolegle online wpisuje inny zabieg na tym samym polu. Co dalej?

KonfliktResolver
Dwa zabiegi na tym samym polu w tym samym dniu (różne typy)Brak konfliktu — oba zapisują się (mogą być różne)
Dwa identyczne zabiegi (ten sam typ, te same preparaty, ten sam dzień)Backend wykrywa duplikat → wraca alert „prawdopodobnie dublujecie się — pokaż oba" → user decyduje
Edycja tego samego pola (np. zmiana powierzchni)Last-write-wins + notyfikacja drugiej osoby „Anna zmieniła powierzchnię Pole #3 z 12.5 na 13.0 ha"
Magazyn — dwóch ludzi odejmuje z tego samego produktuAtomowy UPDATE z WHERE qty >= X w bazie. Jeśli drugi przegrał (qty < X po pierwszym) → alert „brak X kg w magazynie, ktoś już odjął"
Usunięcie pola na którym ktoś właśnie wpisuje zabiegBackend reject, frontend: „To pole zostało usunięte przez [Anna]. Wybierz inne lub przywróć pole"

11.4 Billing edge cases

ScenariuszZachowanie
Karta wygasłaEmail 30 dni przed wygaśnięciem (Stripe Card Updater) + przypomnienie w aplikacji
BLIK nieudany (limit, brak akceptacji w 60s)Retry zgodnie z dunning sequence (1d/3d/5d/7d) + email z linkiem do ponownej próby
Klient zapłacił przelewem ręcznie (poza Stripe)Admin może oznaczyć fakturę jako „paid manually" → przedłuża subskrypcję o okres
Refund (klient żąda zwrotu w trakcie miesiąca)Pro-rated refund (Stripe oblicza automatycznie). Jeśli > 200 zł — wymaga super-admina (sekcja 10)
Klient anulował, ale wrócił po 60 dniachDane jeszcze są (12 mies retention). Reactivate konto, nowy okres rozliczeniowy. Trial nie odnawia się.
Klient anulował, wrócił po 18 miesiącachDane usunięte. Pełna nowa rejestracja, nowy trial 30 dni (rozsądnie, nie blokujemy returnera).
Klient stwierdza „nie zamawiałem, blokuje płatność"Stripe Dispute → my mamy 7 dni na ripostę z dowodami (logi loginu, audit log, faktury PDF) → Stripe decyduje. Loss = chargeback fee 15-25 €.

11.5 Dane i magazyn

ScenariuszZachowanie
User wpisał zabieg z dawką znacznie wyższą niż dozwolonaSoft warn: „Dawka 5 l/ha to 3x więcej niż etykietowa max 1.6 l/ha. Czy na pewno?" [Tak / Popraw]
Magazyn w minusie (wpisał więcej niż jest)Soft warn: „Po tym zabiegu w magazynie będzie −12 kg. Sprawdź stan." [Zapisz mimo to / Popraw]
Praca polowa wpisana w przyszłości (data > dziś)OK — to plan, oznaczany jako 'planowany'. Konwertowany na 'wykonany' po dacie.
Praca polowa wpisana w dalekiej przeszłości (> 3 lata wstecz)Soft warn: „Wpisujesz datę 2022. Na pewno?" — czasem ma sens (importują historię)
Mieszanina ŚOR z niekompatybilnymi preparatamiBackend sprawdza w katalogu (przyszła funkcja) → alert „Artea + Roundup — nie zalecane łączenie wg etykiety" [Zapisz mimo to / Usuń jeden]
Eksport JSON dużego gospodarstwa (500 zabiegów, 50 MB)Generowanie async w background → email z linkiem gdy gotowe (ważny 24h)
Import JSON z błędnym schematemWalidator pokazuje line-by-line co nie pasuje → user koryguje i wgrywa ponownie

11.6 Integracje z zewnętrznymi serwisami

SerwisCo jeśli padnie
Stripe downPłatności kolejkowane → retry. Klienci nie powinni stracić dostępu nawet przy 24h przerwie Stripe.
Email provider (Resend/Postmark) downFallback na drugi provider (Sendgrid backup). Kolejka emailowa nie ginie.
Pogoda API (IMGW / OpenWeather) downUI pokazuje „Dane pogodowe niedostępne — sprawdzimy później". Nie blokuje reszty.
MATIF / notowania API downPokaż ostatnio znane + znacznik „dane sprzed Xh". Nie blokuje reszty.
Supabase / DB down (rzadkie ale możliwe)Aplikacja PWA z lokalnymi danymi nadal działa READ-ONLY z IndexedDB. Mutacje w kolejce do sync.
OCR faktury (jeśli dodamy)Fallback: user wpisuje ręcznie + retry OCR w tle.

11.7 Branżowe edge cases (specyficzne dla rolnictwa)

ScenariuszZachowanie
Pole dzielone na sezony — pszenica ozima + poplonModel: pole ma wiele upraw w czasie (history). Aktualna uprawa = ostatnia, historia widoczna w szczegółach.
Pole wynajęte / oddane innej osobieSoft delete + flaga „dzierżawione komuś" + opcjonalne udostępnienie read-only dzierżawcy (rozszerzenie ról z s.6).
Kontrola ARiMR „za 30 minut, daj papier"Killer feature: przycisk „Pakiet kontrolerski" w 1 kliku (sekcja 9 — Pomysł). PDF off-line dostępny zawsze, nawet bez internetu w polu.
Zmiana sezonu (1 września przejście na nowy rok agronomiczny)Automatyczny przegląd: „Sezon 2025/2026 się skończył. Zarchiwizuj uprawy? Przygotuj plany na 2026/2027?" — wizard na start sezonu.
Wycofanie środka ŚOR z rejestru (zmiana w prawie)Katalog sor_catalog aktualizowany przez super-admina. Gdy preparat wycofany: oznaczenie w magazynie + alert „Bumper 250 EC wycofany z rejestru od 30.06.2026 — zużyj do tej daty".
Klęska żywiołowa, susza, grad — strata uprawyMożliwość oznaczenia uprawy jako „strata całkowita" + dokumentacja (zdjęcia) — przyda się do wniosku o pomoc.
Wymiana sprzętu (sprzedaż ciągnika) w trakcie sezonuMaszyny — moduł na przyszłość. Edge: historia zabiegów z tym ciągnikiem zostaje (historia jest immutable).

11.8 Globalna obsługa błędów — wzorce UI

Apka dziś — minimum error handlingu Apka agro360-mvp2.html ma głównie happy path. try/catch sporadycznie, brak globalnego error handlera, brak loading states (bo localStorage jest synchroniczny). Migracja do SaaS = zero asynchroniczności staje się 100%. Każdy JSON.parse(localStorage.X)await api.X(). To wymaga wprowadzenia: loading states, error states, retry logic, optimistic updates. Wcale niemały refaktor — patrz s.5 i s.12.
Offline-first — to nie jest feature, to architektura Robienie aplikacji offline-first po zbudowaniu wersji online jest 5x trudniejsze niż od razu. Decyzja: czy MVP SaaS robimy od razu jako PWA z IndexedDB, czy najpierw online-only (szybciej), a offline w v2. Trade-off: szybciej do rynku vs nie psucie obietnicy „offline" z landingu. Rekomendacja: MVP online-only, ale architektura przygotowana (data layer ma jeden interface, można podmienić na offline-capable). Decyzja w s.12.
Audit (#3 powtórnie) — sekcja 11.2 musi się uspójnić z s.1 i s.2 11.2 mówi „offline-first to wartość rdzeniowa" i opisuje pełną architekturę PWA + IndexedDB. Ale jednocześnie własna notatka „MVP online-only" i s.12.5 explicite odkłada offline na fazę 2. Trzy sekcje mówią trzy różne rzeczy. Decyzja z audit #3 musi być propagowana tutaj. Jeśli MVP online-only — przepisać 11.2 jako „Plan offline-first (faza 2)". Jeśli MVP offline-first — usunąć z 12.5 i zwiększyć estymaty fazy 1 o ~3 tyg.
Audit #16 — BRAK: metryki kanału agronoma Wszystkie sekcje opisują persona Marta i jej rolę afiliacyjną (1.2, 6.7 pomysł, s.8 kupony), ale w metrykach (s.10.3, s.12.8) brak liczb mierzących czy ten kanał działa:
  • Liczba aktywnych agronomów (with ≥ 1 active client farm)
  • Liczba gospodarstw na agronoma (mediana / max)
  • MRR sprowadzone przez kanał afiliacyjny (% całości)
  • Conversion rate: zaproszenie agronoma → akceptacja
  • Churn klientów-rolników z agronomem vs bez (hipoteza: agronom = niższy churn)
Bez tych metryk pomysł afiliacji (6.7) jest tylko marzeniem. Dodać do dashboardu admina (10.3) i do KPI fazy 2 (12.8).
Pomysł — „tryb żniw" z uproszczonym UI W żniwa rolnik jest zmęczony, ekran telefonu zakurzony, słońce pali. Dodać przełącznik „Tryb żniw" — UI z mega-przyciskami, kontrastowymi kolorami, max 3 akcje na ekran. Wszystko zoptymalizowane pod jedną rękę. Może też tryb głosowy („wpisz zabieg na pole Tomasza Pole, 30 l Roundupa").
Pomysł — proaktywne alerty pogodowe „Jutro w nocy mróz -3°C. Czy zabezpieczyć uprawy?" / „W piątek deszcz, dziś byłby ostatni dzień na opryskiwanie." Integracja IMGW + reguły agronomiczne. Killer feature dla retencji.

12. Roadmap implementacji Gotowe

Sekcja sumuje wszystkie wcześniejsze ustalenia w konkretny plan działania. Założenia: jedna osoba (Adam) + Claude jako pair, iteracyjnie, fragmentarycznie. Cel: pierwszy płacący klient w 4-6 miesięcy od decyzji „budujemy".

12.1 Stack technologiczny — finalne decyzje v2.0 (greenfield, audyt #17 + #18 RESOLVED)

WarstwaDecyzja v2.0Dlaczego
Frontend frameworkReact 18 + TypeScript + ViteGreenfield build (prototyp Przemka jest specyfikacją domenową, nie code base). React = największy ekosystem, najwięcej devów, długoterminowy bet.
RoutingReact Router v6+Standard, deep linking, code splitting
StanTanStack Query (server state) + Zustand (UI state)Query załatwia 90% potrzeb (cache, retry, optimistic updates), Zustand do reszty (modale, filters)
Design systemTailwind CSS + shadcn/ui + Lucide iconsshadcn = komponenty kopiujesz do repo (pełna kontrola, brak vendor lock-in), Tailwind = szybkość, Lucide = spójne ikony
Design tokensCSS custom properties (z palety prototypu: #4a7c2c, #2d5016)Zachowanie wizualnej tożsamości AGRO 360 z prototypu
FontInter (latin-ext dla PL znaków)Bezpłatny, czytelny, wszystkie wagi, self-host
FormsReact Hook Form + ZodPerformance, walidacja type-safe, mała kanapka
Build & PWAVite + vite-plugin-pwa (manifest, basic SW), pełne offline w fazie 2Vite szybszy od CRA/Webpack, plugin daje fundamenty PWA
Hosting frontuVercel (preferowane) lub Cloudflare PagesVercel ma lepsze preview deploys per PR, Cloudflare tańsze przy skali. Start: Vercel.
Backend + DB + AuthSupabase (PostgreSQL + Auth + Storage + Realtime)Najszybciej do MVP, RLS gotowy, hosting EU (Frankfurt). Self-host na backupie.
API layerSupabase client SDK + osobny BFF (Hono na Cloudflare Workers) dla logiki niestandardowej (Stripe webhooks, generacja PDF, OCR)SDK do CRUD, BFF do operacji wymagających sekretów / orchestration
PDF generationKlient-side: react-pdf (MVP) → server-side: Puppeteer w Cloudflare Workers (faza 2)MVP: prosta generacja po stronie klienta. Faza 2: pixel-perfect z asetami
PłatnościStripe + Przelewy24 jako payment method w StripeNajlepsze subskrypcje (Stripe) + BLIK/przelewy PL (P24 w Stripe)
Email transakcyjnyResend (primary), Postmark (fallback)Świetne deliverability, polskie hosting EU, dev experience
Email marketingResend Audiences (start) → ConvertKit (gdy > 500 subskrybentów)Resend Audiences darmowy, ConvertKit ma lepsze sekwencje retencji
SMSSerwerSMS.pl / TwilioSerwerSMS taniej w PL, Twilio bardziej niezawodny — start na SerwerSMS
Error trackingSentry (free tier)Standard, free do 5k events/mies
AnalyticsPlausible (RODO-friendly) + PostHog (events / funnele)Plausible do podstawowych metryk, PostHog do retention cohortów
HelpdeskCrisp (start) → wbudowane (gdy > 100 ticketów/mies)Free na start, wystarczające na MVP
Status pageBetter StackTransparentność dla klientów, alerty SMS dla on-call
CI/CDGitHub Actions + Vercel preview deploysKażdy PR → preview URL, CI uruchamia testy + lint + a11y
TestingVitest (unit) + Playwright (E2E)Standard React/TS, Playwright cross-browser
Mapy (pola)OpenStreetMap + Leaflet (MVP) → ARiMR API (Pro/Enterprise)Free na start, integracja gov-owa później
PogodaOpenWeather (start) → IMGW (gdy stabilne)OWM ma free 1000 calls/dzień, IMGW niedeterministyczne API
RepoMonorepo (Turborepo) — apps/web, apps/admin, apps/landing, packages/ui, packages/typesWspółdzielenie komponentów, jeden CI, jeden lockfile

Łączny stack to ~12-15 zewnętrznych zależności. Większość ma free tier wystarczający na pierwsze 6 miesięcy. Szacunkowy koszt miesięczny po pierwszych 50 klientach: ~120-180 zł (Supabase Pro $25, Stripe transakcje, Resend pro $20, Sentry hobby, reszta free).

12.2 Faza 0 — Przygotowanie (2 tygodnie)

12.3 Faza 1 — MVP SaaS greenfield build (14-16 tygodni)

Cel: Pierwsze 10 płatnych gospodarstw + 2 aktywnych agronomów. Wszystko inne odpuszczamy. Estymata wyższa niż w v1.0 (była 8-10 tyg) — bo greenfield build = wszystko od zera, nie refaktor.

gantt
    title Faza 1 — MVP SaaS greenfield (~14-16 tygodni)
    dateFormat YYYY-MM-DD
    section Setup
    Monorepo + design system (Tailwind+shadcn) :s1, 2026-06-01, 5d
    Supabase setup + schema + RLS              :s2, 2026-06-01, 7d
    Vercel hosting + CI/CD                     :s3, after s1, 3d
    section Auth & Multi-tenancy
    Auth UI (rejestracja, login, reset)        :a1, after s2, 7d
    Membership model + role gating             :a2, after a1, 5d
    Switcher gospodarstw + invitations         :a3, after a2, 7d
    section Core Modules
    Pola — CRUD + lista + szczegóły            :c1, after s3, 7d
    Magazyn — 3 typy + alerty + auto-odejmowanie :c2, after c1, 10d
    Prace polowe — formularz uniwersalny       :c3, after c2, 14d
    Mieszaniny ŚOR + kolejność WG/SC/EC/SL     :c4, after c3, 7d
    Faktury + koszty + dashboard               :c5, after c4, 10d
    Raporty PDF (klient-side, pakiet kontroler) :c6, after c5, 7d
    section Onboarding & Retention
    Onboarding wizard A + B                    :o1, after a3, 7d
    Post-onboarding journey (emaile)           :o2, after o1, 5d
    Empty states + skeleton loaders            :o3, after c1, 5d
    section Billing
    Stripe integration + plany + checkout      :b1, after c5, 7d
    Subscription panel + dunning + faktury VAT :b2, after b1, 7d
    section Landing & Launch
    Landing page (Next.js static)              :l1, 2026-06-01, 14d
    Beta testers (5-10) feedback loop          :l2, after b2, 14d
    Smoke testy + monitoring + go-live         :l3, after l2, 7d
    

12.4 Faza 1 — checklist szczegółowy (greenfield)

#ZadanieOdp. sekcjaEstymata
1Monorepo (Turborepo) + design system base (Tailwind config, shadcn init, tokens z palety prototypu, Inter font)s.12.15 dni
2Supabase: schemat tabel (Users, Memberships, Farms, Fields, ChemWarehouse, SeedWarehouse, GrainWarehouse, WorkHistory, Invoices, Subscriptions, AuditLog, sor_catalog) + RLS policiess.71 tydz
3Landing page (Next.js static): 9 sekcji, analytics Plausible, cookie banners.22 tyg (równolegle)
4Auth UI: rejestracja + weryfikacja email + login (email/hasło + Google OAuth) + reset hasła + magic link (Supabase Auth)s.31 tydz
5Multi-tenancy: currentFarmId context, RLS enforcement w API client, switcher gospodarstw w top barzes.6, s.71 tydz
6Membership: zaproszenia (email z tokenem), akceptacja, role gating w UI + backend, matrix uprawnieńs.61 tydz
7Onboarding wizard A (founder, 5 kroków) z aha momentem na kroku 4s.41 tydz
8Onboarding wizard B (zaproszony user, 3 ekrany)s.4.103 dni
9Moduł Pola: CRUD, lista, szczegóły, dodawanie ręczne (mapy w fazie 2)s.5.51 tydz
10Moduł Magazyn: 3 typy (zboże, chemia, nasiona), alerty progowe, auto-odejmowanie przy zabiegus.5.41.5 tyg
11Moduł Prace polowe: formularz uniwersalny (8 typów), kalkulacja kosztów zł/ha, persystencjas.5.32 tyg
12Mieszaniny ŚOR: multi-add, sortowanie WG/SC/EC/SL, walidacja numerów zezwoleń, koszt sumarycznys.5.41 tydz
13Moduł Faktury: dodawanie ręczne, kategoryzacja, link do zabiegóws.51 tydz
14Moduł Koszty: agregacja z zabiegów i faktur, dashboard, filtry per uprawa/pole/datas.54 dni
15Dashboardy: ownerDashboard, workerDashboard, agronomDashboard (s.6.8), accountantDashboards.5, s.6.81.5 tyg
16Raporty PDF klient-side (react-pdf): pakiet kontrolerski ARiMR (Pro feature, brak w trialu)s.91 tydz
17Stripe: konfiguracja planów (Pro mies/rok, Agronom Pro), checkout, webhook handler w Cloudflare Workers.81 tydz
18Subscription panel: aktualny plan, metoda płatności, faktury VAT, anulowanies.85 dni
19Dunning: webhook payment_failed → email sequence (1d/3d/5d/7d), banner w apce, read-only modes.84 dni
20Ustawienia konta vs gospodarstwa (rozdzielenie zgodnie z s.9), flow usunięcia konta z obsługą jedynego właścicielas.91 tydz
21Eksport/import JSON gospodarstwa (RODO Art. 20)s.9.83 dni
22Email transakcyjny (Resend): templates dla 12 events (welcome, weryfikacja, reset, zaproszenie, dunning x4, retencja x4)s.4.111 tydz
23Post-onboarding journey: 9 touchpoints w 30 dni trialu (scheduler w Cloudflare Cron Triggers)s.4.114 dni
24Empty states + skeleton loaders + retry buttons + globalny error boundarys.11.81 tydz
25Smoke testy E2E (Playwright): 5 najważniejszych flowów (login, onboarding, wpisanie zabiegu, generacja PDF, billing webhook)s.10.8.21 tydz
26Monitoring: Sentry + Better Stack uptime + Crisp helpdesks.10.63 dni
27Beta testers (5-10 osób z grupy docelowej, w tym Przemek) — feedback loop 2 tyg2 tyg (równolegle)

Łącznie: 27 zadań × średnio 5-7 dni roboczych = ~140-180 person-days = 14-16 tygodni dla solo foundera (Adam) lub 8-10 tygodni dla pary (Adam + 1 dev).

Audit #17 — ZMIANA SCOPE: po decyzji greenfield, Faza 1 to nie „migracja" Tabela 12.4 ma pozycje sugerujące migrację istniejącej apki: „Migracja modułów apki na nowy data layer" (#7), „Migrator z lokalnej apki na SaaS" (#14), „Refaktor data layer (localStorage → API)" (#6). Po decyzji greenfield te pozycje znikają lub zmieniają charakter:
  • #6 „Refaktor data layer" → nowa pozycja: „Implementacja warstwy danych (API client, cache, error handling) od zera"
  • #7 „Migracja modułów" → „Implementacja modułów core: pola → magazyn → prace polowe → koszty → faktury — każdy jako fullstack feature (UI + API + DB)". Estymata WIĘKSZA (3-5 tyg zamiast 2-3), bo to nie refaktor a budowa.
  • #14 „Migrator z lokalnej apki" → opcjonalne, dla istniejących userów lokalnej apki którzy chcą przenieść dane. Niski priorytet w MVP, lepiej w fazie 2.
  • Gantt diagram (12.3) trzeba przeliczyć — sumarycznie faza 1 prawdopodobnie 12-16 tyg zamiast 8-10.
Plus, sekcja 12.1 (stack) — wybór „Vanilla JS" był uzasadniony „nie chcemy wyrzucać 9700 linii". Po decyzji greenfield ten argument znika. Rekomendacja stacku frontu na greenfield: React + TypeScript + Tailwind + shadcn/ui (lub Svelte/SvelteKit — równie dobry, mniejszy boilerplate).
Audit #18 — BRAK w stack: design system Tabela 12.1 ma „Hosting", „Backend", „Płatności" itd. — ale nie ma design systemu, który dla greenfield buildu jest pierwszą decyzją techniczną. Bez tego każdy przycisk będzie wyglądał inaczej. Opcje:
  • Tailwind + shadcn/ui — gotowe komponenty, łatwa customizacja, najszybciej do MVP. Rekomendacja.
  • Mantine / MUI / Chakra — bardziej opinionated, mniej elastyczne
  • Własny design system od zera — najwięcej kontroli, najwięcej pracy. Tylko jeśli mamy designera full-time.
Plus tokens (kolory, spacing, typografia) — wziąć z istniejącej apki (zielona paleta #4a7c2c / #2d5016) i sformalizować w pliku tokens (CSS vars / Tailwind config). Ikony: Lucide (otwarte, spójne) lub Phosphor. Font: Inter (bezpłatny, czytelny, polskie znaki).

12.5 Faza 1 — co świadomie NIE robimy

12.6 Faza 2 — Wzrost i polerka (10-14 tygodni)

Cel: 100+ płatnych gospodarstw, NPS > 40, zero blokerów do skalowania.

12.7 Faza 3 — Enterprise i integracje (długoterminowo)

12.8 Metryki sukcesu per faza

FazaKluczowe metrykiTargety
Faza 1 (MVP) Liczba beta testerów aktywnych, trial → paid conversion, time-to-aha-moment 10 płatnych gospodarstw, >25% conversion z trialu, <15 min onboarding
Faza 2 (Wzrost) MRR, churn, NPS, organiczny ruch na landing 5000+ zł MRR, <5% mies churn, NPS > 40, 1000+ unique/mies na landing
Faza 3 (Enterprise) ARR, # enterprise contracts, ARPU 100k+ zł ARR, 3+ enterprise klientów, ARPU > 70 zł

12.9 Ryzyka i mitigacja

RyzykoPrawdopodobieństwoWpływMitigacja
Nikt nie chce płacić — rolnicy nie SaaS-peopleŚrednieKrytycznyWalidacja w fazie 0: rozmowy z 10-20 rolnikami przed kodem. Jeśli „za drogo / nie potrzebuję" — pivot.
Konkurencja (eDWIN, SatAgro) wyprzedzi z polskim UINiskieŚredniTrzymać się obietnicy „prostota i polskie realia"
Refaktor vanilla JS okaże się większy niż myśleliśmyŚrednieŚredniTime-box: jeśli faza 1 punkt 6+7 zajmie > 6 tyg, rozważyć cięcie scopu (np. najpierw tylko 'pola' migrujemy, reszta na potem)
Supabase okaże się za drogi / wolny / lock-inNiskieŚredniSchema PostgreSQL — łatwo zmigrować na własny self-host gdy będzie sens
RODO / podatki / regulacje rolnicze utrudnią startŚrednieWysokiPrawnik na pokładzie od fazy 0. Status „beta" pozwala na uproszczone obowiązki.
Stripe / Przelewy24 odrzuci nasz typ biznesuNiskieKrytycznyWalidacja w fazie 0 (rozmowa z merchant supportem przed pełnym onboardingiem)
Burnout solo founder (Adam)ŚrednieKrytycznyPair z Claude, automatyzacja, mówić „nie" featurom poza scopem, regularny czas off

12.10 Kolejność akcji następnego tygodnia (very next)

  1. Walidacja: 5 rozmów z prawdziwymi rolnikami z grupy docelowej. Pytania: czy płaciliby 49 zł/mies? Co byłoby killer feature? Co dzisiaj robią z ŚOR?
  2. W parallel: fix bugów (fieldWorkHistory persystencja, seed data spójność, nazwa paymentsPanel)
  3. Po rozmowach: aktualizacja sekcji 1 (persona) i 1.6 (model cenowy) na podstawie feedbacku
  4. Decyzja go/no-go fazy 0 → 1
  5. Jeśli go: rejestracja firmy + Supabase setup (równolegle)
Spójność z dokumentem — wszystkie sekcje są zlinkowane Roadmap odsyła do konkretnych sekcji (s.X) — każde zadanie z fazy 1 ma uzasadnienie w odpowiedniej sekcji. Dokument jest spójny: persona → flow → architektura → plan działania.
Najważniejsze ryzyko — walidacja przed kodem Wszystkie założenia w tym dokumencie (cena, persona, value prop, scope) to tezy, nie fakty. Bez 10-20 rozmów z prawdziwymi rolnikami przed Fazą 1 ryzykujemy zbudowanie czegoś czego nikt nie chce. To jedyny absolutnie obowiązkowy krok przed jakąkolwiek linijką kodu produkcyjnego.
Pomysł — co-builder / pilotażowi rolnicy Zamiast tylko ankietować, zaprosić 3-5 rolników do pełnego pilotażu z konkretną relacją: dostają darmowy dożywotni Pro za regularne sesje feedbackowe (1h / 2 tyg). Stworzą bazę testimonials, ich problemy stają się naszym backlogiem. Niski koszt, ogromna wartość PMF.
Pomysł — open-source komponenty Niektóre części (kalkulator MTZ, baza ŚOR, parser etykiet) mogą być open-source. Korzyść: SEO (każdy widok kodu = link), PR (nowi dev kontrybuują), nikomu nie szkodzi (nasza wartość jest w SaaS layer i danych klientów, nie w samym katalogu ŚOR).

13. Notatki dla Przemka — co weryfikujesz jako rolnik v2.0

Przemek — Ty jesteś autorem prototypu agro360-mvp2.html i to dzięki Tobie wiemy że logika agronomiczna działa. Cała reszta dokumentu to nasza propozycja przekształcenia tego w pełnoprawny SaaS. Ta sekcja jest specjalnie dla Ciebie — zostawiamy listę konkretnych pytań na które tylko rolnik może odpowiedzieć rzetelnie. Twoje „nie tak" zaoszczędzi nam tygodnie pracy.

13.1 Persona główna — czy Tomek jest realny?

Opisaliśmy Tomka (s.1.1): 42 lata, 60-150 ha, własny ciągnik + opryskiwacz, kombajn często wynajmowany, 0-2 stałych pracowników, smartfon Android, Excel na poziomie podstawowym, korzysta z Top Agrar / Agrofakt.

13.2 Persona Marta (agronom) — czy ma sens?

Założyliśmy że doradcy agronomiczni (firmy chemiczne, niezależni doradcy) obsługują 10-30 rolników i chętnie zapłacą 99 zł/mies za apkę z dostępem do danych klientów.

13.3 Cena Pro 49 zł/mies — sweet spot?

Zakładamy 49 zł/mies za gospodarstwo (490 zł/rok). Dla Tomka 60-150 ha to ok 0.5-0.8 zł/ha/mies — czyli koszt 4-5 litrów Roundupa rocznie.

13.4 Value proposition — czy to TO?

Powtarzamy 3 obietnice (s.1.5):

  1. Rejestr ŚOR pod kontrolę ARiMR w jednym kliku (PDF do druku)
  2. Koszty zł/ha per uprawa automatycznie
  3. Magazyn który sam się odlicza

13.5 Mieszaniny ŚOR — kolejność WG/SC/EC/SL

W prototypie zaimplementowałeś sortowanie mieszanin wg formulacji (WG → SC → EC → SL). To jest jedna z naszych „kopiujemy 1:1" decyzji (s.5.4).

13.6 Lista preparatów ŚOR (sor_catalog)

Prototyp ma 12 preparatów hardcoded. Plan: rozszerzyć do 100+ w MVP i aktualizować co kwartał z gov.pl.

13.7 Sezonowość — czego nie wziąłem pod uwagę?

Rolnictwo to silnie sezonowy biznes. W dokumencie wspominamy „tryb żniw" (s.11), zmiana sezonu 1 września (s.11.7), klęski żywiołowe.

13.8 Operatorzy w gospodarstwie — kto naprawdę wpisuje dane?

Założyliśmy 4 role (s.6.1): Właściciel, Współwłaściciel, Pracownik, Agronom. Plus pomysł na Księgową.

13.9 Pakiet kontrolerski — co MUSI zawierać?

Killer feature MVP: PDF pod kontrolę ARiMR/PIORiN.

13.10 Słownik — czy używamy poprawnej terminologii?

Glosariusz (s.0.4) zawiera 25+ terminów. Sprawdź czy używamy tych samych słów co rolnik:

13.11 Czego nie ma a powinno być?

Ten dokument jest naszą hipotezą. Bardzo prawdopodobne że czegoś nie pomyśleliśmy.

13.12 Beta testers — kogo poznasz?

W Fazie 1 (s.12.4) potrzebujemy 5-10 beta testerów z grupy docelowej. To kluczowy zasób.

13.13 Co dalej?

Po Twoich odpowiedziach planujemy:

  1. Aktualizacja dokumentu do v2.1 z Twoimi poprawkami (persona / cena / value prop / terminologia)
  2. Adam zarejestruje firmę i Supabase
  3. Zaczynamy budować Fazę 1 zgodnie z s.12.4 — 27 zadań w 14-16 tygodni
  4. Po 8 tygodniach masz pierwszy zalogowalny SaaS do potestowania
  5. Po 14-16 tygodniach launch z bety z 5-10 rolnikami
Dzięki za prototyp, Przemek. Bez Twojej wizji to byłoby teoretyzowanie. Z Twoją wizją — mamy specyfikację działającą na żywym organizmie, z prawdziwą logiką rolniczą i polskimi realiami. Twoja walidacja tej sekcji to ostatni krok przed kodem.