I build products end to end — backend, web, mobile and desktop — and run them in production. Most of my work is in Kotlin (Spring Boot on the server, Kotlin Multiplatform on mobile) and TypeScript/React on the web, on top of MongoDB and Redis.
I care about systems that stay correct when the network, the data or the users misbehave.
Real-time family location and safety. Android and iOS app with a shared UI, a reactive backend and an admin panel.
Location hot path. One write upserts the last known position, appends to a MongoDB time-series, updates presence in Redis, evaluates geofences scoped to the group, then fans out over WebSocket.
Horizontal fan-out. Every instance publishes to Redis pub/sub and only pushes to its own sockets, so it scales without sticky sessions. Updates are coalesced to one per second per user.
Auth. Short-lived access tokens, rotating refresh tokens with reuse detection, Argon2, rate limiting backed by Redis.
Client. Offline queue of locations in SQLite; WebSocket reconnect with backoff and jitter, polling as fallback.
POS for small businesses that keeps selling when the power or the internet goes down, and syncs when it comes back. Web (PWA), Android, iOS and desktop clients over one backend.
One write path. Every change is an op stored in the local database and the outbox in the same transaction. IDs are generated on the client, so a sale never waits for the server.
Ordering and conflicts. The server assigns a per-tenant sequence for replication order; hybrid logical clocks resolve field-level conflicts. Deletes are tombstones.
Facts are never rejected. Sales, refunds and shifts are accepted even if stock goes negative or a product was deleted. Stock is a ledger of deltas, never an absolute value.
Money is integers. Minor units plus ISO currency; a float in a sync payload is rejected.
One contract, two implementations. Merge rules live in a shared schema with fixtures that both the Kotlin and the TypeScript implementation must pass.
Crowdsourced mobile coverage map. Cell towers, signal quality and speed, built from measurements contributed by users of the mobile app.
Tower positioning. Positions solved by least-squares trilateration from timing-advance readings across every sector of a tower, with covariance-based uncertainty and OpenCellID fused as a prior.
Raster coverage. Street-level coverage is served as pre-rendered z/x/y tiles, so the cost per request is constant no matter how dense the data is. Towers stay as clustered JSON on top.
Concurrency. Found and fixed lost updates on concurrent tower writes by replacing full-document saves with atomic $inc, $max and $addToSet.
Kotlin · Spring Boot · MongoDB (2dsphere) · React · Leaflet · Vite
Crypto trading automation. Strategy automation, copy trading and backtesting across several exchanges, with a web dashboard and a mobile app.
Strategies as data. A strategy is a JSON document, not code, so the same definition runs in backtest, paper and live.
Backtesting for AI agents. An MCP server lets a model sweep parameters, pairs and timeframes in one call, then stress-test the winner out of sample, on other pairs and at double the costs. It deliberately cannot trade real money.
Risk. Per-account limits for copy trading; live order and position updates over WebSocket.