Pokrenite projekt

Rentalica

Rad za klijenta · Modernizacija naslijeđenog sustava

Naslovnica Rentalice - koje vozilo zarađuje, a koje Vas potiho košta

Rent-a-car back-office koji je više od deset godina radio na PHP-u 5.6, prepisan kao moderan multi-tenant SaaS — s desetljećem rezervacija, ugovora i dokumenata prenesenim bez ijednog zahtjeva korisniku da resetira lozinku. A onda odveden mnogo dalje nego što je stari sustav ikad mogao.

Godina migriranih produkcijskih podataka
10+
Tablica prepisanih na PostgreSQL
22
Potrebnih resetiranja lozinke
0
Automatiziranih testova koji čuvaju prepisani sustav
102

Softver koji je i dalje radio

FlexiRent nije bio pokvaren: desetljeće je svaki dan vodio stvarnu rent-a-car tvrtku. Samo je stajao na stacku koji je svijet napustio.

Što je radilo

  • PHP 5.6 na Ubuntuu 14.04 — oboje davno bez podrške
  • Vlastiti PHP MVC framework, oko 55 tisuća redaka
  • MySQL 5.5 bez stranih ključeva — veze se održavaju u kodu aplikacije
  • JSON skriven u TEXT stupcima, dopuštenja spremljena kao CSV
  • 440 MB ugovora i skenova na disku jednog poslužitelja

Zašto ovakva prepisivanja propadaju

Uobičajen je pristup pročitati stari kod, pogađati poslovna pravila i isporučiti nešto što izgleda bolje, ali potiho griješi u detaljima. Korisnik to primijeti u drugom tjednu, kad ugovor ispiše krivi polog.

Desetljeće ponašanja u produkciji ne nalazi se u kodu. Ono je u rubnim slučajevima, zaobilaznim rješenjima i brojkama koje ljudi provjeravaju svako jutro. To je ono što prepisivanje mora prvo sačuvati.

Original smo napisali mi

FlexiRent nismo naslijedili od nekoga drugog. Izradio ga je LumiVerse, a zatim ga više od deset godina održavao u produkciji, dok ga je stvarni upravitelj voznog parka koristio svaki dan.

To je deset godina gledanja kako se posao stvarno odvija: koji se ekrani otvaraju prvi ujutro, koja polja uvijek ostaju prazna, što djelatnik radi kad se kombi u nedjelju vrati oštećen. Ništa od toga nigdje nije zapisano. Zato je prepisivanje moglo preskočiti fazu otkrivanja i krenuti ravno u izradu.

Poznavanje domene, a ne nagađanje

  • Specifičnosti hrvatskog najma — kontrolna znamenka OIB-a, AO i kasko osiguranje, datumi registracije i tehničkog pregleda
  • Pravila cijena koja uključuju podjelu s partnerima i provizije
  • PDF ugovori koji se moraju ispisivati točno kao i prije
  • Tijekovi rada preslikani dovoljno vjerno da prelazak ne traži ponovnu edukaciju

Prvo istovjetnost, pa ideje

Mijenjaj tehnologiju ili proizvod, nikad oboje odjednom. Novi je sustav morao biti dokazivo istovjetan prije nego što je smio biti bolji.

  1. Snimiti sve, ne promijeniti ništa

    Potpuna sigurnosna kopija produkcije, samo za čitanje: 2.855 datoteka, cijela baza, konfiguracija web poslužitelja. Živi poslužitelj nikad nije mijenjan. Svaka se kasnija odluka mogla provjeriti na zamrznutoj, provjerenoj kopiji.

  2. Pokrenuti staru aplikaciju lokalno

    PHP 5.6, Apache i MySQL zapakirani u Docker da naslijeđeni sustav radi na prijenosniku. Ne da ga se održi na životu — nego da postoji referentna izvedba za usporedbu, ekran po ekran, broj po broj.

  3. Najprije napisati analizu

    Svaka tablica preslikana na ciljni entitet, svaka implicitna veza dokumentirana, svaki rizik popisan prije ijednog retka novog koda: JSON blobovi, neispravni nul-datumi, CSV dopuštenja, generator PDF-ova.

  4. Prepisati do istovjetnosti

    Vjerna replika na novom stacku — isti ekrani, isti brojevi, nijedna nova ideja — označena i zamrznuta kao točka povratka. Poboljšanja nisu bila dopuštena dok se ta verzija nije poklopila sa starom.

  5. Migrirati, pa dokazati

    Iz MySQL-a u PostgreSQL: JSON blobovi normalizirani, dodani pravi strani ključevi, neispravni datumi pretvoreni. Zatim su automatske provjere integriteta između baza uspoređivale broj redaka i zapise s izvorom dok se nisu poklopili.

  6. Uvježbati prelazak

    Zapisani postupak s povratkom na staro u svakoj fazi: zamrzni staru aplikaciju, ponovno migriraj svježe podatke, provjeri s brojkama prije zamrzavanja, pa prebaci. Uvježbavanje u cijelosti, bez diranja produkcije.

