Sledi
Android aplikacija za sledenje serijam in filmom, narejena kot nadomestilo za TV Time po njegovem zaprtju — s sinhronizacijo na Postgresu, skupnim predpomnilnikom metapodatkov in uvozom, ki reši leta zgodovine ogledov.

Infrastruktura
Aplikacijskega strežnika ni. Odjemalec se prek Supabase pogovarja neposredno s Postgresom, deli, ki potrebujejo privilegije, pa živijo v bazi kot SECURITY DEFINER funkcije — šest jih je in pokrivajo sinhronizacijo oddaj in filmov, podatke za domači zaslon, statistiko profila, shranjevanje odziva ob ogledu in preračun agregatov ocen.
Ta odločitev oblikuje vse ostalo. sync_show sprejme vnaprej pridobljene podatke TMDB kot JSON in v eni transakciji zapiše oddajo z vsemi epizodami, zato sinhronizacija bodisi uspe v celoti bodisi sploh ne. Tabeli media in episodes lahko bere vsak prijavljen uporabnik, neposredno pa vanju ne piše nihče, zato je ta funkcija edina vrata v skupni predpomnilnik. Ker je predpomnilnik skupen in ne vezan na račun, en sam uporabnik z odprtjem oddaje osveži podatke za vse, intervali ponovne sinhronizacije pa so uglašeni po stanju: dva dneva za serijo, ki še teče, in štirinajst za tisto, ki se je končala.
Dve Deno edge funkciji opravita tisto, kar ne sme teči na odjemalcu — izvoz podatkov po GDPR in trajen izbris računa. Obe klicatelja prepoznata iz njegovega žetona in vse poizvedbe izvedeta prek njega, zato rezultat omeji row-level security, identiteta, ki bi jo podtaknil odjemalec, pa ni nikoli sprejeta. Gradnje gredo prek EAS kot podpisani APK-ji na javni GitHub repozitorij, ki ga aplikacija sama preverja za nove izdaje, s čimer se povsem izogne pregledu v trgovini.
Zgrajeno na odprti kodi
Baza je navaden Postgres, dosegljiv prek običajnega SQL-a, brez lastniške poizvedbene plasti vmes. Supabase okoli njega prispeva avtentikacijo, shrambo in gostovanje, a shema je osemnajst oštevilčenih migracijskih datotek, ki bi se uveljavile na katerikoli instanci Postgresa, lokalni razvoj pa teče na istem pogonu kot produkcija — nič v podatkovnem modelu ni ujetnik izbire gostovanja. Aplikacija uslugo vrača s pregledovalnikom licenc v nastavitvah, ki našteje vseh 675 odprtokodnih paketov iz produkcijske gradnje; ustvari ga skripta, ki prehodi drevo odvisnosti, zato ne more zastarati.
Implementacijske opombe
Obseg sem zaklenil na šest funkcij, še preden sem napisal prvo vrstico kode, najtežje pa ga je bilo pustiti zaklenjenega — ideje za družbeni feed, komentarje in priporočila so se pojavile in bile zavrnjene, ker rok ni bil moj. Teste sem pisal le tam, kjer je logika čista in je napaka draga: bralnik izvoza, pravila o datumih predvajanja, ujemanje, razvrščanje knjižnice. Vse to teče kot navadne funkcije nad testnimi podatki, brez naprave in brez omrežja. Uporabniški vmesnik namenoma nima testov.
Problem & rešitev
Problem
TV Time se je 15. julija 2026 zaprl in s seboj odnesel leta zgodovine ogledov. Druge aplikacije so znale slediti serijam, nobena pa ni znala prebrati izvoza, ki so ga uporabniki dobili ob odhodu — menjava je zato pomenila, da desetletje gledanja pustiš za sabo in začneš s praznim seznamom.
Rešitev
Android-first aplikacija, zgrajena na Postgresu in Supabase, kjer je uvoz osrednja funkcija. Arhiv iz TV Time prebere na napravi, vsak naslov poišče v TMDB prek ohlapnega ujemanja, vse dvoumno pa pošlje na zaslon za potrditev, namesto da bi ugibal.
Poudarki
Označitev epizode z enim dotikom, naslednja neogledana se pokaže sama
Domači zaslon, ki se sam razvrsti v Naslednje, Gledam, Že dolgo nisem gledal, Ujet in Seznam želja
Koledar prihajajočih epizod in filmskih premier, z obvestili po izbranih kategorijah
Seznami z oznakami in vidnostjo, priljubljene ter knjižnica z iskanjem in razvrščanjem
Ocene, odzivi in zasebne beležke, poleg tega povprečja skupnosti ob ocenah TMDB
Uvoz iz TV Time: arhiv se prebere na napravi, ohlapno poveže s TMDB in ročno potrdi
Moja vloga
Full-stack mobile
Izvedel sam — React Native aplikacijo, Postgres shemo in vse RLS politike, strežniške funkcije za sinhronizacijo, uvozni motor za TV Time in postopek objave različic.
Ključne odločitve
Postgres funkcije namesto lastnega API-ja
Namesto posebnega strežnika pisalne poti živijo v Postgresu kot SECURITY DEFINER funkcije. Sinhronizacija oddaje v eni sami plpgsql transakciji zapiše metapodatke in vse epizode, zato na pol sinhronizirana oddaja sploh ni mogoča, ponovni zagon pa je idempotenten.
En skupen predpomnilnik metapodatkov za vse uporabnike
Metapodatki TMDB se ne podvajajo po računih. Tabeli media in episodes lahko bere vsak prijavljen uporabnik, piše pa se vanju le prek sinhronizacijskih funkcij — kdor prvi odpre oddajo, jo ogreje za vse.
Supabase namesto lastnoročno spisanega zaledja
Postgres, avtentikacija, shramba in edge funkcije v eni upravljani storitvi. Spodaj je navaden odprtokodni Postgres, dosegljiv prek standardnega SQL-a, zato shema ostaja prenosljiva, sklad pa lahko teče lokalno ali na lastnem strežniku, brez vezanosti na ponudnika.
Uvoz raje vpraša, kot ugiba
Napačno samodejno ujemanje tiho pokvari leta zgodovine. Vse, kar ni dovolj zanesljivo, gre na zaslon za pregled — uvoz je zato počasnejši, a uporabnik ostane gospodar svojih podatkov.
Zagate & rešitve
Izvoz iz TV Time ni čist podatek
Arhiv sestavljajo CSV datoteke z ubežnimi narekovaji, prelomi vrstic znotraj polj in zapisi o ogledih, raztresenimi po več datotekah. Poleg tega se identifikatorji TV Time ne preslikajo na TMDB, sami naslovi pa so dvoumni — predelave in ponovni zagoni trčijo med sabo, eno napačno ujemanje pa onesnaži zgodovino cele oddaje.
Bralnik in združevanje zgodovine sta čisti funkciji brez I/O, zato so grdi primeri prikovani z Jest testi nad resničnimi izvozi. Ujemanje ocenjuje kandidate po naslovu, letu in številu epizod, samodejno sprejme le zelo zanesljive zadetke, ostalo pa pošlje v pregled. Arhiv se prebere v celoti na napravi — nič se ne naloži, dokler uporabnik ne potrdi.
TMDB ima luknje v datumih predvajanja
Epizode sredi sezone včasih sploh nimajo datuma predvajanja, kar je pokvarilo preverjanje, ali je bilo nekaj že predvajano — na tem pa slonita tako koledar kot usklajevanje ob uvozu.
Epizoda brez datuma šteje za predvajano, če je bila predvajana katera koli poznejša epizoda iste oddaje. Gre za pregled naprej namesto poizvedbe za vsako epizodo posebej in zdrži tudi tam, kjer so podatki TMDB pomanjkljivi.
Domači zaslon je za izris potreboval verigo poizvedb
Za prikaz domačega zaslona je bilo treba pridobiti knjižnico, nato zgodovino ogledov in nato še epizode za izračun naslednje — veriga medsebojno odvisnih obhodov, preden se je pokazalo karkoli, in to ob vsakem zagonu.
Ena sama Postgres funkcija vrne knjižnico, omejeno zgodovino in vitek nabor epizod kot en JSON, rezultat pa se shrani na disk, zato se hladen zagon takoj izriše iz zadnjega posnetka in se uskladi v ozadju.
Ocene skupnosti, ne da bi kogarkoli razkrili
Prikaz povprečja skupnosti ob oceni TMDB je pomenil, da vsak uporabnik bere ocene, ki pripadajo drugim ljudem — točno takšna funkcija, ki razkrije več, kot je bilo mišljeno.
Ločena agregatna tabela hrani samo vsote in števce brez identitete, preračunane na strežniku, osebne ocene za njimi pa ostanejo zaklenjene pod row-level security. Šteje le zadnji ocenjeni ogled posameznega uporabnika, zato s ponovnimi ogledi povprečja ni mogoče napihniti.
Rezultati & vpliv
7 tednov
od prvega commita do javnega zgodnjega dostopa
18
SQL migracij — edina pot za spremembo sheme
675
odprtokodnih paketov, navedenih v aplikaciji
Galerija projekta









