Fotografie

Petr Žlebek

Softwarový inženýrDotáhnu projekt od nápadu až do produkce.

Projektové portfolio

Team Wallet

Sdílená peněženka pro malý klub, napojená na bankovní účet.

SupabasePostgreSQLReactTypeScriptEdge FunctionsRow Level Security
Zobrazit více
Použité technologie

Backend stojí kompletně na Supabase: Postgres s Row Level Security, PostgREST pro CRUD operace a tři Edge Functions pro zbytek (zvaní členů, synchronizace plateb z banky, e-mailová upozornění). Frontend je React + TypeScript (Vite, Tailwind, TanStack Query), napojený přímo na PostgREST bez vlastního API serveru.

Role a zabezpečení

Dvě role, administrátor a člen. Zůstatky členů jsou i pro administrátora jen ke čtení, vynucené omezením na úrovni sloupců v databázi (RLS samo o sobě sloupce omezit neumí). Bez přihlášeného účtu s odpovídajícím záznamem člena je systém nedosažitelný.

Napojení na bankovní účet

Edge Function pravidelně stahuje výpis z API banky FIO a podle variabilního symbolu platby automaticky páruje s členy, včetně potvrzovacího e-mailu. Stránka Bankovní výpis navíc porovnává skutečný zůstatek na účtu se součtem kreditů všech členů, takže je vidět, kolik peněz klub reálně vlastní nad rámec vkladů.

Hromadné vyúčtování aktivit

Administrátor může průvodcem naúčtovat aktivitu (trénink, turnaj, soustředění) všem zúčastněným najednou. Cena se podle tarifu předvyplní automaticky, ale u každého člena ji lze ručně upravit.

Hra pro dva hráče, která kombinuje piškvorky s hledáním min. Hraje se lokálně i online.

Online gameRealtimeSupabasePostgreSQLReactViteWebSocket
Zobrazit více
Použité technologie

Herní backend a online lobby leží kompletně na Supabase (PostgreSQL, Edge Functions). Frontend je v Reactu a pro realtime hru využívá spojení pomocí WebSocket.

Groše

Rodinná rozpočtová aplikace, která si bankovní platby stahuje a třídí sama, přímo z e-mailu.

SupabasePostgreSQLReactTypeScriptEdge FunctionsRow Level Security
Zobrazit více
Použité technologie

Backend běží kompletně na Supabase: Postgres s Row Level Security, PostgREST pro CRUD operace a jedna Edge Function, která zpracovává příchozí bankovní e-maily. Klíčová logika (třídění transakcí, přepočty zůstatků, rozpočty) žije přímo v databázi jako triggery a funkce, ne v aplikačním kódu. Frontend je React + TypeScript (Vite, TanStack Query), mobile-first.

Moje role

Vlastní nápad i kompletní realizace pro mou rodinu: datový model, bezpečnost, parsování bankovních e-mailů, celé UI i nasazení.

Co aplikace umí

Groše si sama stahuje bankovní e-maily a nově příchozí platby automaticky roztřídí do kategorií podle dřívějších rozhodnutí. Hlídá rozpočty podle kategorií, upozorní na převody mezi vlastními účty a na jednom místě ukáže zůstatky a historii všech účtů.

Kvalita a nasazení

Projekt má přes 90% pokrytí testy (jednotkové, databázové i end-to-end v Playwrightu), včetně testů proti souběžným zápisům do databáze. Nasazení na produkci běží automaticky přes GitHub Actions po každé změně na hlavní větvi, vždy až po úspěšném proběhnutí celé testovací sady.

MidLine

Interní nástroj, který hledá výhodné rozdíly mezi kurzy sázkových kanceláří a predikčních trhů.

.NETC#ReactTypeScriptPostgreSQLDockerAlgorithmic TradingCloudflare Workers
Zobrazit více
Použité technologie

Backend v .NET 10 se skládá z API a knihoven, které zajišťují napojení na externí API, párování událostí, spouštění backtestingových simulací a persistenci dat. Administrační frontend je React + TypeScript aplikace, doplněná o malou Node.js službu, která streamuje průběh běžících background jobů do UI přes WebSocket.

Moje role

Se startupem MidLine v pre-seed fázi spolupracuji jako freelancer. Mám plnou odpovědnost za architekturu, vývoj, nasazení i údržbu nástroje.

Párování událostí

Největší výzvou a zároveň jednou z nejdůležitějších součástí projektu je automatické párování sázkových příležitostí mezi různými zdroji. Využívá se tokenizace názvů a Jaro-Winkler podobnost slov, doplněné o ručně spravované aliasy. Nutná je jen minimální manuální kontrola.

Backtesting nad historickými daty