Detalj zbog kojeg je prelazak prošao bezbolno

Naslijeđeni je sustav lozinke spremao kao bcrypt sažetke. Bcrypt je bcrypt — novi backend te iste sažetke provjerava izravno. Svaki je korisnik zadržao točno ono korisničko ime i lozinku koje je već imao. Bez e-mailova za resetiranje, bez poziva podršci i bez poruke „migrirali smo, evo Vaših novih podataka za prijavu". Datoteke iz starog sustava prenesene su na isti način: isti dokumenti, iste poveznice, i dalje se preuzimaju.

Što se zapravo promijenilo

Ista poslovna pravila. Posve drukčiji temelj.

SlojNaslijeđenoRentalica
Izvršno okruženjePHP 5.6 na Ubuntuu 14.04, oboje bez podrškePython i Node u kontejnerima, aktualna izdanja
BackendVlastiti PHP MVC framework, oko 55 tisuća redaka za održavanjeFastAPI + SQLAlchemy 2.0, tipizirano i automatski dokumentirano
Baza podatakaMySQL 5.5, bez stranih ključeva, JSON u TEXT stupcimaPostgreSQL sa stvarnim ograničenjima i JSONB-om ondje gdje mu je mjesto
FrontendBootstrap 3 administratorska tema, generirana na poslužiteljuNext.js 15 i React 19 s generiranim tipiziranim API klijentom
PrijavaVlastite datoteke sesija, dopuštenja kao niz odvojen zarezimaSesije u httpOnly kolačićima, provjera uloga na svakom zahtjevu
VišekorisničkostJedna tvrtka, jedna instalacijaMulti-tenant, s odvajanjem koje se provodi na razini upita
TestoviNema ih102 backend testa i pokrivenost end-to-end testovima u pregledniku

Nismo stali na kopiji

Vjerna replika bila je sigurnosni uvjet, a ne cilj. Kad su podaci bili dokazani, novi je temelj donio ono što PHP 5.6 nikad ne bi ponio.

Analitika koja odgovara na jedino pitanje koje je važno

Većina softvera za vozne parkove prikazuje prihod. Rentalica prikazuje ono što ostane. Svaki se trošak unosi jednom, s razdobljem — jednokratno, mjesečno ili godišnje — pa se raspoređuje po mjesecima koje stvarno pokriva i tereti vozilo koje ga je izazvalo. Leasing, AO i kasko, registracija, gume, servis i gorivo slijeću na pravi kombi.

  • Neto rezultat po vozilu — brojka koju prije nitko nije imao
  • Prikaz praga isplativosti: pokriva li ovomjesečni prihod vozni park?
  • Tjedni sažetak: vozila u minusu, neiskorištena imovina, police koje ističu, nenaplaćeni najmovi
  • Sastav voznog parka na bilo koji datum u prošlosti, za planiranje kapaciteta
  • Podjela s partnerima i provizije uračunate u samu matematiku

Računi koji sami ispune svoj obrazac

Fotografirajte račun ili potvrdu s benzinske. Snimka se čita na licu mjesta, a zatim se izvlače iznos, datum, izdavatelj, OIB dobavljača, broj računa i registracijska oznaka, predlaže se kategorija troška i pronalazi vozilo. Uključujući hrvatski zapis decimala. Ništa se ne sprema dok čovjek ne potvrdi.

