Case 01 · 2024 to now
9 languages, 26 paying users, live since 2024
An interactive fiction app where the story branches on the reader's choices, served in nine languages from one Kotlin backend I designed, built and still run.
Screenshots coming once the app store listing is public.
Results
- 9Languages served
- 26Paying users, July 2026
- 61Purchases, July 2026
- 2024Live since
What I did
- Backend architecture on Ktor and JVM 21
- PostgreSQL schema and the JSONB translation layer
- Coins, subscriptions and rewarded ads in one ledger
- Cloudflare R2 media delivery
- Docker Compose deploys and day-to-day operations
Overview
Readers talk to an AI narrator and the plot forks on what they choose. The app has been live on the App Store and Google Play since 2024, in Korean, English, Japanese, Thai, Indonesian, Malay, Turkish, French and German.
I own everything behind the screen: the API, the database, the media pipeline and the release process. New stories ship through a deploy pipeline I run, and by July 2026 the app had 26 paying users across 61 purchases.
Product and client names are withheld under NDA. The stack, the architecture and the figures shown are accurate.
Stack
- Kotlin
- Ktor / JVM 21
- Compose Multiplatform
- PostgreSQL 16
- Cloudflare R2
- Docker Compose
- RevenueCat
- AdMob
Architecture
- Compose Multiplatform · iOS / Android
- Ktor · JVM 21
- PostgreSQL 16
- Cloudflare R2 (media)
- RevenueCat (webhooks)
- AdMob (rewarded)
Decisions that mattered
- 01
Translations live in JSONB
Each piece of content stores its nine translations in one JSONB column, so adding a language is a data change and never a migration.
- 02
One ledger for three revenue streams
Coins, monthly subscriptions and rewarded ads settle into a single per-user balance. Webhook retries and refunds roll back atomically instead of drifting.
- 03
Stories deploy like code
New stories go out as JSON through rsync and a database migration in one step, with a version tag and a rollback path.
- 04
Logs built for a one-person on-call
Request, error and webhook logs live in the database, so a bug report from any of the nine markets can be replayed without SSH.
More work
Have something to build?
Send me two paragraphs about it. I reply within 24 hours, Seoul time, with a price and a date.
Email me