diff --git a/content/projects/cs2-arbitrage-monitor.mdx b/content/projects/cs2-arbitrage-monitor.mdx new file mode 100644 index 0000000..365a2a1 --- /dev/null +++ b/content/projects/cs2-arbitrage-monitor.mdx @@ -0,0 +1,44 @@ +--- +title: 'CS2 Arbitrage Monitor' +description: 'A Python data pipeline that tracks completed-sale prices for CS2 skins across marketplaces and alerts on profitable spreads.' +date: '2026-05-20' +tags: ['python', 'data-pipeline', 'scraping', 'automation'] +featured: false +category: Tools +role: 'Solo project' +cover: '/projects/cs2-arbitrage-monitor.svg' +--- + +Skin prices for the same CS2 item can differ noticeably between Steam and other +skin marketplaces, but spotting the gap by hand means watching several tabs at +once. I built a data pipeline that watches for me and pings a Discord channel +when a real arbitrage window opens. + +The system runs in four stages. **Connectors** pull data per marketplace — a mix +of scrapers and official API feeds. A **sales price engine** normalizes item +names, deduplicates records, and stores historical prices. A **matcher** applies +configurable spread rules to find items priced apart across venues. **Alerts** +post an embed card to Discord with the item, per-marketplace sale prices and +timestamps, the absolute and percentage spread, and links to each listing. + +## Stack + +- **Python** — connectors, the price engine, and the matcher +- **Per-marketplace connectors** — scraping for some venues, official APIs for others +- **Storage layer with migrations** — historical completed-sale prices +- **Declarative rule files** in `src/rules/` — minimum spread, item filters, cooldowns +- **Discord webhook** — embed-card alerts to a single channel + +## Interesting decisions + +I track **completed-sale prices** — realized transactions — rather than +listing or asking prices. What a seller hopes to get is not what an item is +worth; only closed sales give an honest arbitrage signal. + +Detection logic lives in **declarative rule files**, not code. Spread +thresholds, item filters, and cooldowns are all config, so I can tune what +counts as an opportunity without editing the pipeline. + +The whole thing is compliance-first: it respects each platform's terms of +service, robots.txt, and rate limits, collects only public completed-sale data, +and performs no automated purchasing or trading. diff --git a/content/projects/esmer-market-accounting.mdx b/content/projects/esmer-market-accounting.mdx new file mode 100644 index 0000000..45d35e6 --- /dev/null +++ b/content/projects/esmer-market-accounting.mdx @@ -0,0 +1,39 @@ +--- +title: 'Esmer Market Accounting' +description: 'A unified inventory, invoicing, and accounting system for a family Turkish grocery, shipped as both a web app and a Windows desktop app.' +date: '2026-05-15' +tags: ['react', 'node', 'electron', 'sql-server'] +featured: false +category: Desktop +role: 'Solo project' +cover: '/projects/esmer-market-accounting.svg' +--- + +Our family grocery kept stock counts, invoices, and the books in separate +places that never reconciled on their own. Esmer Market Accounting folds all of +it into one Turkish-language system a non-technical shop can run at the counter. + +Four modules. Inventory tracks products, SKUs, categories, suppliers, and stock +transactions. Invoicing takes manual entry plus PDF and image uploads, running +OCR extraction into a status-tracked document archive. Accounting +does multi-currency bookkeeping (TRY/USD/EUR with exchange rates), VAT +reporting, P&L, balance sheet, and cash flow. Analytics rolls it up into +dashboard KPIs and revenue and profit trends. Access is split across admin, +accountant, and cashier roles. + +## Stack + +- **React 18 + React Router** — Tailwind, Bootstrap, React Query, i18next (Turkish) +- **Node.js + Express** — JWT auth, Joi validation, Winston logging, Multer uploads +- **Microsoft SQL Server** — raw `mssql` driver over a Turkish schema (STOK, FIS, CARI) +- **Electron + electron-builder** — packaged as an NSIS installer and portable build + +## Interesting decisions + +- I dropped the ORM and wrote raw SQL over the `mssql` driver. The schema is + Turkish-named (STOK for products, FIS/FIS_DETAY for invoices, CARI for + customers), and direct queries kept full control over how SQL Server was hit. +- One React/Express codebase ships two ways: a web app, and a packaged Windows + desktop app so the shop can install and run it locally on the counter machine. +- Multi-currency accounting with exchange rates, plus OCR on uploaded + invoices so paper documents land straight in the archive. diff --git a/content/projects/esmer-market-website.mdx b/content/projects/esmer-market-website.mdx new file mode 100644 index 0000000..61968c8 --- /dev/null +++ b/content/projects/esmer-market-website.mdx @@ -0,0 +1,35 @@ +--- +title: 'Esmer Market' +description: 'The official site for my family grocery store in Northern Cyprus — Turkish-first, statically exported, with client-side Firebase for reviews and campaigns.' +date: '2026-06-10' +tags: ['nextjs', 'react', 'typescript', 'firebase', 'i18n'] +featured: false +category: Web +role: 'Solo project' +cover: '/projects/esmer-market-website.svg' +--- + +Esmer Market is my family's local grocery store in Yeni Boğaziçi, Gazimağusa, +Northern Cyprus. I built the store its own website so regulars can check +campaigns, leave reviews, and find us without going through a social feed. + +The site covers the essentials: home, about, contact, a gallery, a store map +for the location, customer reviews, and the usual privacy and terms pages, plus +an admin login for managing content. It reads Turkish-first, with English as the +secondary language. + +## Stack + +- **Next.js 15 (App Router, `output: 'export'`)** + **React 19** + **TypeScript** +- **Tailwind CSS v4** with **shadcn/ui** (new-york style) +- **Firebase** — Firestore + Auth, client-side only, for reviews and campaigns +- **i18next / react-i18next** — Turkish default, English secondary +- **Framer Motion** for transitions; deployed static on **Netlify** + +## Interesting decisions + +The whole site ships as a static export, yet it's still dynamic where it counts: +Firebase runs entirely client-side, so reviews and campaigns update live without +any server to host. The one non-static piece is the contact form — a Netlify +serverless function using nodemailer and reCAPTCHA v3, which keeps spam out and +email credentials off the client without standing up a backend. diff --git a/content/projects/event-management-system.mdx b/content/projects/event-management-system.mdx new file mode 100644 index 0000000..f6ff2b5 --- /dev/null +++ b/content/projects/event-management-system.mdx @@ -0,0 +1,38 @@ +--- +title: 'Event Management System' +description: 'A multi-tenant app for hotel staff to schedule and track events across rooms and venues, backed by one PostgreSQL database.' +date: '2026-06-15' +tags: ['react', 'node', 'postgres', 'prisma', 'auth0'] +featured: false +category: Web +role: 'Solo project' +cover: '/projects/event-management-system.svg' +--- + +Hotel staff were juggling weddings, conferences, and private parties across +rooms and venues, with double-bookings a constant risk. I built a single app +that puts every event on one shared calendar and keeps one hotel's data walled +off from the next. + +The frontend is a React calendar with month, week, and day views, color-coded by +category, plus revenue, occupancy, and peak-time charts. Behind it, an Express +API talks to PostgreSQL through Prisma, with Auth0 handling sign-in and Winston +recording what happened. + +## Stack + +- **React 18 + React Router** — SPA with React Big Calendar and Recharts +- **Node.js / Express + Prisma** — REST API over one PostgreSQL database +- **Auth0** — authentication with JWT validation on every request +- **Helmet, CORS, rate limiting, input sanitization** — baseline hardening +- **Electron + PM2 / Nginx** — desktop wrapper and production process management + +## Interesting decisions + +**Multi-tenant with three-tier RBAC.** Every row is scoped to a hotel, and roles +run Super Admin, Hotel Admin, and User. A hotel admin only ever queries their own +hotel's events — isolation lives in the data layer, not the UI. + +**Soft-delete over hard-delete.** Cancelled events are flagged, never dropped, so +there is always an audit trail. The same booking data feeds automatic conflict +detection, which flags two events fighting over the same room before they save. diff --git a/public/projects/cs2-arbitrage-monitor.svg b/public/projects/cs2-arbitrage-monitor.svg new file mode 100644 index 0000000..7709043 --- /dev/null +++ b/public/projects/cs2-arbitrage-monitor.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + TOOLS · CASE STUDY + + + CS2 Arbitrage + Monitor + + + + + + + python + + + pipeline + + + alerts + + + + + + + + + MARKET A + + + + + $142.00 + sold 12:04 + + + + MARKET B + + + + + $168.50 + sold 12:31 + + + + + + + + + +$26.50 · 18% + + + + + + + A + Arbitrage Monitor + + BOT + Today at 14:32 + + + + + + + + + + + + +18% spread + + + MARKET A + $142.00 + + MARKET B + $168.50 + + SPREAD + +$26.50 + + + View listings → + + + + diff --git a/public/projects/esmer-market-accounting.svg b/public/projects/esmer-market-accounting.svg new file mode 100644 index 0000000..8b0c020 --- /dev/null +++ b/public/projects/esmer-market-accounting.svg @@ -0,0 +1,119 @@ + + + + + + + + + + + + DESKTOP · CASE STUDY + + + Esmer Market + Accounting + + + + + + + + react + + + + electron + + + + sql-server + + + + + + + + + + + + + + + + + + + ESMER MARKET · MUHASEBE + + + + + + + + FATURA · DEFTER + + AÇIKLAMA + TUTAR + + + + STOK · #1024 + ₺ 1.240 + + + STOK · #1025 + ₺ 860 + + + CARİ · Toptan + $ 420 + + + KDV %20 + € 96 + + + + CİRO + + + + + + + + + + + + + + + + + + + ₺ / $ / € + ÇOK DÖVİZLİ + + + + + +18% + KÂR + + + + CARİ · 214 + + STOK · 1.284 + + + + diff --git a/public/projects/esmer-market-website.svg b/public/projects/esmer-market-website.svg new file mode 100644 index 0000000..ad7c9ac --- /dev/null +++ b/public/projects/esmer-market-website.svg @@ -0,0 +1,91 @@ + + + + + + + + + + + + WEB · CASE STUDY + + + Esmer Market + + + + + + + + nextjs + + + + firebase + + + + i18n + + + + + + + + + + + + + + + + + + + + esmermarket.com + + + + + TR + EN + + + + + + + Esmer Market + + + + Kampanya + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/projects/event-management-system.svg b/public/projects/event-management-system.svg new file mode 100644 index 0000000..35df11d --- /dev/null +++ b/public/projects/event-management-system.svg @@ -0,0 +1,116 @@ + + + + + + + + + + + + WEB · CASE STUDY + + + Event Management + System + + + + + + + + react + + + + node + + + + postgres + + + + + + + + + + + + + + + + + + + EVENT CALENDAR + + + + + June 2026 + + + S + M + T + W + T + F + S + + + + + + + + + + + + + + + + + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 11 + + + + + Party + + + Wedding · Grand Hall + + + Conference + + + + Weddings + + Conferences + + Parties + OCCUPANCY 78% + + + + diff --git a/src/app/apple-icon.png b/src/app/apple-icon.png new file mode 100644 index 0000000..a5d42b7 Binary files /dev/null and b/src/app/apple-icon.png differ diff --git a/src/app/icon.svg b/src/app/icon.svg new file mode 100644 index 0000000..db52568 --- /dev/null +++ b/src/app/icon.svg @@ -0,0 +1,8 @@ + + + + + AE + + +