Jugoton

Online prodavnica vinila: PHP, MySQL i Oracle Cloud

Funkcionalna online prodavnica vinila s punim CRUD-om, u kojoj sama baza čuva zalihe, narudžbe i adrese. Postavljena uživo na Oracle Cloud.

Status
Univerzitetski projekt
Uloga
Full-stack developer, tim od dvoje (sa Sajrom Agić); postavljanje u cloud uradio sam samostalno
Period
Proljeće 2026., SSST (CS270, CS240 i CS260), postavljeno u junu 2026.
Platforme
Responzivna web aplikacija
  • 10tabela
  • 30+poslovnih pravila
  • 2okidača, plus pogled, procedura i funkcija
  • 4indeksa za pretragu i izvještaje

Cijeli demo, pa svaki ekran

Dodavanje ploče kao admin. Odabir izvođača pokreće upit prema iTunes Search API-ju koji popunjava datum izlaska i iTunes ID, a omot se preuzima pri snimanju. Zatim stranica ploče s pregledom od 30 sekundi i recenzijama. Spori dijelovi su ubrzani (oznaka prikazuje brzinu).
Početna stranica Jugotona s najnovijim pločama
Početna: najnovije ploče i dugme menija u obliku ploče.
Stranica ploče s iTunes plejerom i listom pjesama
Stranica ploče s pregledom od 30 sekundi preko iTunes embeda.
Stranica za filtriranje po žanru
Stranica žanrova. Ploča može pripadati više žanrova.
Rezultati pretrage za izvođača
Pretraga po nazivu albuma ili imenu izvođača.
Bočna korpa s pločom i ukupnom cijenom
Korpa se otvara sa strane, s količinom i ukupnom cijenom.
Forma za recenziju i recenzije kupaca
Recenzije: ocjena obavezna, komentar nije, jedna po korisniku i ploči.
Admin panel s najprodavanijim pločama, najboljim kupcima i posljednjim narudžbama
Admin panel: najprodavanije ploče, najbolji kupci, posljednje narudžbe i zalihe.
Izvještaj o najprodavanijim pločama
Izvještaj o prodaji, čitan iz pogleda (view) u bazi.
Forma za dodavanje nove ploče
Dodavanje ploče. Podaci se popunjavaju iz iTunes Search API-ja.

Strana A

A1IdejaŠta je i zašto

Vinili su ponovo popularni, pa smo napravili Jugoton, prodavnicu ploča nazvanu i stilizovanu po staroj jugoslavenskoj izdavačkoj kući: tamna, s narandžastim detaljima. Projekt je morao zadovoljiti dva predmeta, pa je istovremeno kompletna web aplikacija i pravilno dizajnirana baza. Krenuli smo od napisanih poslovnih pravila, napravili ER model i normalizovali ga prije pisanja koda aplikacije.

Napravljeno za dva predmeta odjednom, Web okruženja (CS270) i Baze podataka (CS240), u timu od dvoje, a zatim postavljeno na Oracle Cloud za treći, Cloud Computing (CS260). Kupci pregledaju, pretražuju, filtriraju po žanru, preslušavaju pjesme, ocjenjuju ploče i kupuju; admini dodaju, mijenjaju i brišu ploče i izvođače i čitaju izvještaje o prodaji.

A2Šta sam napravio7 dijelova
  • Responzivan front end u čistom HTML-u, CSS-u i JavaScriptu, bez frameworka, s dugmetom menija u obliku ploče.
  • Katalog s novim pločama, pretraga po naslovu ili izvođaču, filtriranje po žanru sa stranicama i stranice ploča s iTunes pregledom pjesama.
  • Registracija i prijava s heširanim lozinkama i sesijama, profil sa stanjem računa i odvojeni dijelovi za kupce i admine.
  • Bočna korpa, plaćanje koje u jednoj transakciji umanjuje stanje i zalihu i recenzije (jedna po korisniku i ploči, ažurirane jednim upitom).
  • Admin panel s punim CRUD-om za ploče i izvođače, zalihama i izvještajima: najprodavanije, najvredniji kupci, posljednje narudžbe.
  • Nove ploče se automatski popunjavaju iz iTunes Search API-ja (datum izdanja, ID pregleda, žanr); omoti su u Oracle Cloud Object Storageu.
  • MySQL baza: 10 tabela, 30+ poslovnih pravila, 4 indeksa, pogled za analitiku prodaje, procedura za narudžbe, funkcija za nivo kupca i 2 okidača.

Tehnologije: PHP, HTML, CSS, JavaScript, MySQL/MariaDB, phpMyAdmin, iTunes Search API, Oracle Cloud Object Storage, GitHub; deployment: Oracle Cloud Infrastructure, Ubuntu 24, Nginx, PHP 8.4-FPM, Oracle Autonomous Database, OCI8

A3Kako radidijagrama: 2

Plaćanje, korak po korak

Korpaploče i količineForma za plaćanjeadresa dostavesp_place_orderJedna transakcija1 Provjera da ploča postoji2 Provjera zalihe3 Kreiranje narudžbe4 Dodavanje stavki, umanjenje zalihePotvrdanarudžba primljenaPoništenjeništa se ne mijenjaOkidač na Order_Itemsblokira količinu veću od zalihe
Narudžba je sve ili ništa. Baza sprječava prodaju preko zalihe čak i ako aplikacija to propusti.