Simulační engine na základě předem nastavené strategie prochází všechny události z historického datasetu. V každém relevantním okamžiku zkontroluje, zda je dle strategie vhodné uskutečnit nákup dané pozice. Výsledkem simulace jsou jasně definované metriky, které stakeholderům umožní najít ideální strategii. Tyto výsledky také pomohou v rozhodování, zda má smysl do projektu a nástrojů dále investovat.

Nasazení a zabezpečení

Docker Compose spouští backendové služby (API, migrační služba, realtime relay a Postgres). Každá služba má svůj healthcheck a případně závislost na pořadí startu. Backendové služby jsou nasazeny na VPS přes službu Coolify. Frontend admin je nasazen samostatně na Cloudflare Workers. Backend i frontend je nasazen automaticky v reakci na každou změnu v hlavní větvi repozitáře projektu prostřednictvím Github Actions. Frontend je díky Cloudflare Zero Trust přístupný pouze pro whitelistované uživatele. Endpointy backendové API jsou rovněž zabezpečené a dosažitelné pouze z chráněného frontendu.

Quiz Engine

Self-hosted kvízový engine. Hráči se připojí QR kódem a odpovídají přímo z mobilu.

Node.jsExpressSocket.IOJavaScriptState Machinengrok
Zobrazit více
Použité technologie

Jednoduchý backend je napsaný v JavaScriptu a běží na Express frameworku Node.js. Pro real-time komunikaci mezi backendem a frontendovými klienty je použita knihovna Socket.IO. Stav hry je uložen v jednom in-memory objektu na serveru. Hra běží jako stavový automat. Kromě lokální sítě lze server zpřístupnit i mimo ni přes tunel ngrok.

Motivace

Očekával jsem u sebe doma partu kamarádů. Zrovna probíhalo Mistrovství světa ve fotbale a my jsme měli společně sledovat zápas. Napadlo mě, že připravím krátký tématický kvíz. Udělal jsem si rešerši dostupných kvízových webových aplikací. Moje požadavky byly:

  • hráči se připojí naskenováním QR kódu, bez instalace čehokoliv
  • kvíz se hraje přímo v mobilním prohlížeči
  • možnost vlastní stylizace (název, barvy, vzhled)

Z cenově dostupných aplikací jsem žádnou nevybral, a tak jsem se rozhodl, že si zkusím rychle naprogramovat vlastní řešení.

Spolehlivost

Největší výzvou bylo udržet hru konzistentní i při výpadcích. Mobilní připojení nemusí být vždy ideální, telefony se uzamykají, lidé přepínají aplikace. Díky session ID v localStorage se hráč do hry může kdykoli vrátit a klidně i v novém tabu.

Modularita

Otázky a odpovědi se definují v jednoduchém Markdown souboru, který server při spuštění parsuje a rozdělí do sekcí. Odpovědi se vyhodnocují automaticky (normalizace textu, tolerance na shodu klíčového slova), moderátor ale může výsledek kdykoliv v review obrazovce manuálně přepsat.

Vizuální styl (název, podtitulek, barvy) je oddělený do konfiguračního JSON souboru, takže kvíz lze pro různé příležitosti rychle upravit bez zásahu do kódu. Pokročilý uživatel si může definovat CSS soubor s vlastním stylem.

Solver Benchmark

Obecný dashboard pro spouštění, ukládání a porovnávání různých optimalizačních solverů.

.NETC#PostgreSQLDockerReactViteTailwind CSSWebSocket
Zobrazit více
Použité technologie

Backend je kompletně v .NET 10. Jako databázový systém se používají relační tabulky v PostgreSQL. Frontend je v Reactu. Fronta jobů využívá notifikační systém v PostgreSQL na backendu a WebSocket protokol na straně frontendu.

Obecnost

Všechny optimalizační problémy a velké kombinatorické úlohy mají jedno společné. Mají jasně definované datové typy pro vstup a výstup. Přesně s tímto počítá tato webová aplikace, takže ji lze snadno přepoužít pro libovolný problém. Umožňuje spouštět různé solvery na různé instance a ukládat a porovnávat vypočtená řešení. Veřejně dostupné demo obsahuje ukázky Vehicle Routing Problem a jejich řešení.

Aplikace alespoň částečně podporuje všechny optimalizační úlohy. Všechny jsou ve výchozím stavu podporovány k prohlížení a editaci v raw json formátu. I to může mít svou přidanou hodnotu. K tomu, aby byla zajištěna plná podpora, je potřeba naimplementovat jednotlivé views pro datový typ instance problému, řešení problému a možnosti řešitele. Pokud tyto views implementují obecný interface a splňují naming konvence, zobrazí se místo raw jsonu právě implementovaná editovací okna.

Napojení na solvery

Každá úloha má svůj specifický solver, který musí být zabalený v API. Ta musí implementovat specifikované API endpointy a běžet na předdomluveném portu tak, aby se na ni GUI mohlo napojit.