Asistent koji govori hrvatski i SQL

Pitajte na običnom hrvatskom koji putnički kombi mjesečno prijeđe najmanje kilometara i dobit ćete tri stvari: odgovor, tablicu iz koje je došao i točan upit koji ga je proizveo. Ništa nije skriveno iza oblačića za chat — korisnik može provjeriti rad prije nego što mu povjeruje.

  • Pitanja na hrvatskom, odgovori s prikazanim upitom
  • Pitanja o dobiti idu u pravi obračun dobiti i gubitka, nikad se ne procjenjuju
  • Približno pronalaženje vozila, pa i pogreška u tipkanju nađe pravi kombi
  • Trajne upute — recite jednom da je auto privatan i zapamtit će to

Skeniranje dokumenata, na vlastitoj infrastrukturi

Vozačke dozvole, osobne iskaznice, putovnice i prometne dozvole razvrstava i čita OCR servis na vlastitim poslužiteljima, pa snimke ostaju na Vašoj infrastrukturi. Strojno čitljive zone obrađuju se s ICAO kontrolnim znamenkama — čisto očitanje samo sebe potvrđuje.

Arhiva dokumenata dostojna imena

Svaka priložena datoteka slijeće na jedno mjesto i pretraživa je po onome što u njoj piše, jer se izdvojeni tekst sprema uz datoteku. Tablica poveznica bilježi uz što je svaki dokument vezan — pa možete iz dokumenta natrag do njegova vozila, troška ili ugovora, i pronaći one koji nisu vezani ni uz što.

Imenik koji je izrastao u CRM

Jedan imenik za kupce, tvrtke i partnere, razvrstan grupama i oznakama. Svaki kontakt otvara cijeli profil: svaki najam, svaki ugovor, što još duguje, uz povezane zadatke i dokumente. Brojevi dozvola, kategorije i datumi isteka stoje na samom zapisu.

Posao koji se ne drži u nečijoj glavi

Popisi zadataka po osobi i zajednički za tim, svaki zadatak prikvačen uz vozilo, rezervaciju ili kupca na koje se odnosi, s nositeljem, prioritetom i rokom. Istek registracije, osiguranja i tehničkog pregleda sam podiže podsjetnik, a da se itko ne mora sjetiti pogledati.

Pustiti AI blizu stvarne baze

Asistent nad živim poslovanjem vrijedan je povjerenja koliko i njegova ograničenja. Naša se provode u kodu i PostgreSQL-u, a ne u promptu.

  1. Na popisu dopuštenih, ne na povjerenje

    Svaka se generirana naredba raščlanjuje u sintaksno stablo i popisuje se svaka tablica koje se dotiče — uključujući one zakopane u podupitima i spojevima preko zareza. Sve izvan odobrenog skupa odbija se prije nego što dođe do baze. Računi djelatnika i sažeci lozinki trajno su izvan dosega.

  2. Odvajanje koje se ne da nagovoriti

    Prije izvršavanja svaka se navedena tablica prepisuje u filtrirani pogled na retke tog korisnika, pa se neprecizan upit razrješava na prave podatke samom izvedbom, a ne dobrim ponašanjem. Zajednički tablični izrazi odbijaju se u startu — inače bi mogli redefinirati taj filtar.

  3. Samo za čitanje, na razini baze

    Upiti se izvršavaju unutar transakcije samo za čitanje, s vremenskim ograničenjem naredbe i tvrdim ograničenjem broja redaka, a ta se transakcija uvijek poništava. Upis ne odbija modelova bolja prosudba — on se na toj vezi jednostavno ne može dogoditi.

Zaglavili ste sa sustavom koji ne možete ugasiti?

Ako je softver koji vodi Vaše poslovanje star, nedokumentiran i prevažan da bi se smio pokvariti, to je problem koji rješavamo. Prvo istovjetnost, dokazano netaknuti podaci i prelazak koji se može poništiti.

Primamo nove projekte

Pogledajte početne cijene za ovakav posao ili nam recite što gradite i odgovorit ćemo u roku od 24 sata. Radije biste koristili neki od naših proizvoda, poput Tvrtko.ai, Moj Kolega ili Titlomata? I oni su dostupni.