andrewlb notes

Etyde

Etyde

Tools

Claude CodeNext.jsReactTypeScriptFastifyPostgreSQLSupabaseDrizzle ORMBullMQRedisOllamaalphaTabPlaywrightVitestTurborepoAnsible

What worked

Row-level security from day one turned out to be the right call — multi-tenant isolation at the DB layer meant we never had to retrofit access control. The generate-on-read pattern (recurring lesson slots and practice set sessions computed on query, never materialized) kept the data model clean. AI notation generation via AlphaTex hit 89-94% success, and the graceful fallback chain (retry 3x, strip notation, deliver text-only session) meant students always got something useful even when generation failed.

What broke

The VPN tunnel to the Mac Mini is the weakest link — host sleep drops the connection and AI features silently degrade until reconnect. Redis has no replication, so jobs vanish on restart. Qwen inference takes 30-90 seconds per generation, which is too slow for anything interactive. alphaTab requires a webpack plugin that blocks Turbopack adoption. PWA and offline practice slipped scope entirely.

Roles

I defined the domain model — the separation of lessons, practice sessions, repertoire, goals, and the parent portal as read-only. I chose Supabase + RLS over rolling auth. Claude Code built the API routes, frontend, AI worker, and deployment playbooks. The three-step S3 upload (presign, upload, confirm) was Claude's proposal; the generate-on-read pattern was a shared decision.

Etyde (Music Learning Platform)

Overview

Etyde is a music learning platform connecting private music teachers with students through practice-centric workflows. It replaces the 3-4 separate tools teachers currently juggle (scheduling, lesson notes, practice tracking, sheet music) with a single integrated platform.

Target users: Private music teachers (guitar, piano) with 2-10 students, their students, and parents.

What It Does

  • Lesson management with plans, outcomes, notes, and RRULE-based scheduling with timezone handling and iCal export
  • Practice sessions with a live timer, auto-complete after inactivity, and integrated metronome and tuner
  • Sheet music rendering for PDF, Guitar Pro, and MIDI files via alphaTab, with notation/tablature toggle and track controls
  • AI-generated practice sessions that combine a student's goals and repertoire into tailored exercises with progressive difficulty (Practice Sets)
  • AI notation generation producing AlphaTex rendered as interactive sheet music, with quality gates and graceful fallback
  • Student goals and repertoire tracking with growth dashboards
  • Parent portal providing read-only visibility into practice activity, lessons, and goals
  • Real-time messaging between teacher and student via Supabase Realtime

How It Fits Together

A Next.js frontend talks to a Fastify API backed by PostgreSQL (via Supabase with row-level security) and Drizzle ORM across 34 schema files. BullMQ + Redis handle async work, with an AI worker running Ollama (Qwen 32B) on an M4 Mac Mini connected over WireGuard. File uploads go through a three-step S3 flow (presign, upload, confirm) to bypass the API for large files. The whole stack deploys via Docker Compose + Ansible + Traefik on a Hetzner VPS, with Watchtower for auto-updates.

Architecture Decisions

  • RLS from day one — Multi-tenant isolation lives at the database layer, not in application code. Claude Code managed this across 34 schema files without leakage.
  • Generate-on-read for recurring entities — Lesson slots and practice set sessions are computed on query, never materialized. Keeps the data model honest and avoids stale-data bugs.
  • Three-step S3 upload — Presign on server, upload direct to storage, confirm back to API. Large files never touch the application server.
  • Graceful AI degradation — Notation generation fails 3x? Strip notation. Still fails? Deliver text-only session. The student always gets something.
  • Live auto-save everywhere — No "Save" button. Debounced mutations reduce cognitive load for teachers writing lesson plans.

Iteration Story

The project shipped across three milestones. The v1.0 MVP proved the core teaching/learning loop worked. v1.1 added the operational features teachers actually need daily — scheduling, calendar views, the parent portal. The interesting shift came in v1.2 (AI Studio): rather than bolting AI onto existing features, we built a separate practice generation pipeline where AI composes multi-session sequences with progressive difficulty. The key learning was that AI notation generation needed aggressive quality gates — the 89-94% success rate sounds high, but a 10% failure rate in a music lesson is unacceptable, so the fallback chain became the real product design work.

Weaknesses & Open Questions

  • VPN brittleness — The WireGuard tunnel to the Mac Mini is a single point of failure for AI features. Graceful degradation is in place, but the failure mode still surprises users (features just quietly disappear).
  • Inference latency — 30-90 seconds per AI generation is fine for batch/async but rules out any interactive AI features.
  • Redis SPOF — No replication means jobs are lost on restart. This needs proper persistence tuning or a managed alternative.
  • alphaTab vendor lock — Requires a webpack plugin, blocking Turbopack. No ESM support on their roadmap.
  • PWA deferred — Offline practice tools never shipped. This matters most for students practicing without reliable internet.
  • No real user validation yet — The platform is architecturally solid but hasn't been tested with actual teachers and students beyond the developer.

Ecosystem Role

Etyde routes AI inference through Roughneck's plugin-based job queue and reports health to CNC for monitoring and error classification. It shares the music domain with AbletonBuddy (learning vs. production) and Evolver (instrument mastery vs. music theory/practice).