2026 — Present
Konku
Personal spaced-repetition learning system — notes, flashcards, and a scheduler that never lets what you learn disappear silently.

- The problem
- Cross-domain self-directed learning — general knowledge, math, psychology, music, alongside deepening existing coding skills — is easy to start and easy to abandon, and most productivity or habit apps optimize for engagement metrics such as streaks, badges, and notifications rather than for whether anything actually gets retained. I built Konku to solve a specific, real version of that problem for myself: motivation that fades without visible progress, sessions that drift without a hard start and end, and the sharpest one — genuinely forgetting material within weeks without a system that resurfaces it on a schedule I can't forget to check. Rather than adopt an existing habit tracker, I wrote those constraints out as a product brief and built directly against them, with a rule that every feature had to answer at least one of five named failure modes. That constraint-first approach shaped real engineering, not just copy: streaks are weekly rather than daily so one bad day doesn't erase weeks of progress, focus sessions start short (15-20 minutes) and grow over time, and there is no gamification, no losable daily streak, and no guilt-driven notification copy anywhere in the product.
- My role
- Solo developer — Go backend (chi, Postgres via pgx + sqlc), React/TypeScript frontend, the spaced-repetition scheduling engine, and the deployment architecture
- Outcome
- MVP built, full loop working end to end; hardening toward a production-grade, multi-user service is in progress
Key decisions
Kept the spaced-repetition engine pure, and enforced it in CI
`internal/srs` imports nothing else from the codebase, and `make check-pure` fails the build if that ever changes. It carries the product's actual value and is the part most likely to go subtly wrong if it gets entangled with database or HTTP concerns, so isolating it keeps it trivially testable no matter what changes around it.
Weekly streaks, and no gamification anywhere in the product
The failure mode was guilt, not lack of engagement. A weekly streak means one bad day doesn't erase weeks of progress; there are no badges, no losable daily streak, and no guilt-driven notification copy. Focus sessions start at 15–20 minutes and grow from there.
Two independent mechanisms for multi-tenant isolation
Every query carries a `WHERE user_id` clause, and Postgres Row Level Security enforces the same boundary underneath it. "Your data is yours" is a guarantee that shouldn't rest on either one alone.
Wrote the constraints out as a product brief before building
Five named failure modes, with a rule that every feature had to answer at least one of them. Building against written constraints rather than a market gap is what produced the weekly streak and the no-guilt copy as engineering rules instead of leaving them as vibes.
My Role & Impact
This is the project I designed most deliberately around a real personal constraint rather than a market gap, and it's shaped how I think about who a feature is actually for. The spaced-repetition engine (internal/srs) is deliberately isolated — it imports nothing else from the codebase, and a CI check (make check-pure) enforces that — because it carries the product's actual value and is the part most likely to get subtly wrong if it gets entangled with database or HTTP concerns.
What I Learned
- Translating a personal, qualitative constraint ("don't make me feel guilty about a missed day") into a concrete, testable engineering rule — weekly streaks, no punitive copy — instead of leaving it as a vibe.
- Keeping the core logic that matters most, the scheduler, genuinely pure and enforcing that purity in CI, so it stays trivially testable no matter what changes around it.
- Defense in depth for multi-tenancy: treating "your data is yours" as a guarantee that needs two independent mechanisms — a
WHERE user_idclause and Postgres Row Level Security — not either alone.
Showcase



Screenshots
The full product, as it actually runs.