Dijagram entiteta i veza

Dijagram entiteta i veza
Konačna šema: deset tabela, uključujući veznu tabelu Vinyl_Genres za vezu više-prema-više.
A4Tehnički detalj: baza provodi pravilaDetaljnije

Neka pravila su previše bitna da bi se prepustila kodu aplikacije. Okidač zaustavlja svaku stavku narudžbe koja traži više primjeraka nego što ima na zalihi, a drugi okidač čuva tačno jednu zadanu adresu po korisniku. Narudžba ide kroz pohranjenu proceduru kao jedna transakcija: provjerava ploču i zalihu, pravi narudžbu, dodaje stavku i umanjuje zalihu, a ako jedan korak ne uspije, sve vraća nazad. Sljedeći planirani korak je prebacivanje svih upita na prepared statements.

tr_verify_vinyl_stock.sql
CREATE TRIGGER tr_verify_vinyl_stock
BEFORE INSERT ON Order_Items FOR EACH ROW
BEGIN
  DECLARE current_stock INT;
  SELECT stock INTO current_stock FROM Vinyls WHERE vinyl_id = NEW.vinyl_id;
  IF current_stock < NEW.quantity THEN
    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'Transaction aborted: Insufficient vinyl inventory available.';
  END IF;
END

Iz izvještaja projekta. Okidač se pokreće prije snimanja svake stavke narudžbe.

Strana B

B1Postavljanje na Oracle Cloud (CS260 Cloud Computing)Ubuntu, Nginx, PHP-FPM, MySQL

Za predmet Cloud Computing (CS260) samostalno sam postavio istu aplikaciju uživo na Oracle Cloud Infrastructure u junu 2026. Radi na Ubuntu 24 virtualnoj mašini kao klasična troslojna postavka: Nginx servira statične fajlove, PHP 8.4-FPM izvršava PHP, a MySQL čuva podatke. Kopija baze nalazi se i u Oracle Autonomous Database. Cloud server je bio dio kursa i može biti ugašen, pa video na ovoj stranici prikazuje cijeli tok.

Oracle Cloud (OCI)Ubuntu 24 virtualna mašinaPreglednikposjetilacNginxservira CSS,slike, HTMLPHP 8.4-FPMizvršava PHPskripteMySQLvinyl_shopsamo localhostPort 80 otvoren, port 3306 zatvoren prema internetuAutonomous DBOracle kopijapodataka:80OCI8socket
Tri sloja na jednoj Oracle Cloud virtualnoj mašini, uz Oracle Autonomous Database koji čuva kopiju podataka.

Šta sam uradio

  1. Spojio sam se na VM preko SSH-a, ažurirao sistem i klonirao repozitorij s GitHuba u Nginx web root, u vlasništvu korisnika www-data.
  2. Napisao sam Nginx server block koji PHP fajlove prosljeđuje PHP-FPM-u preko Unix socketa.
  3. Instalirao sam MySQL, napravio bazu vinyl_shop i posebnog korisnika i uvezao SQL export projekta.
  4. Otvorio sam port 80 u OCI security listi i firewallu VM-a, a MySQL port ostavili zatvorenim, pa bazi može pristupiti samo sama VM.
  5. Izvezao sam podatke s mysqldump i ručno prepravio skriptu za Oracle (NUMBER umjesto INT UNSIGNED, sekvence umjesto AUTO_INCREMENT, TO_DATE za datume), pa je učitao u Oracle Autonomous Database preko SQL Developer Weba.
  6. Izgradio sam PHP ekstenziju OCI8 uz Oracle Instant Client, da se PHP može spojiti na Autonomous Database za sinhronizaciju i izvještaje.

Šta se pokvarilo i kako sam to našao

  • Svaka stranica je vraćala grešku 500. Nginx error log je pokazao da se PHP prijavljuje u MySQL korisnikom koji je postojao samo na našim računarima, a index.php je imao i svoju drugu konekciju upisanu u kod. Popravio sam db.php, pa sve ostale reference pronašao s grep.
  • Neke stranice su javljale da tabele poput Artists ne postoje. MySQL na Windowsu ne razlikuje velika i mala slova u imenima tabela, a na Linuxu razlikuje. Preširoka zamjena sa sed ispraznila je nekoliko fajlova. Vratio sam ih s git checkout i ponovio popravku sa šablonima za granice riječi.
  • Build OCI8 nije mogao naći oci.h, a PHP-FPM nije mogao učitati libclntsh.so. PECL sam usmjerio na folder Instant Clienta i LD_LIBRARY_PATH učinio dostupnim korisniku www-data.

Šta bi prava produkcija promijenila

Jedna VM je dovoljna za predmet, ali ne i za prave kupce. Produkcija bi bazu prebacila na upravljani servis, postavila load balancer ispred više aplikacijskih servera, sve servirala preko HTTPS-a, čuvala pristupne podatke u OCI Vaultu umjesto u kodu i postavljala nove verzije kroz CI/CD pipeline umjesto ručno preko SSH-a. Najveća lekcija je bila čitati logove: nijedna prava greška se nije vidjela u pregledniku.

Oracle SQL Developer Web s listom Jugoton tabela u Autonomous Database
Sve tabele projekta uvezene u Oracle Autonomous Database.
Nginx error log u kojem PHP ne uspijeva da se prijavi u MySQL
Prvi trag: Nginx error log iza grešaka 500.