-
Näillä rakennan
Saatavilla nyt, ja avoin kunnianhimoisille full-stack-rooleille, joissa sekä laatu että vauhti ratkaisevat.
Kielet
-
TypeScript / JavaScript työ
- Zod
-
Python
- PyTorch
- Demucs
- librosa
- WORLD
- PyMuPDF
- ebooklib
- Tesseract
- ffmpeg
- CustomTkinter
-
C#
- .NET 8
- ASP.NET Core
- Razor Pages
- ASP.NET Identity
- EF Core
-
PHP
- Laravel
- Blade
- Eloquent
- Pest
-
Rust
- Tokio
- axum
- Dioxus
- zbus
- WebAssembly
- Argon2id
- XChaCha20-Poly1305
- zeroize
-
SQL
-
GLSL
-
Bash
-
PowerShell
-
AppleScript
- iTerm2 automation
Frontend
-
Next.js työ
- NextAuth
- next-intl
-
React työ
- MUI työ
- Recharts työ
- ReactFlow
- framer-motion
-
Astro
-
Three.js
- GSAP
- postprocessing
-
Phaser 4
-
Web Audio API
- Strudel
-
Tailwind CSS
-
Chrome Extension (MV3)
Backend ja data
-
PostgreSQL työ
- Prisma
- PgTyped työ
- Kysely
- pgvector
- pg-boss
-
Node.js työ
- Pino
-
MongoDB
-
SQLite
-
FastAPI
- asyncpg
AI ja kielimallit
-
Claude Code
- Subagents
- Skills
- Hooks
- MCP
- Plugins
- Permission allowlists
- Skill calibration
-
Anthropic API
-
Ollama
-
RAG
- pgvector
- fastembed
- BM25
- lingua
- FastAPI
- Ollama
- Tailscale Funnel
- Microsoft.Extensions.AI
-
Text-to-speech
- Edge-TTS
- Piper
- Chatterbox
- VoxCPM2
- Qwen VoiceDesign
-
Microsoft.Extensions.AI
Alusta
-
Docker
- Docker Compose
-
Kubernetes työ
- Helm
-
Azure työ
- App Service
- Static Web Apps
- Functions
-
Vercel
-
GitHub Actions
- CodeQL
-
Testing työ
- Jest
- Vitest
- Playwright
- pytest
- xUnit
- Stryker
- jest-axe
-
Observability
- OpenTelemetry
- Sentry
-
Packaging
- PyInstaller
- macOS .app bundle
- launchd
- Inno Setup
- Task Scheduler
-
Turborepo
-
Tailscale Funnel
HRM 28
- TypeScript / JavaScript
- Zod
- SQL
- Next.js
- NextAuth
- next-intl
- React
- MUI
- ReactFlow
- PostgreSQL
- Prisma
- pg-boss
- Pino
- MongoDB
- Anthropic API
- Docker
- Docker Compose
- Helm
- Vercel
- GitHub Actions
- Testing
- Jest
- Playwright
- Stryker
- jest-axe
- Observability
- OpenTelemetry
- Sentry
Platform 17
- TypeScript / JavaScript
- Zod
- SQL
- Next.js
- NextAuth
- next-intl
- React
- MUI
- framer-motion
- PostgreSQL
- Prisma
- Vercel
- Testing
- Jest
- Playwright
- jest-axe
- Turborepo
Portfolio 28
- TypeScript / JavaScript
- SQL
- GLSL
- Astro
- Three.js
- GSAP
- postprocessing
- Tailwind CSS
- asyncpg
- Permission allowlists
- RAG
- pgvector
- fastembed
- BM25
- lingua
- FastAPI
- Docker
- Docker Compose
- Vercel
- GitHub Actions
- CodeQL
- Testing
- Vitest
- Playwright
- pytest
- Observability
- Sentry
- Tailscale Funnel
ReadLog 10
- TypeScript / JavaScript
- Next.js
- NextAuth
- React
- MUI
- PostgreSQL
- Prisma
- Vercel
- Testing
- Jest
ReadLog .NET 12
- .NET 8
- ASP.NET Core
- Razor Pages
- ASP.NET Identity
- EF Core
- SQLite
- Docker
- Azure
- App Service
- GitHub Actions
- Testing
- xUnit
ReadLog Laravel 10
- PHP
- Laravel
- Blade
- Eloquent
- Pest
- PostgreSQL
- SQLite
- Docker
- Docker Compose
- GitHub Actions
AudiobookMaker 19
- Python
- PyTorch
- PyMuPDF
- ebooklib
- Tesseract
- ffmpeg
- CustomTkinter
- PowerShell
- Text-to-speech
- Edge-TTS
- Piper
- Chatterbox
- VoxCPM2
- Qwen VoiceDesign
- GitHub Actions
- pytest
- Packaging
- PyInstaller
- Inno Setup
Spacepotatis 15
- TypeScript / JavaScript
- Zod
- SQL
- Next.js
- NextAuth
- React
- Three.js
- GSAP
- Phaser 4
- Tailwind CSS
- PostgreSQL
- Kysely
- Vercel
- Testing
- Vitest
Strudel Patterns 4
- TypeScript / JavaScript
- Web Audio API
- Strudel
- Claude Code
claude-continue 10
- Python
- PowerShell
- AppleScript
- iTerm2 automation
- GitHub Actions
- Packaging
- PyInstaller
- macOS .app bundle
- launchd
- Task Scheduler
PasswordManager 12
- TypeScript / JavaScript
- Rust
- Tokio
- axum
- WebAssembly
- Argon2id
- XChaCha20-Poly1305
- zeroize
- PowerShell
- Chrome Extension (MV3)
- SQLite
- GitHub Actions
claude-agents 9
- Bash
- Claude Code
- Subagents
- Skills
- Hooks
- MCP
- Plugins
- Permission allowlists
- Skill calibration
SongGenerator 5
- Python
- PyTorch
- Demucs
- librosa
- WORLD
Feedback Intelligence 16
- C#
- .NET 8
- PowerShell
- Node.js
- SQLite
- RAG
- Ollama
- Microsoft.Extensions.AI
- Docker
- Azure
- Static Web Apps
- Functions
- GitHub Actions
- CodeQL
- Testing
- xUnit
kielet projekteissa projekteja per kieli, ei osuutta koodista - TypeScript 5
- Python 3
- C# 2
- JavaScript 2
- Bash 1
- GLSL 1
- PHP 1
- Rust 1
työ = käytetty asiakastyössä. Muut ovat omista tuotantoprojekteistani. Avaa rivi nähdäksesi mitä sen alla on.
-
-
Rust, ja oman työn tarkistaminen
Uusi kieli ja tiukempi näytön vaatimus tulivat yhtä aikaa. Kieli on Rust, jonka otin käyttöön salasanahallintaan, jossa koko kryptografinen pinta asuu yhdessä cratessa, joka kääntyy sekä natiivisti että WebAssemblyksi. Komentorivikassa, synkronointipalvelin, selaimessa toimiva client ja Chrome-laajennus ajavat kaikki samaa koodia, neljän toisistaan hiljalleen loittonevan kopion sijaan.
Tapa oli kieltäytyä uskomasta omaa sanaani mistään. Avaimenjohtamisen parametrit, nonce-strategia, se mihin autentikoitu salateksti on sidottu: jokainen niistä on kirjattu päätös, johon liittyy uhkamalli, mukaan lukien selkeä lista siitä mitä suunnittelu ei suojaa. Repossa on tätä viimeistä kohtaa varten omat auditoijansa: yksi käy päätöskirjaukset läpi koodia vasten, toinen vertaa esitettyjä turvallisuusväitteitä siihen, mitä kryptografia todella tekee. Väite jota kukaan ei tarkista uudelleen on vain kommentti.
-
Yksi crate, neljä clientia
Argon2id 256 MiB:llä ja kolmella kierroksella, XChaCha20-Poly1305 tuorein nonce jokaista tietuetta kohden, ja jokainen tietue on sidottu omaan id:hensä ja aikaleimaansa niin ettei kahta tietuetta voi vaihtaa keskenään huomaamatta. Pääsalasana ei koskaan poistu clientilta, ja synkronointipalvelin pitää hallussaan vain salatekstiä. Lukituksen avaaminen maksaa noin 430 ms, mikä on ominaisuus, ei regressio.
-
Kolmekymmentä kierrosta, sokkona
Suomenkielisen kielimallin valinta paikalliseen pinoon ratkaistiin järjestämällä kolmekymmentä suomenkielistä vastausta sokkona, arvioijana äidinkielinen puhuja joka ei nähnyt kumpi malli kirjoitti minkäkin vastauksen. Poro-2-8B sijoittui ensimmäiseksi 26 kertaa 30:stä ja päätyi tuotantoon tällä tuloksella. Toinen projekti ajoi samat luvut ja jätti sen väliin, koska oikea valinta riippuu siitä miten tuotosta käytetään. Kumman tahansa valitseminen fiiliksen perusteella olisi ollut nopeampaa eikä olisi todistanut mitään.
Lue tutkimus -
Yleensä bugi on minun
Kun vastaukset alkoivat liittää vääriä päivämääriä omaan tutkimukseeni, mukava selitys olisi ollut että pieni malli sekoili. Ei sekoillut. Päivämäärä putosi pois prompt-rajalla ennen kuin malli näki sitä koskaan. Kolme aiempaa yritystä korjata asia mallin puolella on kirjattu umpikujiksi, jotta seuraava katsoja ei käytä siihen viikkoa niin kuin minä käytin.
-
Mittaus joka ei muuttanut mitään
Monikielinen embedder näytti ilmeiseltä päivitykseltä suomenkieliseen hakuun. Suoraan vertailtuna jo tuotannossa oleva ratkaisu sai 0,810 pistettä ehdokkaan 0,762 pistettä vastaan, joten mikään ei mennyt tuotantoon. Kokeilu joka puhuu suunnitelmaa vastaan on yhtä arvokas kuin se joka vahvistaa sen, kunhan kummankin kirjaa ylös.
-
-
Mittasin AI-työnkulun
Vuoden ajan väitin että työnkulku kannattaa, joten ajoin A/B:n. Jokainen mukautettu Claude Code -skilli mitattuna itseään vastaan kylmänä (sama tehtävä, subagent päällä ja pois) Sonnetilla, Opuksella ja Haikulla. 34 skilliä, 33 kalibroitua. Yhteissäästö: +17 %, noin 327K tokenia portfoliossa.
Julkaistuun rekisteriin kuuluvat ne skillit jotka maksoivat ENEMMÄN kuin kylmänä meneminen. Ne eivät ole epäonnistumisia. Niissä on tarkkuutta jonka kylmä haara ohitti (auditin perusteellisuus, protokollakuri, spec-syvyys). Arvo on täydellisyys, ei pakkaaminen. PDF on ladattavissa contact-terminaalista; jokainen luku on jäljitettävissä oikeaan transkriptiin.
-
Rakennusvuosi 2026
Elokuussa 2026: neljätoista projektia tuotantoon yksin. Full-stack-verkkosovelluksia, työpöytätyökalu, selainpeli, Rust-salasanahallinta ja Azureen julkaistu ReadLog-käännös. Oikeita käyttäjiä, oikeaa ops-puolta, täysi omistajuus skeemasta deployhin.
-
Triage ennen uudelleensuunnittelua
Kun tallennuksen korruptio iski Spacepotatikseen toukokuussa 2026: palvelinpuolen vahti samana päivänä, audit-taulu seuraavana, arkkitehtoninen korjaus vasta viikon datan jälkeen. Lievennä → observoi → arkkitehtuuri.
-
AI-työnkulku osana koodia
Spacepotatis toimittaa kokoelman Claude Code -skillejä repon sisällä, koodikatselmoidut ja auditoidut. ~3,13M tokenia säästöä ensimmäisenä vuotenaan.
Menetelmä -
Ei työkalulukitusta
AudiobookMaker pyörittää kolmea TTS-moottoria yhden putken alla: Edge-TTS, Piper, Chatterbox. Käyttäjä valitsee per kirja.
-
Mutaatiotestaus > kattavuus
HRM ajaa Strykerin jokaisessa PR:ssä. 92,2 % rivikattavuus tarkoittaa että rivit ajettiin; mutaatiopistemäärä tarkoittaa että assertiot oikeasti löytävät bugit.
-
Korjaa upstreamissa, ei paikallisesti
Diagnosoin muistivuodon syvällä Chatterboxin päättelypolussa; lähetin kaksi PR:ää upstreamiin resemble-ai/chatterboxiin (#505, #510), molemmat avoinna ja muiden kontribuuttoreiden bumppaamia.
-
Yksin full-stack, ei jonoja
SQL, sovelluskoodi, CI, Vercel- ja Azure-deployt, allekirjoitetut Windows-asentajat GitHub Releasesin kautta, OpenTelemetry. Omistettuna päästä päähän kaikissa neljässätoista projektissa.
-
-
AI-natiivit työnkulut
Agenttilähtöistä, AI-avusteista kehitystä versioituna kurinalaisuutena. Mukautetut Claude Code -skillit menevät repoon tuotantoartefakteina. Jokainen opettaa agentille projektikohtaisen reseptin (lisää vihollinen, vie tietokantamigraatio, auditoi tallennusputki) niin että se menee suoraan asiaan eikä grepaa ympäriinsä hinnalla $X/token. Parikoodausta rinnakkaisilla subagenteilla itsenäisten siivujen yli, sen jälkeen tulosten synteesi.
Skillit ovat versionhallinnassa, auditoituja (skillin ja sen viittaaman koodin välinen drift on aito bugiluokka, ja drift napataan ja korjataan), ja niitä käsitellään tuotantoartefakteina. Arvioitu säästö pelkästään Spacepotatiksella: ~3,13M tokenia vuodessa. Nopeammin tuotantoon ilman että rima laskee.
Työnkululla on omat työkalunsa: claude-continue pitää Claude Coden 5-tuntiset käyttöikkunat peräkkäin lukemalla aktiivisen ikkunan nollautumisajan ja jatkamalla keskeytettyjä istuntoja heti kun seuraava ikkuna avautuu, niin ettei pitkä autonominen ajo pysähdy ikkunoiden väliseen kuoppaan.
-
Isäksi tuleminen
Jäin pois kokopäivätyöstä perhesyistä. Omat projektit etenivät taustalla.
-
Kasvu Labs Oy
Kaksi vuotta full-stack-työtä, kolmessa vaiheessa.
Ensin avoin data. Rakensin TypeScript-työkalun, joka hakee julkiset tilastot ja muokkaa ne uuteen muotoon, ja se jäi yrityksessä käyttöön lähtöni jälkeenkin. Se syötti kioskiverkoston sovellusta: myynti kioskeittain ja tuotteittain, kuka vastasi mistäkin, ja Suomen kartta, jolla jokainen kioski näkyy kuntien ikä-, tulo- ja työllisyysdatan päällä. Sovellus vastasi kysymykseen, missä kioskeja pitäisi olla enemmän ja missä vähemmän.
Sitten asiakasprojekti, jossa vedin full-stack-tikettejä kanban-taululta. Enimmäkseen frontendia: React-komponentteja, MUI:ta räätälöitynä reilusti oletuksia pidemmälle, ja mittatilausratkaisuja sinne, mihin mikään valmis ei sopinut. Usein koko polku samalla: PgTyped-kysely, sille REST-päätepiste, kytkennät ja näkymä päälle, testeineen.
Kuukausittaiset datapäivitykset olivat myös minun vastuullani. Suoraa tietokantayhteyttä ei ollut, joten menin sisään Kubernetes-klusterin kautta ja ajoin psql:ää podissa tuotantoa vasten.
Viimeinen vaihe oli lääketieteellinen tutkimusprojekti. Sama pino, sama työ päästä päähän.
-
Rautakauppa
24 vuotta rautakaupan alalla, pääosin perheyrityksen palveluksessa. Sisustus, remontointi, työkalut, rakentaminen: joka osasto, kaikenlaiset asiakkaat. Se työ joka opettaa mitä käyttäjä oikeasti tarvitsee, ennen kuin laitat ruudun väliin.