Objavljeno: 02.06.2026
Razvoj kompletnog makroekonomskog data engine-a i AI integracije (MEDepot API)Uspešno sam postavio i zaokružio celokupnu backend arhitekturu za svoj fullstack web projekat. Sistem je u potpunosti operativan, modularan i spaja analitiku finansijskih podataka u realnom vremenu sa veštačkom inteligencijom.
Tokom ove faze radova uspešno sam realizovao sledeće celine:
Dizajn i postavka PostgreSQL baze (MEDepot_db):
Kreirao sam i indeksirao ukupno 9 tabela kroz pgAdmin 4. Tabele pokrivaju tržišne podatke, ekonomiju, kamatne stope centralnih banaka, sentiment indekse, korisnike, watchlist-e, kao i strukturu za orderbook i orderflow (polovično).
Koristio sam TIMESTAMPTZ i NUMERIC tipove radi finansijske preciznosti.
Inicijalizacija FastAPI backend-a:
Podigao sam asinhroni server i povezao ga sa bazom podataka preko asyncpg drajvera, koji je najbrži izbor u Python ekosistemu za rad sa PostgreSQL-om. Konfiguraciju i API ključeve sam obezbedio kroz bezbedne Pydantic Settings modele i .env datoteke.
Izgradnja modularnih servisa (Ekstrakcija podataka):
Kako bih izbegao monolitnu strukturu, razbio sam logiku na izolovane servise unutar app/services/ foldera:fed.py: Koristi zvanični FRED API za automatsko povlačenje i punjenje istorijske serije podataka o američkoj kamatnoj stopi i krive prinosa obveznica (2Y, 10Y, 30Y).ecb.py. Automatski parsira zvanični XML/RSS feed Evropske centralne banke i ažurira stope evrozone.nbs.py. Implementira robustan HTML scraper sa BeautifulSoup koji bezbedno čisti i izvlači referentnu kamatnu stopu sa sajta Narodne banke Srbije.
Masovno osvežavanje tržišnih cena:
Unutar market.py rutera konfigurisao sam povlačenje podataka za preko 100 najjačih finansijskih instrumenata istovremeno preko yfinance. Sistem jednim pozivom povlači i raspoređuje indekse (S&P500, Nasdaq, VIX), sirovine (zlato, nafta, srebro) i Mega-Cap akcije iz Amerike i Evrope po zvaničnim finansijskim sektorima.
Dvostruki Sentiment Engine: Razdvojio sam praćenje psihologije investitora na dva nezavisna kanala. Implementirao sam endpoint za CNN Fear & Greed indeks (tržište akcija) sa matematičkim fallback-om na VIX indeks, kao i odvojeni endpoint za Crypto Fear & Greed indeks. Podaci se u bazi bezbedno razdvajaju kroz sufikse.
Integracija Gemini AI Analitike:
Uspešno sam povezao najnoviji Google GenAI SDK i kreirao ruter ai.py. Napravio sam endpoint koji direktno iz baze asinhrono povlači najnovije monetarne stope, cene sirovina, krive prinosa i oba indeksa sentimenta. Podaci se pročišćavaju i šalju modelu gemini-2.5-flash koji na osnovu njih generiše sveobuhvatan, dubok makroekonomski izveštaj i investicione preporuke direktno na srpskom jeziku sa statusom 200 OK.
#fastapi, postgresql, asyncpg, yfinance, fred-api, google-gemini, python, backend
Objavljeno: 24.05.2026
OPTIMIZACIJA PREPORUKA NA EKRANU PRIJATELJA + TASTATURAImplementacija dinamičkih preporuka i rešavanje softverske tastature.
Danas sam uspešno završio ugradnju i stabilizaciju dva ključna modula:
Sistema za automatsko šaltanje preporuka na tabu prijatelja i podsistema za kreiranje čet grupa.
Ovim koracima sam postigao potpunu automatizaciju korisničkog interfejsa i eliminisao zaleđivanje ekrana usled deljenja Ktor mrežnih ruta.
Tehnička struktura i realizovane izmene:
1. Nezavisni reaktivni tajmer (FriendsScreen.kt):
Izmestio sam logiku za mešanje predloga iz mrežnog polera u potpuno odvojen LaunchedEffect(suggestionsList) blok.
Novi tajmer radi isključivo u lokalnoj memoriji (RAM) uređaja.
Na svakih 3.5 sekunde uzima sirovi niz, primenjuje .shuffled().take(4) i izbacuje tačno 4 nasumične osobe.
Ovim je rešen problem Ktor preusmeravanja, a potrošnja mobilnih podataka je smanjena na minimum jer se klijent više ne preplavljuje celom bazom podataka pri svakom osvežavanju.
2. Klijentski optimizam i kreiranje grupa (GroupsScreen.kt):
Ugradio sam FloatingActionButton (plutajući +) i povezao ga sa AlertDialog komponentom direktno unutar glavnog Scaffold-a.
Dijalog preko client.post šalje parametre action: "create" i group_name ka serverskom ruteru api_groups.php.
Zatvaranje prozora je trenutno, a nova grupa automatski skače na sam vrh liste u sledećem mrežnom ciklusu zahvaljujući serverskom sortiranju ORDER BY id DESC.
3. Fiksiranje UI elemenata (AndroidManifest.xml):
Ugradio sam sistemski parametar android:windowSoftInputMode="adjustResize" unutar glavne aktivnosti aplikacije.
Ovim sam postigao da gornji plavi bar sa imenom grupe i funkcijama ostane potpuno nepomičan i zakucan na vrhu ekrana prilikom otvaranja i zatvaranja tastature, dok se prostor za poruke fluidno skraćuje.
Rezultat:
Sistem je uspešno kompajliran i testiran na realnom Samsung Galaxy S9+ hardveru. Upozorenje "Assigned value is never read" je uspešno obrisano, a korisnički interfejs reaguje instant i bez ikakvog kašnjenja.
Sledeći korak je implementacija ADMIN LOGS dugmeta sa bezbednosnom klijent-server proverom za adminski nalog.
#jetpack-compose, android-ui, soft-input-mode, recommender-system, groups-creation, hardware-debugging, jetpack-compose, android-ui, soft-input-mode, recommender-system, groups-creation, hardware-debugging
Objavljeno: 24.05.2026
INTEGRACIJA REAL-TIME CHAT SISTEMAFinalna integracija i optimizacija real-time chat sistema na realnom hardveruDanas sam zaokružio projekat stabilizacije i puštanja u rad modula za privatne poruke 1-na-1 na klijentskoj i serverskoj strani.
Ovim sam postigao potpunu fluidnost u real-time komunikaciji, eliminišući mrežna zagušenja i probleme sa keširanjem memorije na mobilnom uređaju.
Tehnička struktura sistema:
Unificirana API arhitektura:
Implementirao sam centralni upravljački ruter api_private.php koji koristi univerzalni parser dolaznih podataka (JSON body, POST i GET).
Zamenio sam require_once naredbe sa čistim require strukturama, čime sam omogućio stabilan mrežni poling u realnom vremenu.
Hijerarhija izvršavanja i bezbednost:
Čelični SQL zid (list_chats.php):
Uveo sam restriktivni INNER JOIN sa podupitom nad tabelom friends koji filtrira saobraćaj prema statusu 'accepted'.
Dodao sam korensku proveru ulogovanog ID-ja ($my_id <= 0) na serveru, čime je fizički onemogućeno prelivanje cele baze korisnika na ekran u slučaju mrežnog kašnjenja.
Razbijanje Ktor keš blokade:
Na Android klijentu sam ugradio dinamički vremenski žig (System.currentTimeMillis) unutar URL-a polera, što je prisililo Ktor drajver da zaobiđe keš i osvežava lista prijatelja instant (nakon maksimalno 3 sekunde) čim se status promeni na vebu.
UI optimizacija i Jetpack Compose:
Uklonio sam duplirane pozadinske niti (LaunchedEffect) koje su gušile procesor i RAM memoriju telefona. Omotao sam stanje pretrage u reaktivni remember(chatsList) blok bez nestandardnih karaktera (Čatovi -> Catovi), čime sam omogućio momentalno iscrtavanje novih prijatelja i poruka. Uveo sam uslovno boldovanje teksta (FontWeight.Bold) i promenu boje za nepročitane poruke na osnovu unreadCount brojača.
Robusnost:
U AndroidManifest.xml fajlu sam aktivirao largeHeap="true" i usesCleartextTraffic="true", čime je limit RAM memorije za aplikaciju na telefonu podignut sa 27MB na maksimalne serverske kapacitete.
Uvedena je try-catch logika na klijentu i serveru koja osigurava da privremeni pad mrežnog signala ili preklapanje sa dashboard saobraćajem ne zaustavlja rad aplikacije.
Rezultat:
Sistem je uspešno testiran u realnim uslovima na Samsung Galaxy S9+ uređaju putem USB debugging-a. Krug osvežavanja liste i istorije poruka traje tačno 3 sekunde, a lokalni optimizam na dugmetu za slanje renderuje oblačiće na ekranu u roku od 1 milisekunde, nakon čega niti odlaze u stanje mirovanja.
Projekat je uspešno integrisan sa postojećom web aplikacijom i spreman za dalju nadogradnju.
#android-development , etpack-compose, ktor-client, php-backend, real-hardware-testing, systems-integration, optimization, android-development, jetpack-compose, ktor-client, php-backend, real-hardware-testing, systems-integration, optimization
Objavljeno: 21.05.2026
Siže migracije i refaktorisnja ChatterApp 3.0 za Android sistemFaza 1: Čišćenje i postavljanje temelja (Modularna Backend Arhitektura)
Prvi pravi izazov bio je prelazak sa stare, monolitne PHP strukture u jednom fajlu na čist, modularni sistem koji je lak za održavanje. Počeo sam od nule: preuredio sam MariaDB bazu podataka, analizirao users, chat_groups i private_messages tabele. Da bih izbegao "monolitnu bombu" od preko 200 linija koda u api_groups.php na mom kućnom Linux serveru, kreirao sam strukturu foldera group-actions/ i private-actions/ i u njih hirurški izmestio sve teške operacije (list, create, leave, delete, kick, add). Glavni API fajlovi su time postali ultra-čisti ruteri koji samo prihvataju mrežni saobraćaj i delegiraju rad modulima preko require_once.
Faza 2: Borba sa mrežnim blokadama i vremenskim zonama bazeKada je backend prodisao na Linuxu, udario sam u zid mrežne administracije i strogih provera. Prvobitno, kada bi Android telefon poslao brz GET zahtev za članove ili pretragu, globalna provera za user_id na vrhu PHP fajla bi detektovala nulu i instant prekinula skriptu, zbog čega je na telefonu stalno pisalo "Učitavanje članova...". Problem sam rešio tako što sam akcije members i search_users izvukao iznad te blokade, dajući im potpunu slobodu. Drugi zid su bile online status lampice – iako je korisnik bio ulogovan na laptopu, baza mu nigde nije ažurirala vreme aktivnosti. Implementirao sam pozadinski UPDATE users SET last_seen = NOW() mehanizam pri svakom mrežnom pollingu i prebacio SQL logiku sa problematičnih timestamp intervala na neprobojne UNIX_TIMESTAMP sekunde, čime su lampice momentalno oživele.
Faza 3: Optimizacija Jetpack Compose Frontenda i eliminacija "uljeza"U Android Studiju, MainActivity.kt je dostigao kritičnih 700 linija koda jer je u sebi svesno sadržao sve ekrane, navigacione tabove i teške JSON parsere. Izveo sam veliku ekstrakciju komponenti: kreirao sam AuthScreen.kt, AuthScreenWrapper.kt i centralni MainScaffold.kt ruter. MainActivity je spao na čistih ~200 linija stanja (States). Najveća peripetija na interfejsu bio je stari kod unutar dijaloga članova – on je "uljez" metodom skenirao samo istoriju poruka (messagesList) umesto baze, pa su neaktivni članovi bili nevidljivi. Prebacio sam interfejs na Triple<Int, String, Boolean> strukturu koja uživo vuče (ID, Ime, Online) sa baze. Takođe, prevazišao sam problem minimalističkih Android biblioteka zamenom problematične ikonice Icons.Default.Add tekstualnim plusom "+", čime sam osigurao uspešan Gradle Build bez ikakvih spoljnih zavisnosti.
Faza 4: Automatizacija rada, Instant-Offline i AutodopunaDa bi privatni čet 1-na-1 i grupni menadžment radili bez greške, morao sam da osiguram real-time sinhronizaciju.Implementirao sam while(showMembersDialog) beskonačnu petlju sa delay(3000) unutar PrivateScreen.kt i GroupsScreen.kt, čime se spisak članova i lampice automatski osvežavaju bez potrebe za zatvaranjem kartice.Napravio sam sistem autodopune (sugestija) tokom kucanja unutar onValueChange bloka koji na svako pritisnuto slovo pita search_users.php i izbacuje prelepu sivu Card karticu sa predlozima imena sa veb sajta.Kreirao sam instant-offline rešenje u logout.php na laptopu – moj lični trik koji pri odjavi korisnika sa sajta prisilno vraća njegov last_seen 10 minuta unazad u prošlost, zbog čega lampica na telefonu posivi u istom sekundu.Sve promene sa laptopa na Linux server slao sam direktno iz PowerShell terminala kroz moćnu scp -r komandu preko Tailscale HTTPS mreže.
Status: Sistem grupnih i privatnih četova je 100% operativan, modularan, osiguran od pucanja i sinhronizovan u realnom vremenu.
#Linux, SQL, PHP, JetpackCompose, Kotlin, AndroidStudio, Tailscale, Ktor, Polling, RealTime, UNIX_TIMESTAMP, SQL, Scp, PowerShell, JSON, FullStack, ChatterAppDigital
Objavljeno: 20.05.2026
Kako sam povezao i modularizovao Chatter Android aplikacijuNakon uspešno postavljenog i testiranog sistema, ovde dokumentujem kompletan proces razvoja, od rešavanja prvih unutrašnjih grešaka u IDE okruženju do uspostavljanja stabilne, modularne Android arhitekture povezane sa mojim kućnim Linux serverom.
Razvojni proces korak po korak:Korak: Sređivanje IDE okruženjaPrvo sam se susreo sa dosadnim unutrašnjim bagom Android Studija (IllegalStateException na EDT niti) koji je iskakao nakon Gradle sinhronizacije.
Utvrdio sam da je to greška same IntelliJ platforme koja ne utiče na moj kod, uspešno je ugasio i osigurao stabilan nastavak rada.
Korak 1:
Povezivanje fizičkog uređaja (Samsung Galaxy S9+)
Zbog ograničenih resursa na laptopu (16GB RAM-a), odlučio sam da preskočim težak Android emulator.
Na svom Samsungu S9+ sam upalio Developer Options, aktivirao USB Debugging i povezao ga kablom, čime sam prebacio sav teret izvršavanja direktno na procesor telefona.
Korak 2:
Probijanje mrežne blokade i Tailscale tunelPošto sam testirao aplikaciju preko mobilnog interneta (van kućne mreže), podigao sam Tailscale VPN na telefonu i ulogovao se na isti nalog kao i kućni server. Time sam napravio bezbedan tunel do servera.
Zatim sam u Kotlinu redefinisao Ktor HttpClient dodavanjem prilagođenog sslManager-a koji ignoriše provere sertifikata i dozvoljava saobraćaj ka mom privatnom *.ts.net domenu.
Korak 3:
Analiza MySQL baze i prvi PHP API (api_chat.php)Dobio sam SQL grešku da tabela messages ne postoji. Preko Linux terminala pokrenuo sam pretragu strukture mog chatter_db.sql fajla i otkrio da se stvarna tabela zove private_messages i da koristi kolonu created_at umesto date. Napisao sam api_chat.php skriptu koja radi JOIN sa tabelom users kako bih na telefonu umesto ID brojeva dobio stvarna korisnička imena, i uspešno povukao prve čet poruke na ekran S9+.
Korak 4:
Slanje poruka sa telefona i otključavanje Apache blokade (api_send.php).
Napisao sam api_send.php za upis novih poruka u bazu, ali mi je server uporno vraćao prazan odgovor od 0 karaktera. Čitanjem db_chatter.php shvatio sam da me blokira session_start() koji puca jer robotski Ktor zahtev sa telefona nema kolačiće i sesiju. Potpuno sam osamostalio api_send.php, ugradio direktnu PDO konekciju sa tačnim parametrima baze (nikic_admin), fiksirao upis pod grupom 8 ("KontraverzniBiznismeni") i uspešno poslao poruku sa telefona direktno u MySQL bazu na Linuxu.
Korak 5:
Implementacija Login sistema i zaobilaženje heša (api_auth.php).
Kada sam napravio ekrane za Login i Registraciju, veb sajt me je odbijao jer koristi drugačiji algoritam za hešovanje lozinki u odnosu na standardni password_verify. Da bih otključao razvojni sistem, napravio sam "master key" skriptu api_auth.php koja samo proverava da li korisnik uopšte postoji u bazi i odmah pušta unutra sa bilo kojom lozinkom.Korak: Rešavanje asinhronih niti u Kotlinu. Prilikom slanja Login zahteva aplikacija je pucala jer je Android blokirao mrežni poziv na glavnoj (UI) niti. Popravio sam funkciju handleAuth tako što sam je eksplicitno zatvorio unutar withContext(Dispatchers.IO) bloka, čime sam saobraćaj prebacio u pozadinu i stabilizovao rad.
Korak 6:
Modularizacija arhitekture i uvođenje Bottom Navigation menija,kako bih sprečio da mi MainActivity.kt postane kilometarski i nepregledan fajl, primenio sam profesionalnu praksu. Razbio sam projekat na zasebne fajlove unutar novog foldera (paketa) screens.
Napravio sam samostalne fajlove DashboardScreen.kt i GroupsScreen.kt, a u samoj MainActivity zadržao samo Login i registraciju, i dodao Material 3 Scaffold sa donjim menijem (tabovima) za šetanje kroz aplikaciju.
#AndroidStudio, Kotlin, JetpackCompose, Material3, KtorHttpClient , Coroutines, DispatchersIO, PHP, MariaDB, MySQL, TailscaleMesh, LinuxDebian, SSHTerminal, VSCode
Objavljeno: 14.05.2026
Rešenje problema trigera sistema i email obaveštenja na BGDX projektuKao autor BGDX monitora za Beogradsku berzu, uspešno sam rešio ključni arhitektonski izazov: kako da sinhroni Python scraper koji prikuplja cene u realnom vremenu pokrene asinhroni sistem email obaveštenja, a da mrežne restrikcije ili kašnjenje eksternih SMTP servera ne blokiraju rad scrapera.
Problem sam rešio uvođenjem asinhronog Message Queue (red čekanja) modela direktno kroz PostgreSQL bazu u tri precizna koraka:
1. Kreirao sam namensku tabelu `email_queue` koja služi kao izolovani posrednik između scrapera i API backend-a. Tabela skladišti podatke o primaocu, naslovu, telu poruke i statusu slanja (pending, sent, failed).
2. U samom scraperu, unutar funkcije za upis podataka u bazu (`insert_stock_data`), ugradio sam inteligentnu logiku za prepoznavanje "Ticker change" trigera. SQL upit poredi najnoviju skrejpovanu cenu sa poslednjom zabeleženom cenom u istoriji. Ako se cena razlikuje (došlo je do realnog pomeranja na tržištu), sistem prolazi kroz korisničke preference. Da bih sprečio spamovanje korisnika istom informacijom tokom dana, uveo sam restrikciju `NOT EXISTS` koja proverava da li je alarm za taj tiker već generisan u toku dana (`CURRENT_DATE`). Za svakog kvalifikovanog korisnika, scraper izvršava brz `INSERT` u `email_queue` sa statusom pending.
3. Na strani FastAPI backend-a, unutar `lifespan` menadžera aplikacije, kreirao sam asinhranu pozadinsku petlju `email_queue_worker` koja se podiže zajedno sa serverom. Ovaj worker radi autonomno u pozadini i na svakih 60 sekundi šalje upit bazi tražeći zapise sa statusom pending. Čim uoči nove zapise, on asinhrono koristi moju integrisanu `fastapi_mail` funkciju koja se povezuje na Gmail SMTP server preko zaštićenih kredencijala i šalje prelepo formatiran HTML izveštaj korisniku. Nakon uspešnog slanja, worker ažurira status u bazi u sent, čime uspešno prazni red i zatvara krug.
Ovom arhitekturom postigao sam potpunu otpornost na greške (fault tolerance). Ako SMTP servis uspori ili padne, scraper nastavlja da radi nesmetano i puni bazu, a worker će bezbedno poslati sve zaostale mejlove čim se veza stabilizuje.
#postgres, mq, backend, worker, trigger
Objavljeno: 30.04.2026
Migracija BGDX 2.0 sistema na Linux (Debian)Faza 1: Čišćenje i postavljanje temelja
Prvi pravi izazov bio je prelazak sa Windows razvojnog okruženja na Debian Linux. Počeo sam od nule: instalirao sam PostgreSQL bazu, kreirao BGDX_db i ručno podesio korisnike i privilegije. Najveća peripetija ovde bili su Python venv (virtuelna okruženja) – morao sam da obrišem stare Windows verzije i ponovo instaliram sve zavisnosti (FastAPI, Pydantic, SQLAlchemy, psycopg2-binary) direktno na Linuxu kako bi se izbegle nekompatibilnosti biblioteka poput bcrypt.
Faza 2: Borba sa portovima i CORS politikom
Kada je kod "prodisao" na Linuxu, udario sam u zid mrežne administracije. Da bi sistem bio javan (preko Tailscale-a), morao sam da uskladim tri različita servisa:
Apache (Portfolio) na portu 80.
Next.js (Frontend) na portu 3000.
FastAPI (Backend) na portu 8000.
Najviše vremena mi je oduzelo rešavanje CORS grešaka i Mixed Content blokada u browseru. Problem je bio u tome što je browser odbijao da šalje podatke sa HTTPS domena na običan HTTP port.
Rešenje je bilo u preciznom mapiranju Tailscale Funnel-a:
Glavni domen sam ostavio za Portfolio.
Port 8443 sam namenio Next.js frontendu.
Port 10000 sam iskoristio kao kapiju za Backend.
Faza 3: Optimizacija Frontenda i Backenda
Morao sam "hirurški" da izmenim api.ts i sve komponente (register, login, market) kako bih izbacio localhost:8000 i zamenio ga novim Tailscale HTTPS linkom. Nakon svakoe sitne popravke u kodu, radio sam puni npm run build kako bi Next.js "zapekao" ispravne putanje u statičke fajlove. Tek tada je registracija korisnika na telefonu konačno proradila bez crvenih grešaka u konzoli.
Faza 4: Automatizacija i "Panic Button"
Da ne bih svaki put kucao deset komada naredbi, napravio sam start_all.sh skriptu. Ipak, falila mi je kontrola nad scraperom.
Implementirao sam aliase u .bashrc (startberza, killberza, berza).
Rešio sam problem sa "crnim ekranom" u logovima dodavanjem -u (unbuffered) parametra u Python poziv, čime sam dobio ispis skrepera u realnom vremenu (čuveno "Spavam 15 min...").
Kreiraio sam resetberza komandu – moj lični "panic button" koji gasi sve procese, čisti keš i podiže ceo sistem iz nule.
Status: Sistem je 100% operativan, dostupan globalno i stabilan.
#Linux, Debian, PostgreSQL, FastAPI, Next.js, Tailscale, Funnel, CORS, Networking, Ports, Reverse Proxy, Python, Scraper, Automation, Bash, Alias, SSL, HTTPS, Web Development, System Administration, DevOps, Mentorship, Troubleshooting, BGDX Digital
Objavljeno: 30.04.2026
Izgradnja BGDX Monitor SistemaSve je počelo od ideje da napravim moderan, real-time terminal za praćenje Beogradske berze. Evo hronologije našeg napretka:
Sređivanje Dashboard-a i vizuelni identitet
Prvo sam se fokusirao na samu osnovu. Napravio sam dinamičku tabelu koja se osvežava uživo. Rešio sam dosadne React greške sa "unique key" propovima koristeći React.Fragment. Podelio sam ekran tako da pored svakog grafikona stoje i detaljni statistički podaci (otvaranje, VWAP, dnevni max/min) koje izvlačim direktno iz PostgreSQL baze.
Autorizacija i sigurnost
Da bih omogućio korisnicima personalizovano iskustvo, uveo sam JWT (JSON Web Token) autentifikaciju. Povezao sam Login i Register stranice sa backendom. Napravio sam get_current_user funkciju koja služi kao "policajac" – ona prepoznaje ko je ulogovan i dozvoljava pristup samo onim podacima koji pripadaju tom korisniku.
Sistem preferencija (Slajderi)
Ovo je bio ključni deo. Umesto da svi dobijaju sve, napravio sam stranicu "Preferencije". Korisnik sada može za svaki ticker (npr. NIIS, AERO) posebno da upali ili ugasi šta želi da prati na email-u: cenu, obim, procentualne promene ili vesti. Sve te izmene se u realnom vremenu čuvaju u user_subscriptions tabeli.
Rešavanje PostgreSQL izazova
Naišao sam na problem jer se baza nije automatski osvežavala kada bih dodao nove kolone u Python modele. Ručno sam "pregazio" bazu SQL komandama u pgAdmin-u kako bih dodao polja za notifikacije i ulazne cene, osiguravajući da backend i baza pričaju istim jezikom.
Email Alert Mašinerija
Povezao sam sistem sa Gmail SMTP serverom koristeći FastAPI-Mail. Najveći izazov ovde bio je slanje PDF dokumenata iz baze. Pošto su PDF-ovi u bazi binarni podaci, napravio sam logiku koja kreira privremeni fajl, šalje ga kao prilog i odmah ga briše sa diska kako ne bi zauzimao prostor.
Pametno grupisanje i personalizacija
Na kraju sam optimizovao slanje. Umesto da korisnik dobije tri različita mejla, sistem sada proverava njegove slajdere i pakuje sve bitne promene (cena, obim, %) u jedan jedini, lepo dizajniran HTML mejl. Ako je ugasio slajder za obim, taj podatak se dinamički izbacuje iz izveštaja.
#Next.js 14, React, Tailwind CSS, Lucide React, Recharts, Axios, FastAPI, Python, Uvicorn, Pydantic, PostgreSQL, SQLAlchemy, pgAdmin 4, JWT, OAuth2, Bcrypt, js-cookie, WebSockets, FastAPI-Mail, SMTP, Gmail API
Objavljeno: 27.04.2026
Razvoj WEB Frontend sistema za BGDX DigitalNakon što sam postavio "blindiran" backend, fokus sam prebacio na izgradnju korisničkog interfejsa. Moj cilj je bio jasan: kreirati platformu koja Beogradsku berzu uvodi u 21. vek, koristeći estetiku modernih fintech giganata poput Yahoo Finance-a.
1. Arhitektura i Postavka Projekta
Za osnovu sam izabrao Next.js sa App Router arhitekturom. Ovo mi je omogućilo da sajt podelim na logične rute (/dashboard, /login, /register) i iskoristim prednosti brzog učitavanja. Poseban trud sam uložio u rešavanje strukture foldera, osiguravajući da src direktorijum bude čist i pregledan, čime sam eliminisao konflikte pri renderovanju stranica.
2. Dizajn i Korisničko Iskustvo (UI/UX)
Sajt sam dizajnirao u tamnom modu (Dark Mode) koristeći Tailwind CSS.
Globalni Layout: Implementirao sam fiksni Sidebar sa leve strane i Topbar sa indeksima koji su vidljivi na svakoj stranici. Koristio sam specifičnu paletu boja (#0a0f18 i #0d121d) kako bih postigao taj "profesionalni terminal" osećaj.
Interaktivnost: Ubacio sam Lucide React ikonice za intuitivnu navigaciju i vizuelne indikatore (zeleno/crveno) za promene cena.
3. Autentifikacija na Frontendu
Povezao sam login i registraciju sa backendom koristeći Axios.
Implementirao sam Axios Interceptor koji automatski dodaje JWT token u svaki zahtev ka bazi.
Sesiju korisnika čuvam bezbedno pomoću js-cookie biblioteke, što omogućava da korisnik ostane ulogovan i nakon osvežavanja stranice.
Posebno sam obratio pažnju na povratne informacije (feedback) – forme sada jasno ispisuju greške ili uspeh pri registraciji.
4. Real-time Monitoring i Integracija Podataka
Ovo je srce aplikacije.
Povezao sam se na WebSocket mog backenda. Dashboard sada reaguje momentalno – čim scraper unese novu cenu u bazu, tabela na sajtu "zasija" i ažurira vrednost bez potrebe za osvežavanjem (refresh) cele stranice.
Koristio sam Promise.all za efikasno povlačenje inicijalnih cena, vesti i indeksa, čime sam postigao da se Dashboard učitava bleskovito brzo.
5. Debugging i Optimizacija
Tokom razvoja, uspešno sam rešio mrežne izazove (CORS polise i IP konfiguracije) i eliminisao kritične greške koje su blokirale komunikaciju između frontenda i API-ja. Osigurao sam da svaki deo koda (od Sidebara do glavne tabele) bude stabilan i spreman za dalju nadogradnju grafikona.
#Next.js 14, TypeScript, Tailwind CSS, Axios, Lucide React, js-cookie, WebSocket, React Hooks (useEffect, useState, useRef), Turbopack
Objavljeno: 27.04.2026
Razvoj WEB Backend sistema za BGDX MonitoringU prvoj fazi projekta, fokusirao sam se na izgradnju robustnog, skalabilnog i bezbednog backend sistema koji služi kao spona između mog Python scrapera i buduće web aplikacije. Evo detaljnog pregleda onoga što sam uradio:
1. Arhitektura i Tehnološka Osnova
Odlučio sam se za FastAPI framework zbog njegove brzine i nativne podrške za asinhrono programiranje. Sistem sam postavio modularno, razdvojivši logiku u posebne celine: modele baze podataka, Pydantic šeme za validaciju, rutere za API putanje i sigurnosne module. Ovakva struktura mi omogućava da lako proširujem sistem bez kvarenja postojeće logike.
2. Modelovanje Baze Podataka (PostgreSQL)
Koristeći SQLAlchemy 2.0 (moderni DeclarativeBase pristup), definisao sam relacionu bazu podataka koja pokriva sve aspekte berzanskog poslovanja.
Napravio sam tabele za:
Tickere: Centralna lista kompanija koje scraper prati.
Istoriju cena: Gde beležim svaku promenu cene, obim i promet.
Arhivu vesti: Sa podrškom za binarno čuvanje PDF dokumenata.
Indekse i Logove: Za praćenje BELEX15/BelexLine i zdravlja samog scrapera.
3. Autentifikacija i Sigurnost
Implementirao sam bezbednosni sistem baziran na OAuth2 protokolu i JWT (JSON Web Token) tokenima.
Lozinke korisnika se nikada ne čuvaju u čistom tekstu, već se hesiraju koristeći bcrypt algoritam.
Uveo sam uloge (Admin vs User) kako bih osigurao da samo ja mogu da menjam listu tickera, dok korisnici mogu da upravljaju samo svojim obaveštenjima.
4. Real-time Komunikacija i Notifikacije
Da bi sistem bio moderan, integrisao sam:
WebSockets: Napravio sam ConnectionManager koji omogućava da se cene na frontendu ažuriraju u realnom vremenu čim scraper pošalje podatak, bez potrebe za osvežavanjem stranice.
Email sistem: Koristeći fastapi-mail i Google App Passwords, omogućio sam slanje automatizovanih obaveštenja sa PDF prilozima.
5. "Bulletproof" Testiranje
Poseban akcenat stavio sam na kvalitet koda kroz rigorozno testiranje koristeći Pytest i Httpx.
Napisao sam 8 integracionih testova koji pokrivaju sve kritične tačke: od uspešne registracije i logovanja, preko zaštite ruta od neovlašćenog pristupa, pa sve do validacije formata podataka sa berze.
Rešio sam specifične probleme sa asinhronim loop-ovima na Windowsu i uskladio verzije biblioteka (poput bcrypt-a) kako bi testovi prolazili bez ijednog upozorenja (warnings) ili greške.
#FastAPI, Python 3.12, PostgreSQL, SQLAlchemy 2.0, Pydantic v2, JWT, OAuth2, Bcrypt, WebSockets, Fastapi-Mail, Pytest, Uvicorn, Httpx
Objavljeno: 26.04.2026
Razvoj BGDX-monitora v2.0Faza 1:
Stabilizacija i Validacija (Pydantic & Selenium)
Započeo sam rad na unapređenju sistema za praćenje Beogradske berze. Prvi izazov bio je prelazak Belex-a na novi format podataka za indekse (AmCharts JSON). Postojeći modeli su pucali jer su očekivali proste liste, a dobijali kompleksne objekte.
Implementirao sam Pydantic modele sa extra: allow konfiguracijom, što je omogućilo skriptama da "progutaju" metapodatke grafikona bez rušenja. Sredio sam mrežne logove u Seleniumu kako bih precizno hvatao JSON pakete (BELEX15 i BELEXline) direktno iz saobraćaja pretraživača.
Faza 2:
"Bulletproof" Arhitektura i Error Handling
Nakon stabilizacije podataka, fokusirao sam se na otpornost sistema. Uveo sam Explicit Wait mehanizme u scraper-e, čime sam eliminisao nasumične padove zbog sporog učitavanja stranica.
Sve skripte sam opremio preciznim try-except-finally blokovima. Poseban akcenat stavio sam na kulturno gašenje sistema – implementirao sam KeyboardInterrupt logiku koja pri pritisku na Ctrl+C momentalno i čisto zatvara sve brauzere i procese, bez ostavljanja "zombi" procesa u Task Manageru.
Faza 3:
Migracija na PostgreSQL
Izbacio sam nepraktične JSON fajlove i prešao na PostgreSQL bazu podataka. Kreirao sam unificiranu bazu BGDX_db sa sledećom strukturom:
Dinamičko upravljanje: Tabela tabela_tickera sada kontroliše koje akcije skraperi prate u realnom vremenu.
Istorija cena: Svaka promena cene se loguje sa vremenskim pečatom.
Binarna arhiva: Napravio sam sistem za download PDF vesti direktno u bazu koristeći BYTEA tip podataka. Više nema potrebe za eksternim folderima; fajlovi su sigurni unutar SQL-a.
Indeksi:
Za složene grafikone indeksa iskoristio sam JSONB tip kolone, što omogućava čuvanje celih AmCharts struktura uz zadržavanje brzine pretrage.
Faza 4:
Sistemsko Logovanje i Testiranje
Za potrebe budućeg Admin Panela, razvio sam centralizovani sistem logovanja. Svaki ERROR, WARNING ili CRITICAL događaj iz bilo kog modula automatski se upisuje u tabelu system_logs zajedno sa kompletnim stacktrace-om.
Na samom kraju, postavio sam Retention Policy koji automatski čisti bazu (cene nakon 90 dana, PDF vesti nakon 2 godine). Celu fazu krunisao sam sa 19 automatizovanih testova koji potvrđuju 100% ispravnost konverzije, validacije i komunikacije sa bazom.
Jezik: #Python3.12
Browser Automation: #Playwright #Selenium #Chromedriver
Validacija Podataka: #PydanticV2
Baza Podataka: #PostgreSQL #psycopg2 #JSONB #BYTEA
Testiranje: #Pytest
Upravljanje okruženjem: #Virtualenv (venv)
Frontend Formati: #JSON #AmCharts
#Python3.12, Playwright, Selenium,Chromedriver, PydanticV2, PostgreSQL, psycopg2, JSONB, BYTEA Testiranje, Pytest Upravljanje okruženjem, Virtualenv, venv, JSON, AmCharts
Objavljeno: 25.04.2026
Finalna integracija unificiranog BGDX Monitoring SistemaDanas sam zaokružio projekat kreiranjem centralnog upravljačkog modula BGDX_Monitor.py.
Ovim sam postigao potpunu automatizaciju prikupljanja podataka sa Beogradske berze u okviru jedinstvenog procesa.
Tehnička struktura sistema:
Master Script arhitektura:
Implementirao sam sistem koji koristi subprocess modul za sekvencijalno pokretanje tri nezavisna podsistema.
Ovakav pristup drži potrošnju RAM-a na minimumu jer se u svakom trenutku izvršava samo jedan browser proces.
Hijerarhija izvršavanja:
Monitor cena:
Svakih 5 minuta vrši skreping 20 najlikvidnijih akcija putem Playwright biblioteke.
Monitor indeksa:
Odmah nakon cena, pokreće se Selenium modul koji presreće JSON podatke za BELEX15 i BELEXline.
PDF Downloader:
Postavljen je uslovni ciklus (modulo operacija) koji na svakih sat vremena vrši proveru novih korporativnih dokumenata i preuzima ih u lokalnu arhivu.
Robusnost:
Sistem je očišćen od beskonačnih petlji unutar podmodula, čime je kontrola vremena i stabilnosti prebačena na Master skriptu.
Uvedena je try-except logika koja osigurava da eventualni pad jednog modula ne zaustavlja rad celog sistema.
Rezultat:
Sistem je uspešno testiran u realnim uslovima.
Krug prikupljanja svih podataka (cene + indeksi + vesti) traje prosečno oko 60-70 sekundi, nakon čega sistem odlazi u stanje mirovanja do sledećeg termina.
Projekat je spreman za migraciju na Linux server i "ubrizgavanje" u web aplikaciju.
Tagovi:
#systems-integration #automation #python-master #bgdx-production #data-harvesting
#systems-integration, automation, python-master, bgdx-production, data-harvesting
Objavljeno: 25.04.2026
Implementacija objedinjenog monitoringa tržišnih indeksa (BELEX15 i BELEXline)Danas sam uspešno razvio i integrisao modul za simultano praćenje dva glavna berzanska indeksa — BELEX15 i BELEXline.
Glavni izazov je bio u tome što sajt dinamički učitava podatke za ove indekse putem AJAX zahteva tek nakon interakcije korisnika, što sam rešio naprednom automatizacijom browsera.
Tehnička rešenja i logika:
Simulacija korisničkog ponašanja: Kako bi sistem "naterao" server da pošalje podatke za oba indeksa, implementirao sam logiku koja prvo učitava osnovnu stranu (gde je BELEX15 podrazumevan), a zatim programski vrši klik na tab BELEXline. Time sam izazvao generisanje specifičnog mrežnog saobraćaja koji je neophodan za prikupljanje podataka.
Presretanje mrežnog saobraćaja (Network Interception):
Umesto klasičnog skrepovanja HTML-a, konfigurisao sam Selenium da prati performance logove browsera. Ovom metodom presrećem direktne JSON odgovore sa servera (indeksi.php).
Prednost ovog pristupa je maksimalna preciznost, jer dobijam sirove podatke namenjene za iscrtavanje grafikona na samom sajtu.
Objedinjavanje podataka:
Razvio sam mehanizam koji razdvaja logove pre i posle klika. Podatke prikupljene iz oba "hvatanja" spajam u jedan unificirani fajl belex_15_line.json.
Na ovaj način dobijam strukturiranu bazu koja sadrži kompletan dataProvider niz (istoriju kretanja), trenutne vrednosti i procente promene za oba indeksa na jednom mestu.
Optimizacija i stabilnost:
Upravljanje sesijom:
Skripta je dizajnirana tako da svako osvežavanje (na 5 minuta) radi u potpuno novoj sesiji, što sprečava detekciju botova i curenje memorije na serveru.
Headless režim:
Sistem radi u "nevidljivom" režimu, što ga čini idealnim za rad u pozadini na Linux serveru bez grafičkog interfejsa.
#selenium, chrome-performance-logs, BELEX15, BELEXline, ajax-interception, user-simulation, data-aggregation
Objavljeno: 25.04.2026
Implementacija sistema za automatsko prikupljanje korporativne dokumentacijeDanas sam razvio i pustio u rad specijalizovani modul za automatsko preuzimanje zvaničnih dokumenata (PDF i DOCX) sa Beogradske berze (BGDX). Fokus ovog modula je na praćenju objava izdavalaca, kao što su godišnji izveštaji, sazivanja skupština akcionara i odluke o dividendama.
Tehnička realizacija:
Targetiranje podataka:
Skripta mapira HTML strukturu tabele sa klasom vesti i precizno izvlači datum objave, naslov vesti i relativnu putanju do dokumenta.
Pametno filtriranje:
Implementirao sam logiku koja prati objave u okviru poslednja dva dana (danas i juče). Ovo je ključno za osiguravanje kontinuiteta podataka, naročito nakon neradnih dana ili vikenda.
Sistem protiv duplikata:
Kreirao sam lokalnu bazu u JSON formatu (downloaded_docs.json) koja služi kao registar svih preuzetih dokumenata. Sistem pre svakog downloada vrši proveru linka – ukoliko link postoji u bazi, proces se preskače, čime štedim prostor na disku i mrežni saobraćaj.
Automatizacija skladištenja:
Dokumenti se automatski preuzimaju putem requests biblioteke i skladište u folder vesti. Imena fajlova se dinamički generišu u formatu Datum_Ticker_Naslov, što omogućava laku kasniju pretragu i preglednost.
Optimizacija za 24/7 rad:
Modul je podešen da se aktivira ciklično na svakih sat vremena.
Posebnu pažnju sam posvetio upravljanju memorijom na Linux serveru: Playwright instanca se u potpunosti podiže i gasi unutar svakog ciklusa, čime je eliminisana mogućnost curenja memorije (memory leak) tokom dugotrajnog rada.
Rezultat:
Sistem je uspešno testiran i već je automatski povukao najnovije godišnje izveštaje za tikere poput AERO i ENHL. Modul će sada raditi potpuno samostalno u pozadini na kućnom serveru.
#python, playwright, requests, json, datetime, web-scraping, automation, data-storage, memory-management, linux, debian, background-process
Objavljeno: 25.04.2026
Implementacija ekstrakcije kompletne tabele tickera (Deep Scraping)Nakon što sam uspešno implementirao brz monitoring trenutne cene akcija (odziv ~10s za celu listu), naišao sam na značajnu prepreku pri pokušaju da izvučem celu tabelu sa podacima (Promena, Obim, Promet, VWAP, High/Low).
Moji prvobitni pokušaji su rezultirali konstantnim FAIL statusima i Timeout greškama. Identifikovao sam dva uzroka:
Anti-Bot Zaštita: Pokušaji da "pametno" parsiram celu HTML tabelu odjednom ili da šaljem višestruke zahteve ka istom URL-u su aktivirali Rate Limiting na serveru berze, što je dovodilo do blokiranja konekcije.
Asinhrono Učitavanje: Iako je commit status brz, podaci u tabeli se nekad ne renderuju istog milisekunde kada stigne zaglavlje stranice.
Rešenje (Metodologija)
Umesto komplikovanja sa masovnim izvlačenjem podataka (evaluate cele tabele) ili usporavanja skripte (čekanje CSS-a i slika), odlučio sam da primenim identičnu logiku koja je radila za cenu, ali iterativno.
Shvatio sam ključnu stvar: Ako je Browser učitao polje "Cena", kompletan HTML stranice je već u memoriji. Nema potrebe za novim mrežnim saobraćajem.
Implementirani algoritam:
Setup: Zadržao sam agresivni "Speed Hack" (blokiranje CSS-a, slika, fontova) i headless mod za maksimalnu brzinu.
Navigacija: Koristim page.goto sa wait_until="commit" – ovo je najbrži mogući način da dobijem sirovi HTML.
Sidro: Čekam isključivo da se pojavi element //td[text()='Cena']. Ovo mi služi kao potvrda da je tabela spremna.
Lokalna Ekstrakcija: Umesto ponovnog učitavanja, definisao sam dictionary sa svim poljima koja me zanimaju. Skripta zatim "peške" prolazi kroz taj rečnik i za svako polje primenjuje locator na već učitanoj stranici.
Tehnička Realizacija (Code Snippet Python koda):
# Ključni deo logike koji je rešio problem
base_xpath = "//td[text()='Cena']/following-sibling::td"
page.wait_for_selector(f"xpath={base_xpath}", timeout=5000)
# Iteracija kroz polja bez novih mrežnih zahteva
for label, key in fields.items():
xpath = f"//td[text()='{label}']/following-sibling::td"
raw_val = page.locator(f"xpath={xpath}").first.inner_text().strip()
#python, playwright, optimization, data-mining, belex-api, json, troubleshooting
Objavljeno: 25.04.2026
Automatizovani monitoring Beogradske berze (BGDX)U okviru ovog zadatka, razvio sam Python skriptu za ekstrakciju podataka u realnom vremenu sa Beogradske berze.
Cilj je bio napraviti izuzetno brz i robustan sistem koji može da obiđe listu najznačajnijih kompanija (tickera) i prikupi poslednje cene trgovanja bez suvišnog opterećenja procesora i mreže.
Ključne faze i tehnike koje sam primenio:
Izbor tehnologije (Playwright):
Odlučio sam se za Playwright biblioteku jer omogućava preciznu kontrolu nad browser enginom (Chromium).
Za razliku od običnih HTTP zahteva, Playwright mi dozvoljava da simuliram realno ponašanje korisnika, što je ključno za sajtove koji dinamički generišu sadržaj poput berzanskih tabela.
SII Speed Hack (Optimizacija resursa):
Ovo je najbitniji deo mog koda. Implementirao sam presretanje mrežnih zahteva putem page.route.
Skripta detektuje i automatski blokira učitavanje slika, CSS stilova i fontova.
Na taj način, stranica se učitava kao "ogoljeni" HTML, što je ubrzalo proces za više od tri puta i omogućilo da se ceo monitoring završi za oko 15 sekundi.
Napredna navigacija i selektori:
Koristio sam wait_until="commit" parametar. To znači da skripta ne čeka da se stranica potpuno "nacrta" u browseru, već kreće u akciju čim server pošalje prvi bajt podataka.
Podatke pronalazim koristeći preciznu XPath lokaciju: //td[text()='Cena']/following-sibling::td.
Ovaj selektor je veoma pouzdan jer traži ćeliju koja sadrži reč "Cena", a zatim uzima vrednost iz prve susedne ćelije, bez obzira na to gde se ona nalazi u tabeli.
Obrada i čuvanje podataka:
Sistem automatski vrši konverziju "srpskog" formata brojeva (gde je tačka separator za hiljade, a zarez za decimale) u standardni float tip koji Python prepoznaje.
Sve prikupljene informacije se na kraju procesa pakuju u JSON format (live_prices.json), što omogućava lakšu integraciju sa drugim aplikacijama ili bazama podataka.
Robustnost i Error Handling:
Predvideo sam try-except blokove koji sprečavaju pucanje skripte u slučaju da neki tiker trenutno nema trgovanja ili je server berze privremeno nedostupan.
Skripta u tim situacijama samo markira tiker kao "FAIL" i nastavlja dalje bez zastoja.
#python, playwright, webscraping, belex, automation, dataengineering, speedoptimization, json, fintech
Objavljeno: 23.04.2026
Prepravljen refresh dashboard-a (problem sa komentarima)Chatter update-ovan dashboard:
function refreshNews() {
// Provera da li je kursor u polju za kucanje
const active = document.activeElement;
const isTyping = active && (active.tagName === 'INPUT' || active.tagName === 'TEXTAREA');
if (isTyping) {
console.log("Kucanje u toku... osvežavanje vesti je pauzirano.");
return; // Prekida funkciju i ne osvežava ništa
}
fetch('fetch_news.php')
.then(r => r.text())
.then(data => {
document.getElementById('dynamic-news').innerHTML = data;
});
}
#php
Objavljeno: 23.04.2026
TEHNIČKA DOKUMENTACIJA RAZVOJA CHATTER APLIKACIJEDanas sam sproveo niz kritičnih ažuriranja na Chatter ekosistemu, fokusirajući se na mrežnu transparentnost, bezbednosne protokole, dinamičku interakciju podataka i potpunu rekonstrukciju korisničkog interfejsa (UI/UX).
1. Arhitektura mreže i identifikacija (IP Transparency)
Prvi izazov bio je rešavanje problema maskiranja IP adresa unutar Tailscale Funnel okruženja. Implementirao sam konfiguraciju za Apache RemoteIP modul kako bih ekstrahovao stvarne adrese posetilaca iz X-Forwarded-For zaglavlja. Ovo mi je omogućilo precizan logging sistem koji u bazu podataka beleži unikatne sesije, povezujući javni IP sa korisničkim profilom u realnom vremenu.
2. Implementacija bezbednosnog podsistema (Cyber-Security)
Razvio sam robusnu dvoslojnu barijeru za kontrolu pristupa:
User/IP Ban logika: Kreirao sam relacione tabele za trajno blokiranje specifičnih ID-eva i mrežnih opsega.
Aktivna terminacija sesije: Modifikovao sam centralni db_chatter.php fajl tako da pri svakom server-side zahtevu proverava status korisnika. Ukoliko detektujem ban, skripta vrši momentalnu session_destroy() operaciju i vrši preusmeravanje na stilizovanu "Access Denied" stranicu, efektivno izbacujući blokiranog korisnika iz sistema bez obzira na njegovu trenutnu aktivnost.
3. Dinamički Data-Stream (AJAX & Real-time)
Eliminisao sam zastareli model osvežavanja cele stranice (Full-page reload).
Asinhroni Dashboard: Koristeći JavaScript fetch API i PHP endpoint-e (fetch_sidebar.php, fetch_news.php), omogućio sam pozadinsko ažuriranje liste prijatelja i vesti.
Sistem interakcije: Implementirao sam AJAX logiku za lajkove i komentare. Ovo omogućava korisnicima da komuniciraju sa objavama bez gubitka pozicije skrola, što značajno unapređuje UX.
Audio Feedback: Integrisao sam event-listener koji prati promenu broja nepročitanih poruka i aktivira MsgSound.mp3 samo pri detekciji novog dolaznog saobraćaja.
4. Admin-Centric kontrola (Ghost Mode)
Konstruisao sam Admin Panel koji koristi SQL GROUP BY i MAX() funkcije za prikazivanje unikatnih, hronoloških logova. Poseban tehnički podvig je Ghost Mode unutar chat.php i group_chat.php. Admin sada može pristupiti bilo kojoj konverzaciji putem URL parametara, pri čemu sistem:
Onemogućava seen update upite u bazu.
Blokira formu za slanje poruka na backend nivou.
Uklanja administrativne elemente iz UI-ja kako bi osigurao neprimetno nadgledanje.
5. Rekonstrukcija UI/UX i Mobilni odziv (Responsive Design)
Izvršio sam potpunu migraciju stilova u centralni style.css i primenio modernu Flexbox/Absolute hibridnu strukturu:
"Push" Layout u grupama: Implementirao sam sidebar članova koji se uvlači i izvlači pomoću CSS transition i transform svojstava, fizički pomerajući (guranje) čet-prostor umesto preklapanja.
Fiksirani slojevi: Osigurao sam da chat-header i input-container imaju visoke z-index vrednosti i fiksne pozicije, dok se sadržaj između njih skroluje kroz definisane visine (calc(100vh - offsets)).
Zlatni UI akcenti: Dizajnirao sam specifične klase za interaktivna dugmad sa border-box ramom i box-shadow efektom na hoveru, dajući aplikaciji premium "dark-mode" izgled.
#PHP PDO Security, Asynchronous Fetch, Real-time DOM Manipulation, Session Persistence Control, Responsive CSS Grid/Flex, Cross-device Optimization, Dynamic UI State, SQL Relational Joins, Data Normalization, Upsert Logic.
Objavljeno: 22.04.2026
Deployment "Chatter" sistema na Debian 12: Od SCP transfera do SQL migracijeNakon završenog razvoja Chatter aplikacije u lokalnom okruženju (XAMPP), uspešno je izvršen prenos sistema na Debian 12 server. Ovaj proces obuhvatio je mrežnu konfiguraciju, migraciju relacione baze podataka i fino podešavanje Linux permisija.
1. Transfer fajlova putem SSH protokola
Za prenos izvornog koda sa Windows radne stanice na Linux server korišćen je SCP (Secure Copy) protokol unutar Git Bash terminala.
Izazov: Prvobitni pokušaj transfera je odbijen zbog restriktivnih dozvola nad /var/www/html/ direktorijumom.
Rešenje: Privremeno je promenjeno vlasništvo nad ciljnim folderom komandom chown i dodeljena su prava pisanja (777), nakon čega je celokupna struktura projekta (PHP, CSS, JS) uspešno prebačena.
2. Migracija baze podataka (SQL Dump & Import)
Migracija podataka sa laptopa na server izvedena je u tri faze:
Eksport: Korišćenjem uslužnog programa mysqldump, kreirana je "slika" baze chatter_db.sql.
Transfer: SQL fajl je prebačen u kućni direktorijum korisnika na serveru.
Import: Na serveru je kreirana nova baza, a zatim je pomoću MariaDB CLI-ja izvršen uvoz podataka:
sudo mariadb -u root chatter_db < chatter_db.sql.
3. Konfiguracija Database Autentifikacije
Zbog Debianovog unix_socket bezbednosnog modela, PHP aplikacija nije mogla da pristupi bazi koristeći root nalog.
Inženjersko rešenje: Implementiran je princip najmanjih privilegija. Kreiran je namenski korisnik nikic_admin sa lozinkom, kojem su dodeljena sva prava isključivo nad bazama dnevnik_rada_db i chatter_db.
Refaktorisane su konekcione žice u db_chatter.php kako bi koristile nove kredencijale, čime je eliminisana greška Access denied (1698).
4. Optimizacija Linux okruženja (Permissions & Sessions)
Da bi aplikacija funkcionisala besprekorno u multi-user okruženju, izvršena su završna podešavanja:
Session Fix: Folder /var/lib/php/sessions je osposobljen za upisivanje podataka sesija, što je ključno za Login sistem.
Ownership: Vlasništvo nad aplikacijom je vraćeno na www-data (Apache korisnik) uz 755 permisije, čime je postignut balans između funkcionalnosti i sigurnosti.
Tailscale Integration: Sistem je u potpunosti dostupan unutar privatne mesh mreže, omogućavajući siguran pristup dashboard-u sa bilo koje lokacije bez izlaganja servera javnim pretnjama.
Zaključak:
Projekat je uspešno prešao iz faze razvoja u fazu eksploatacije. Postavljena je infrastruktura koja podržava skalabilnost (grupe i prijateljstva) i real-time monitoring (Online status), uz punu kontrolu nad podacima putem terminala.
#ssh-deployment, scp-transfer, mariadb-migration, debian-admin, php-sessions, sql-privileges, infrastructure-as-code
Objavljeno: 22.04.2026
Razvoj i Deployment "Chatter" aplikacije – Kompletan Real-Time Messenger sistemNakon uspešnog osnovnog portfolija, prešao sam na razvoj "Chatter" aplikacije, kompleksnog sistema za komunikaciju u realnom vremenu.
Cilj je bio prevazići statične stranice i napraviti dinamičko okruženje sa bazom podataka koje simulira rad modernih messengera poput Discord-a ili Slack-a.
1. Inženjerski dizajn baze podataka (SQL Arhitektura)
Srce aplikacije je relaciono modelovana baza podataka na MariaDB serveru. Umesto prostih fajlova, koristio sam četiri međusobno povezane tabele:
users: Sa last_seen timestamp-om za praćenje online statusa.
friends: Implementacija sistema zahteva (pending/accepted) za kontrolu privatnosti.
chat_groups & group_members: Kompleksna "mnogo-prema-mnogo" (many-to-many) veza koja omogućava korisnicima da kreiraju i upravljaju grupnim četovima.
private_messages: Centralizovana tabela za sve poruke, optimizovana da podrži i 1-na-1 i grupne razgovore kroz group_id i receiver_id atribute.
2. Backend logika i Funkcionalnosti (PHP & AJAX)
Aplikacija je razvijena korišćenjem PHP 8.2 uz striktnu upotrebu PDO prepared statements radi prevencije SQL Injection napada.
Real-time Interakcija:
Koristio sam asinhroni JavaScript (AJAX Fetch) i setInterval funkciju kako bi se poruke i statusi (Seen, Online) osvežavali bez potrebe za ponovnim učitavanjem stranice.
Seen Status: Razvio sam algoritme koji prate pročitane poruke. U grupama, sistem precizno broji koliko je članova videlo poruku ("Seen by 2", "Seen by all").
Online Heartbeat: Implementiran je sistem koji na svakih 5 minuta proverava aktivnost korisnika i vizuelno prikazuje "Online" lampicu ili "Last Seen" informaciju (npr. "Aktivan pre 15 min").
3. Linux Server Administracija (Debian 12 Deployment)
Projekat je sa lokalnog XAMPP okruženja prebačen na Debian 12 server unutar Tailscale privatne mreže.
Konfiguracija sesija: Rešen je kritičan problem sa dozvolama na Debianu postavljanjem chmod 777 na /var/lib/php/sessions folderu, čime je omogućen stabilan login sistem.
Sigurnost pristupa: Kreiran je poseban DB korisnik sa ograničenim privilegijama, a root pristup bazi je ostavljen isključivo za sistemsku administraciju putem terminala.
Automatizacija: Napisan je Bash Alias (backup) koji vrši instant dump cele chatter_db baze sa vremenskim pečatom u nazivu fajla.
4. UI/UX i Administracija
Dark Modern Design: Interfejs je rađen u tamnim tonovima sa fokusom na čitljivost i "stretch" oglasnu tablu koja popunjava sav slobodan prostor na ekranu.
Admin Dashboard: Kao vlasnik sistema, implementirao sam "Globalnu oglasnu tablu" – centralno mesto gde samo moj nalog (snikic01) može da objavljuje vesti i obaveštenja koja vide svi korisnici.
Ključne komande i tehnologije:
Tehnologije: PHP, MySQL/MariaDB, JavaScript (ES6), CSS3 Variables.
Linux: chown, systemctl, mysqldump, nano, tail -f (za logove).
Network: Tailscale (VPN/Mesh), SSH.
Ovaj projekat za sada predstavlja krunu mog dosadašnjeg rada jer spaja softversko inženjerstvo, administraciju baza i sistemsko inženjerstvo u jednu funkcionalnu celinu dostupnu sa bilo kog mesta na svetu.
#full-stack, debian, php-pdo, real-time-chat, sql-design, devops, tailscale, ssi-diploma
Objavljeno: 22.04.2026
Automatizacija i održavanje: Implementacija Backup sistema na Debian serveruNakon uspešnog deployment-a aplikacije, fokus sam prebacio na obezbeđivanje podataka. Kao softverski inženjer, svestan sam da sistem vredi onoliko koliko su sigurni podaci u njemu.
Zbog toga sam implementirao rešenje za brzu rezervnu kopiju baze podataka direktno kroz Linux terminal.
Tehničko rešenje:
Kreirao sam Bash Alias koji automatizuje proces eksportovanja MariaDB baze podataka. Umesto ručnog kucanja dugačkih mysqldump komandi, proces je sveden na jednu reč.
Implementacija:
Konfiguracija Bash okruženja: Modifikovao sam .bashrc fajl svog korisnika na Debianu.
Dinamičko imenovanje: Koristio sam Linux funkciju $(date +%F_%H-%M) unutar komande, što omogućava da svaki backup fajl u nazivu nosi tačan datum i vreme kreiranja (npr. dnevnik_backup_2026-04-22_02-40.sql).
Alias komanda:
bash
alias backup='mysqldump -u nikic_admin -p[lozinka] dnevnik_rada_db > ~/dnevnik_backup_$(date +%F_%H-%M).sql'
Zašto je ovo bitno?
Ovim korakom sam postigao:
Brzinu: Backup celog sistema traje manje od sekunde.
Sigurnost: Podaci su sada lako prenosivi. Zahvaljujući Tailscale mreži, ove SQL dump-ove mogu lako da povučem na bilo koji uređaj u mojoj privatnoj mreži koristeći scp protokol.
Verzionisanje:
Svaki backup je jedinstven fajl, što mi omogućava da se vratim na bilo koju prethodnu verziju dnevnika ako dođe do greške pri eksperimentisanju sa kodom.
Ovim je ciklus razvoja ovog projekta zaokružen, od ideje i koda, preko deployment-a, do strategije održavanja podataka.
#linux-alias, bash, mysqldump, debian, automation, data-integrity, backup-strategy
Objavljeno: 22.04.2026
Full-stack Deployment: Od Windows XAMPP-a do Debian 12 ServeraSadržaj:
Ovaj projekat je bio test izdržljivosti u rešavanju problema koji nastaju pri migraciji aplikacije iz Windows okruženja na pravi Linux server. Cilj je bio napraviti "ogoljeni" Reddit klon za dnevnik rada, fokusiran na brzinu, sigurnost i minimalizam.
1. Faza: Razvoj i Arhitektura (PHP & SQL)
Projekat je građen na PHP 8.2 jeziku. Glavni fokus je bio na sigurnosti podataka, pa sam odbacio zastarele metode i koristio:
PDO (PHP Data Objects): Za komunikaciju sa bazom, što mi omogućava lakšu migraciju između različitih SQL sistema.
Prepared Statements: Svaki unos (naslov, sadržaj, keywords) prolazi kroz pripremljene upite, čime je eliminisana mogućnost SQL Injection napada.
Bcrypt Hashing: Lozinka se u bazi nikada ne čuva kao običan tekst. Koristio sam funkcije password_hash() i password_verify() za industrijski standard zaštite admin naloga.
2. Faza: Linux Administracija (Debian 12)
Nakon što je kod bio spreman na laptopu, prešao sam na SSH administraciju mog Debian servera. Ovde sam koristio niz sistemskih funkcija:
SCP (Secure Copy): Za prenos fajlova i SQL dump-ova sa lokalne mašine na server (scp -r).
Apt Package Manager: Instalacija kompletnog steka – apache2, mariadb-server i php-mysql modula.
Systemd (systemctl): Upravljanje servisima, restartovanje Apache-a i MariaDB-a nakon svake promene konfiguracije.
Dozvole i Vlasništvo: Jedan od većih izazova bio je usklađivanje dozvola. Koristio sam chown -R www-data:www-data da dam Apache-u vlasništvo nad fajlovima, i chmod za rešavanje problema sa PHP sesijama u /var/lib/php/sessions.
3. Faza: Troubleshooting & Debugging
Najveća lekcija bila je razlika u autentifikaciji. Debianov MariaDB po defaultu koristi unix_socket za root-a, što je onemogućavalo PHP-u pristup. Problem sam rešio kreiranjem posebnog baze podataka korisnika sa mysql_native_password metodom. Takođe, rešio sam problem sa Apache portovima menjajući Listen direktivu u httpd.conf kako bih izbegao konflikte.
Ključne komande koje sam savladao:
ls -la i pwd – navigacija i provera skrivenih fajlova.
sudo nano – editovanje konfiguracionih fajlova direktno na serveru.
mariadb -u root -e "..." – izvršavanje SQL komandi bez ulaska u konzolu.
tail -f /var/log/apache2/error.log – praćenje grešaka u realnom vremenu (ključno za rešavanje 500 i 404 grešaka).
Zaključak:
Sistem sada radi stabilno na public IP adresi koju sam osposobio preko Tailscale-a, ima funkcionalnu pretragu po keywordovima i siguran admin panel. Ovaj projekat je bio odlična vežba u spajanju web programiranja i sistemskog inženjeringa.
#debian, linux-admin, php-pdo, mysql, scp, ssh, web-security, Apache
Objavljeno: 22.04.2026
Ovo je test2Ovo je prvi post testiram da li konacno radi na serveru?
#test
Objavljeno: 22.04.2026
TestiranjeTestiram keyword
#Test
Objavljeno: 22.04.2026
Kreacija Dnevnika radaDanas sam napravio php aplikaciju sa admin panelom, ovde cu kaciti buduce radove!
#php, linux