Projects
Selected work
Projects
Things I have built. The desktop view shows them as an interactive solar system — here is the readable list.
-
HRM
liveFull-stack HR management system
Production-ready HR system built to portfolio standards. Two databases (PostgreSQL for structured data, MongoDB for an immutable, hash-chained audit log), 38 granular permissions with per-user overrides, TOTP 2FA, server-side rate limiting, OpenTelemetry tracing, 18 languages, and real-time activity notifications over SSE (with polling fallback).
- 2906+ tests
- 92.2% coverage
- PostgreSQL + MongoDB
Integrations
- Google OAuth
- GitHub OAuth
- Sentry
- OpenTelemetry
- Next.js
- React
- TypeScript
- PostgreSQL
- MongoDB
- Prisma
- MUI
- Jest
- Playwright
- Docker
- GitHub Actions
- Zod
- NextAuth
- next-intl
- ReactFlow
- Pino
- pg-boss
-
Platform
liveCommunity platform built on HRM
Live community platform serving a real WoW guild at vuohiliitto.com. Turborepo monorepo with HRM as a git submodule. Multi-tenant, with WoW-themed gamification (XP, levels, achievements, quests), tabbed chat with whispers and slash commands, a Mythic+ team tracker via the Raider.IO API, and a guided tour for new members.
- Real users
- Multi-tenant
- 1388+ tests
Integrations
- Raider.IO API
- Google OAuth
- GitHub OAuth
- GitHub API
- Turborepo
- Next.js
- React
- TypeScript
- PostgreSQL
- Prisma
- NextAuth
- MUI
- Playwright
- Jest
- next-intl
-
Portfolio
wipThis site
The site you are looking at. Fully static, built with Astro, Three.js and GSAP. A visual showcase of motion craft, intentionally separate from the production stack used in HRM and Platform.
- Astro
- Three.js
- GSAP
- TypeScript
- Tailwind CSS
-
ReadLog
liveTrack every book you've read
Personal reading tracker. Searches Open Library and Google Books in parallel and deduplicates results, then lets you log books with format (paper / e-book / audiobook), a 0–5 star rating, and finish date. Public anonymous feed of recently logged books on the homepage.
- 90 tests
- Multi-source search
Integrations
- Open Library
- Google Books
- Google OAuth
- Next.js
- React
- TypeScript
- Prisma
- PostgreSQL
- NextAuth
- MUI
- Jest
-
ReadLog .NET
liveReadLog, ported to ASP.NET Core
An idiomatic ASP.NET Core port of ReadLog, running live and free on Azure App Service. The same reading-log app — search Open Library and Google Books, log books with format, finish date, and a 0–5 rating, then browse your library and a public "recently read" feed — re-expressed in .NET 8 Razor Pages, EF Core + SQLite, and ASP.NET Core Identity (local and Google sign-in). Containerized and shipped by a reviewer-gated GitHub Actions pipeline to GHCR, then on to Azure over OIDC; EF Core migrations apply on first run.
- ASP.NET Core 8 port
- Live on Azure App Service
- EF Core · SQLite · OIDC deploy
Integrations
- Open Library
- Google Books
- Google OAuth
- .NET 8
- ASP.NET Core
- Razor Pages
- EF Core
- SQLite
- ASP.NET Identity
- Bootstrap 5
- xUnit
- Docker
- GitHub Actions
- Azure App Service
-
AudiobookMaker
wipPDF → audiobook
Desktop app that turns PDF, EPUB, Word/DOCX, or plain text files into audiobooks; scanned PDFs are run through Tesseract OCR first. Four TTS engines: Edge-TTS (cloud, 30+ voices in 6 languages), Piper (offline, no GPU needed), Chatterbox with the "Grandmom" voice for voice cloning from a short reference clip, and VoxCPM2 for zero-shot voice cloning and voice design from text (NVIDIA GPU, developer setup only). The same Chatterbox engine voices the in-game story of Spacepotatis. English output quality is already strong; Finnish is harder to synthesize with available resources, so it gets a dedicated 19-pass text normalization pipeline that handles governor-word number inflection, abbreviation expansion, unit agreement, and loanword respelling — advancing with every release. Ships as a Windows installer with auto-updates and 3000+ tests.
- Chatterbox voice cloning with the Grandmom voice
- 19-pass Finnish text normalization, 3000+ tests
- Voices the in-game story of Spacepotatis
Integrations
- Microsoft Edge-TTS
- Python
- PyMuPDF
- ebooklib
- ocrmypdf
- Tesseract
- num2words
- edge-tts
- Piper
- Chatterbox
- VoxCPM2
- PyTorch
- CustomTkinter
- pydub
- pygame
- ffmpeg
- PyInstaller
- Inno Setup
- GitHub Actions
-
Spacepotatis
liveBrowser shooter — your potato vs the galaxy
Live browser game where a potato in a shield bubble shoots bugs across a procedural galaxy. Boots like a vintage terminal, opens into a 3D solar system you drag and zoom, drops you into top-down vertical combat in the spirit of Tyrian 2000. Next.js 16 + React 19 wraps a Phaser 4 combat scene; Three.js + GSAP power the galaxy view and the camera transition into combat; PostgreSQL on Neon is talked to via Kysely (typed SQL builder, no ORM). All voice generated by AudiobookMaker; all music written in strudel-patterns. Ships a catalog of custom Claude Code skills under .claude/skills/ — version-controlled, audited, treated as production artifacts.
- Next.js 16 + Phaser 4 + Three.js
- ~1300 tests, CI on every push
- Custom Claude Code skills as production artifacts
Integrations
- Google OAuth
- Next.js
- React
- TypeScript
- Phaser 4
- Three.js
- GSAP
- PostgreSQL
- Kysely
- NextAuth
- Tailwind CSS
-
Strudel Patterns
liveAlgorithmic music in Strudel
Live-coded electronic music written in Strudel — a JavaScript pattern engine, port of TidalCycles. Every track is a single composable expression: stacked synths, basslines, drum patterns, and effect chains. Composed through a structured AI workflow — natural-language direction → generation → listen → iterate, with decisions logged alongside the git history. Selected tracks score Spacepotatis (galaxy overworld, mission themes, story narration bed) and the mikkonumminen.dev landing page. Reusable component library, curated synth presets, session notes per iteration.
- Live-coded in Strudel
- AI-directed iteration, logged in git
- Soundtrack to Spacepotatis and mikkonumminen.dev
- Strudel
- JavaScript
- Web Audio API
- Claude Code
-
claude-continue
wipKeep Claude Code windows back-to-back
A cross-platform Python tool — a CLI plus a one-button Tkinter GUI — that keeps Claude Code's 5-hour usage windows running back-to-back. It reads the active window's reset time from ccusage, waits for the rollover, then resumes paused sessions — broadcasting to iTerm2 on macOS, typing into tmux panes on macOS or Linux, or a headless run on Windows/WSL — and re-arms for the next window. Runs unattended via launchd (macOS) or Windows Task Scheduler. Built for long autonomous agent runs, and honest about the review debt that pattern creates.
- Python · Tkinter GUI
- macOS · Windows · WSL · Linux (tmux)
- Unattended via launchd / Task Scheduler
- Python
- Tkinter
- ccusage
- PyInstaller
- launchd
- Task Scheduler
- tmux
- GitHub Actions
-
PasswordManager
wipZero-knowledge password manager in Rust
Local-first password manager where a single Rust crate is the only place crypto exists — Argon2id key derivation and XChaCha20-Poly1305 authenticated encryption, compiled natively and to WebAssembly. Four clients share it: an offline-first CLI vault on SQLite, a sync server that stores ciphertext only, an in-browser WASM client, and a Chrome extension with autofill and save-on-login. Per-entry nonces and AEAD bound to entry id + timestamp block record swapping; keys are zeroized after use; the master password never leaves the client. Every security choice is recorded as an ADR against an explicit threat model, and CI guards secrets out of the repo while running format, clippy, the full workspace tests, and the wasm build.
- One crypto crate, four clients
- Argon2id + XChaCha20-Poly1305
- Server stores ciphertext only
Integrations
- Google OAuth
- Tailscale Funnel
- Cloudflare Tunnel
- Rust
- WebAssembly
- Tokio
- SQLite
- Argon2id
- XChaCha20-Poly1305
- wasm-bindgen
- Chrome Extension (MV3)
- JavaScript
- GitHub Actions
-
claude-agents
liveCost-routing subagents for Claude Code
A small global set of Claude Code subagents that stops paying Opus prices for work a cheaper model does just as well. Twelve agents, each pinning both model tier and reasoning effort in its frontmatter: Haiku for read-only recon (scout, log-miner, scribe, dep-checker, tidy), Sonnet for spec-driven edits (mechanic, test-writer, locale-translator, doc-scribe, migrator, bisect), and an unpinned architect that inherits the session model for design work. Agents auto-detect each repo’s stack — test runner, linter, i18n layout — so one set covers JS, C#, and Python projects. Installs as a Claude Code plugin from a shared marketplace or via script. MIT-licensed.
- 12 model-pinned agents
- Decouples model tier from reasoning effort
- Plugin or script install
- Claude Code
- Claude Haiku
- Claude Sonnet
- Claude Opus
- Bash
- Markdown
-
Feedback Intelligence
liveGrounded feedback analysis with a local LLM
Feedback-intelligence engine that turns messy free-text feedback into situational signal without letting the LLM near the numbers: a deterministic, rule-coded alert layer computes every count and trend, and the LLM only structures input and synthesizes theme narratives — each claim cited back to feedback ids and dropped to a fallback if it fails validation. Domains are pluggable modules (first: Finnish hybrid grocery–hardware retail); a config flag swaps in another domain with zero core edits. .NET 8 over a local Poro 2 8B on Ollama — picked in a 30-round blind test — with a live demo on Azure Static Web Apps reaching the local GPU through a Tailscale Funnel at zero cloud-inference cost. GDPR-clean synthetic corpus, prompt-injection defense in depth, hermetic xUnit suite in CI.
- Deterministic alerts — LLM never computes the numbers
- Pluggable domains, zero core edits
- Live demo on Azure, inference on a local GPU
Integrations
- Tailscale Funnel
- .NET 8
- C#
- SQLite
- Ollama
- Poro 2 8B
- Microsoft.Extensions.AI
- xUnit
- Docker
- Node.js
- Azure Static Web Apps
- Azure Functions
- GitHub Actions
- CodeQL