Laravel + Vue.js: jak budujemy panele, CRM i aplikacje B2B
Autor:
Paweł Matusiak
·
Dedykowany CRM nie musi wyglądać jak relikt z 2010 roku. Laravel daje solidny backend i API, Vue.js — szybki, nowoczesny interfejs. Tak powstają systemy, z których zespół naprawdę korzysta na co dzień.
Gotowy CRM obiecuje wszystko. W praktyce zespół i tak trzyma prawdę w Excelu, bo pola nie pasują, a raport wymaga trzech eksportów. Dedykowany panel na Laravel + Vue.js odwraca tę logikę: najpierw proces firmy, potem ekrany. Interfejs jest tak prosty, jak pozwala na to prawdziwa praca — nie odwrotnie. Nie budujemy kombajnu z tysiącem checkboxów. Budujemy drogę od zapytania do faktury, od rezerwacji do SMS-a, od WZ do stanu magazynu — i dopiero potem ozdoby.
To ten sam stack, który opisujemy na technologiach i w tekście dlaczego Laravel na aplikacje biznesowe. Backend jest jeden. Frontów może być kilka: panel Vue, strona klienta, Android na tym samym API. Nie dublujemy reguł rabatów w trzech miejscach. Poniżej: architektura, co najczęściej stawiamy, jak pilnujemy ról i raportów, i jak wygląda projekt od środka — z Git i 6 miesiącami gwarancji na końcu, nie z kodem zamkniętym w czyjejś chmurze.
Architektura, która się broni
Backend Laravel wystawia REST API. Vue.js (Vite, Pinia) jest frontendem panelu: tabele, filtry, formularze, dashboardy. Dzięki temu to samo API może obsłużyć aplikację Android, integrację z innym systemem albo sklep na osobnej domenie. Walidacja i policies żyją po stronie serwera. Vue nie jest źródłem prawdy o tym, czy wolno usunąć fakturę — jest interfejsem. Ukryty przycisk nie jest uprawnieniem. To A01 z OWASP w praktyce panelu.
Na serwerze: Nginx, PHP 8, MySQL albo PostgreSQL, Redis na cache, sesje i kolejki. Ciężkie rzeczy — generowanie PDF, wysyłka maili, import 20 tysięcy SKU — idą do kolejki, a nie blokują kliknięcia użytkownika. Harmonogram (przypomnienia, przeterminowane oferty, stany minimalne) jest w kodzie. Panel webowy loguje się sesją / cookie Sanctum z CSRF; Android tokenem, który da się unieważnić. Szczegóły w logowaniu i 2FA.
Co najczęściej budujemy w tym stacku
- CRM: kartoteka klientów, szanse, zadania, historia kontaktu, uprawnienia zespołu, notatki bez pola na wszystko.
- Panele B2B: indywidualne cenniki, zamówienia hurtowe, faktury, statusy dostaw, limity kredytowe.
- Rezerwacje i terminarze: zasoby, personel, powiadomienia mail/SMS, zaliczki, synchronizacja kalendarza.
- Magazyn i WZ/PZ: stany, lokalizacje, skaner w aplikacji Android, alerty minimum, historia ruchów.
- Portale klienta: zgłoszenia, dokumenty, płatności, status realizacji — bez konta biuro po stronie klienta.
Role, które odzwierciedlają firmę
Właściciel widzi marżę. Handlowiec — swoich klientów. Magazyn — wydania. Księgowość — dokumenty. Laravel policies pilnują tego po stronie API, nie tylko przez ukrycie przycisku w menu. To samo API odrzuci sprytne wywołanie z innej przeglądarki. Wspólne konto nie przechodzi — inaczej nie ma audytu, nie ma offboardingu, nie ma RODO. Test handlowiec nie pobierze płac jest na CI, nie na zaufaniu.
Raporty, które nie bolą bazy
Dashboard na żywo liczy to, co musi: dzisiejsze zamówienia, wąskie gardła, alerty. Ciężkie raporty dziennie/tygodniowo lądują w Redis albo w tabeli zagregowanej, odświeżanej zadaniem w tle. Dzięki temu panel nie zwalnia w piątek po południu, gdy wszyscy klikają eksport do Excela. Eksport dużej bazy wymaga uprawnienia i często 2FA — to nie jest link w stopce dla każdego.
Jak wygląda projekt od środka
- Analiza procesów i szkic ekranów — zanim napiszemy model danych. Ustalamy role, retencję, must-have integracji.
- Prototyp najważniejszego przepływu (np. od zapytania do faktury) na środowisku testowym, na Twoich przykładach.
- Development etapami z podglądem. Zmiana zakresu — pisemnie, z wpływem na termin i kwotę.
- Testy, uprawnienia, kopie, SSL, wdrożenie na serwer klienta. Sanctum, limity logowań, 2FA tam gdzie trzeba.
- Przekazanie Git, dokumentacja, 6 miesięcy gwarancji, opcjonalny pakiet utrzymania.
Nie zaczynamy od pełnego dashboardu z dwunastoma wykresami. Zaczynamy od czynności, bez której firma stoi. Reszta wchodzi, gdy rdzeń żyje. To samo mówimy przy wycenie: Starter i Business na stronie to wizytówka i mały panel, nie cena katalogowa CRM. CRM / B2B z płatnościami i magazynem jest po briefie, etapami.
Dlaczego nie Blade-wszędzie i nie osobny frontendowy kombajn
Proste strony i małe panele da się zrobić w Blade. Gdy zespół klika osiem godzin dziennie w tabele, filtry i formularze, SPA Vue jest szybszy w utrzymaniu i przyjemniejszy w użyciu — pod warunkiem, że API jest jedynym miejscem reguł. Nie dokładamy osobnego BFF, GraphQL i trzech środowisk frontendowych na pierwszy panel dla 12 osób. Vite, Pinia, komponenty tabeli i formularza, jeden design system. Gdy przyjdzie druga aplikacja (portal klienta), korzysta z tych samych endpointów i tych samych polityk.
Kolejki i Redis nie są fanaberią. Są różnicą między panelem, który zamarza przy imporcie, a panelem, który mówi przyjęto, damy znać. PDF faktury, masowy mail, przeliczenie stanów — to workery. Jeśli ktoś obiecuje to samo na tanim hostingu współdzielonym bez kolejki, zapytaj, co się stanie w pierwszy Black Friday. My mówimy to na analizie i wliczamy właściwy serwer albo VPS, nie ukrywamy go w niskiej cenie.
Kiedy tego stacku nie polecamy
Jeśli potrzebujesz bloga i oferty — WordPress albo Starter będzie tańszy. Jeśli gotowy SaaS zjada 90% procesu i umiesz żyć z resztą w Excelu — nie zmuszamy do customu. Jeśli nie ma właściciela procesu po Waszej stronie, najpierw warsztat, nie sprint. Laravel + Vue opłaca się, gdy codziennie ktoś się loguje, gdy reguły są Wasze, gdy integracje nie mieszczą się w wtyczce i gdy kod ma przeżyć zmianę wykonawcy. Wtedy Git nie jest dodatkiem. Jest warunkiem.
Przykłady typów systemów, które tak budujemy, są w inspiracjach. Jeśli widzisz tam coś bliskiego Twojej firmie — albo nie widzisz i właśnie o to chodzi — opisz proces, który chcesz zautomatyzować. Wycena w 24h, bez zobowiązań. Powiemy, czy to mały panel z widełek Business, czy etapowy CRM bez ceny z katalogu.
Model danych zanim powstaną ładne tabele
Najdroższy błąd w CRM na zamówienie to narysować ekrany, a kolumny wymyślić przy kodowaniu. Najpierw: co jest klientem (firma, osoba, lokalizacja), co jest szansą, co jest zamówieniem, co jest dokumentem księgowym. Jeśli hurtownia sprzedaje na NIP, a handlowiec myśli osobami, a magazyn lokalizacjami — to trzy encje, nie jedno pole nazwa. Laravel migracje i relacje zmuszają do tej rozmowy w pierwszym tygodniu. Vue tylko to pokazuje. Źle nazwana tabela wraca jako trzy miesiące roboty przy pierwszym raporcie marży.
Import ze starego Excela projektujemy jako osobny etap, nie jako na końcu wciągniemy. Deduplikacja NIP, śmieciowe telefony, trzy pisownie tej samej firmy — to praca produktowa, nie skrypt na niedzielę. Na teście pokazujemy raport konfliktów, zanim cokolwiek wyleci na produkcję. Inaczej nowy panel startuje z bałaganem i zespół wraca do Excela, bo tam przynajmniej znaczą kolory.
Kolejki, Redis i to, czego użytkownik nie powinien czekać
Kliknięcie zapisz zamówienie ma trwać ułamek sekundy. Wydruk 200 PDF, wysyłka do kuriera, przeliczenie promocji na całym cenniku — nie. Worker zjada job, panel pokazuje status, mail przychodzi, gdy jest gotowy. Redis trzyma sesje SPA, cache słowników i locki, żeby dwa importy nie nadpisały stanów. Bez tego Black Friday albo inwentaryzacja kończy się timeoutem i podwójnym dokumentem. To nie jest Enterprise dla korporacji. To minimum, jeśli panel ma przeżyć sezon.
Monitoring kolejek (zablokowany worker, rosnący backlog) jest częścią wdrożenia, nie dodatkiem jak będzie budżet. Gwarancja 6 miesięcy obejmuje też to, że joby, które dostarczyliśmy, nie milczą po cichu. Nie obejmuje nowego kanału Slack, którego nie było w zakresie. Granicę piszemy w odbiorze, żeby potem nie zgadywać.
Testy, CI i to, czego nie widać na screenie
Policy bez testu umiera przy pierwszym hotfixie. Na CI odpalamy testy uprawnień, walidacji i kluczowych przepływów (zamówienie, płatność, reset hasła). Nie obiecujemy 100% coverage na MVP — obiecujemy, że scenariusz, który boli biznes, jest zielony i że nie wraca cicho po refactorze tabeli. Vue testujemy tam, gdzie logika siedzi w komponencie (filtry, stany formularza), nie tam, gdzie dublowałaby serwer.
Środowisko testowe jest w cenie projektu, nie jako miły dodatek. Na nim klikasz zanim cokolwiek zobaczy klient końcowy. Dane na teście są zanonimizowane, jeśli produkcja ma dane osobowe — inaczej test jest drugim zbiorem pod RODO. Deploy na produkcję jest powtarzalny, nie ftp w piątek wieczorem. To samo repozytorium Git, które oddajemy, jest tym, z którego wstaje serwer.
Co z designem i codziennym klikaniem
Panel ma być czytelny na 1366 px i na tablecie w magazynie, nie tylko na slajdzie. Nie projektujemy osobnego language of brand na pół kwartału, zanim wstanie pierwsze zamówienie. Mamy zestaw komponentów (tabele, filtry, stany puste, błędy walidacji) i dokładamy tożsamość wizualną firmy: kolor, logo, typowe etykiety. Jeśli potrzebujesz pełnego brand booka i animacji, to osobny zakres — i mówimy to, zanim ktoś porówna nas z agencją kreatywną w cenie Starter.
Dostępność: kontrast, focus, etykiety pól, nie tylko ładny fiolet. Formularze mówią, co jest nie tak, bez zgadywania. Skróty klawiszowe dokładamy tam, gdzie zespół klepie ten sam flow sto razy dziennie, nie dla ozdoby. To detale, które decydują, czy po dwóch tygodniach wrócą do Excela. Dlatego prototyp klikamy na Waszych danych, nie na lorem ipsum z trzema fikcyjnymi klientami o imieniu Test. Jeśli po tygodniu testów widać, że ekran przeszkadza, zmieniamy go w ramach uzgodnionego zakresu, nie chowamy się za tak było w makiecie. Repozytorium Git, dokumentacja odbioru i 6 miesięcy gwarancji idą razem z panelem, nie jako płatny dodatek dopisany na końcu ostatniej faktury etapu wdrożenia na serwer wskazany przez klienta w umowie wdrożeniowej.
SPA, Pinia i gdzie kończy się front
Vue 3 + Vite buduje panel: HMR na teście, code-split na produkcji. Pinia trzyma stan UI (filtry, sesja użytkownika, szkic formularza), nie reguły rabatów. Reguły żyją w Laravelu: serwisy, policies, joby. Jeśli ten sam rabat trzeba policzyć w Vue, w Androidzie i w cronie — zduplikujesz błąd. API jest źródłem prawdy. Vue pokazuje błąd walidacji z Form Request (422) w polu, nie zgaduje. v-html na danych klienta nie używamy — XSS w panelu księgowym jest gorszy niż na blogu.
Routing SPA nie zastępuje autoryzacji. Guard we Vue chowa menu; Sanctum + policy odrzuca request. Tokenów do własnego panelu nie trzymamy w localStorage (dokumentacja Sanctum: cookie session). Android dostaje personal access token z revoke. Wersjonowanie API (/api/v1) dokładamy, gdy drugi klient (mobilka, partner) nie może dostać breaking change w tym samym dniu co panel. Na pierwszy CRM dla 12 osób nie stawiamy GraphQL, BFF i trzech design systemów — za wąski zespół, za szeroki kontrakt.
Idempotencja, joby i piątek o 16:00
Zapis zamówienia jest synchroniczny i krótki. Wydruk 200 PDF, Woo-style import SKU, wysyłka do kuriera, przeliczenie promocji — ShouldQueue. Retry, backoff, failed_jobs, alert gdy backlog rośnie. Idempotency key na webhooku płatności: ten sam payload nie księguje drugiej wpłaty (A10 OWASP 2025). Redis lock przy imporcie stanów, żeby dwa pliki CSV się nie zabiły. Horizon albo równoważny podgląd kolejek jest w wdrożeniu, nie „jak zostanie budżet”. Bez workera tani hosting współdzielony padnie przy pierwszej inwentaryzacji.
Raporty ciężkie liczymy agregatem w tle, nie SUM-em na pięć lat przy każdym wejściu na dashboard. Paginacja i indeksy na obcych kluczach to higiena, nie optymalizacja „na później”. Eksport CSV dużej bazy — uprawnienie, kolejka, często 2FA. Inaczej A01 (masowy wyciek jednym kliknięciem) i RODO schodzą się w jednym przycisku „pobierz wszystko”.
Kontrakt API z Androidem i z człowiekiem
To samo REST, dwa klienty. Kotlin nie dostaje „mobilnej bazy”. Offline w terenie projektujemy tylko gdy naprawdę nie ma LTE, z jawną kolejką sync i konfliktami (dwa wydania tego samego SKU). Skaner kodów to kamera + endpoint, nie osobny ERP. Push — gdy status ma dogonić kuriera, nie żeby mieć apkę w store. iOS nie jest w cenie linii Android; jeśli ma być, jest w briefie i w aneksie. Dokumentacja endpointów (OpenAPI albo równoważna) idzie z Gitem, żeby kolejny zespół nie zgadywał z sieciówki.
Odbiór etapu: scenariusz z briefu klikany na teście, na Waszych (zanonimizowanych) danych. 6 miesięcy gwarancji na dostarczony zakres, nie na nowy kanał Slack. Wycena bez katalogu CRM; logowanie w standardzie projektu. Opisz przepływ od zapytania do dokumentu — powiemy, czy to Business-mały panel, czy etapowy CRM.
Najczęściej zadawane pytania
- Czym różni się panel Laravel + Vue od gotowego CRM?
- Gotowiec ma tysiąc pól, z których używasz 12. Dedykowany panel odwzorowuje Twój proces: role, raporty, integracje — bez Excela obok. Droższy na starcie, tańszy gdy pola nie pasują już w drugim miesiącu.
- Czy aplikacja Android korzysta z tego samego backendu?
- Tak. Jedno API Laravel, dwa interfejsy (Vue i Kotlin). Nie utrzymujesz osobnej mobilnej bazy. Tokeny Sanctum da się unieważnić.
- Jak długo trwa CRM na zamówienie?
- Od miesiąca do kilku miesięcy, w etapach. Zaczynamy od najważniejszego przepływu (np. od zapytania do faktury), nie od pełnego dashboardu. Termin na wczoraj z pływającym zakresem jest droższy.
- Czy mogę potem zmienić wykonawcę?
- Tak. Dostajesz Git i dokumentację. Laravel i Vue są na tyle popularne, że inny programista w Polsce odczyta kod. 6 miesięcy gwarancji na dostarczony zakres zostaje przy nas.
- Czy to SPA na tokenach?
- Panel webowy: sesja / cookie Sanctum z CSRF, zgodnie z dokumentacją. Mobilka: tokeny. Nie mieszamy jednego worka na wszystko. Szczegóły w artykule o 2FA i Sanctum.
- Ile to kosztuje?
- Mały panel może wejść w rząd Business od 6 000 zł tylko gdy zakres jest naprawdę mały. CRM / B2B z integracjami — po briefie, bez ceny katalogowej. Rozpisane w artykule o wycenie.
- Czy dam radę edytować treści bez programisty?
- Tak, tam gdzie treść jest treścią (strony, maile, statusy). Reguł rabatów i uprawnień nie wystawiamy jako CMS dla każdego — to celowo, żeby stażysta nie otworzył marży całej hurtowni.
- Co z wydajnością przy dużych tabelach?
- Paginacja, indeksy, agregaty w tle, kolejki na eksport. Dashboard nie liczy historii pięciu lat na każde wejście. Jeśli ktoś obiecuje wszystko na żywo na jednym ekranie, zapytaj o piątek o 16:00.
Powiązana usługa:
Platformy B2B i CRM na zamówienie
Opisz projekt