Work
Work I'm proud of
There are four things I look at in every project: what the client was struggling with, what we ended up building, what it runs on, and what changed when it went live. Read through one of them, and you’ll soon see whether your situation matches this.
Almost all of this is bespoke software: web applications built at Laravel, along with the associated apps at iOS and Android. I built them all in Groningen and stayed there long after their launch. You take the source code and documentation with you when you leave.
References available on request. I’ll put you in touch with a client who’s been enjoying the results for some time now, and I’m really proud of that.
MyWarranties: scan receipts and submit warranty claims
The problem. Warranties live in a drawer. Thermal receipts fade to a blank strip, so by the time something breaks the proof of purchase has gone or the term has quietly run out. For the supplier the problem inverts: every claim arrives as a fresh email thread, and nothing in it points back to the product.
What I built. A warranty platform with three faces on one Symfony API. The customer photographs a receipt and a vision model reads products, brands, purchase dates, serial numbers and warranty terms straight off it. Nothing gets typed in. (Serial numbers are the field nobody fills in voluntarily.) The app warns before a warranty lapses. When something breaks the customer opens a claim and talks to the supplier in a live thread. Suppliers answer from a staff console, or simply reply to the notification mail, and that reply lands back in the thread.
The result. What shipped:
- 68 REST endpoints spread across 41 controllers with a single action, tested by 126 automated tests
- A single codebase is delivered as a web app, an Android app and a iOS app
- Reading a receipt involves a single AI call with schema constraints, whereby token usage and the cost per call are tracked
- Reminders 30, 7 and 3 days before the expiry date, which cannot be triggered twice
- A supplier can process a claim without having to install anything, simply by replying to the email
- User interface in eight languages
SmartLabel Academy: a learning platform for the music industry
The problem. SmartLabel teaches young creatives the business side of the music industry: rights, royalties, contracts, metadata. The platform grew up on WordPress with LearnDash bolted on top. By then it needed a personal rights dossier, a live community, native apps and four languages, and no stack of plugins stretches that far.
What I built. A standalone React front end on a Laravel API. WordPress gives up one capability at a time. Learners work through video lessons and quizzes, build a CreatorPassport holding their releases, roles and rights, search a knowledge base of contract terms and model contracts, and meet in a live community. A read-only bridge to the old WordPress database lets both systems run side by side. The migration takes as long as it takes, rather than one weekend where everything switches at once.
The result. I wrote the contract first. Static analysis holds the code to it on every push:
- 269 documented API endpoints spread across 95 tables, converted into an OpenAPI specification
- The backend runs on PHPStan, level 10, with strict rules enforced in CI before an image is built
- Runs alongside the WordPress system it replaces, via a read-only connection
- A single cache handles both page requests and live WebSocket updates, and continues to work even when you go offline
- Web, iOS and Android from a single codebase, in four languages
Your project could well be the next one
Do you recognise your own problem in any of these examples? If so, please send me an email. If what you need isn’t listed on this page at all, that’s just as good a reason, and I’ll make a point of reading those emails twice. Just a few sentences about your situation will get you an honest assessment, a cost estimate and details of the first week when I’m available.