andrewlb notes

Etyde

Etyde

Tools

Claude CodeNext.jsReactTypeScriptFastifyPostgreSQLSupabaseDrizzle ORMBullMQRedisOllamaalphaTabPlaywrightVitestTurborepoAnsible

What worked

Three full milestones in 18 days — v1.0 MVP (3 days), v1.1 Studio Foundations (9 days), v1.2 AI Studio (6 days) — at ~43 commits/day accelerating across milestones. Claude Code handled the RLS-from-day-one pattern across ~34 Drizzle schema files without leakage, built 649 test files + 17 Playwright E2E specs, and produced the three-step S3 upload (presign → upload → confirm) cleanly. AI notation generation via AlphaTex hit 89-94% success with a graceful fallback to text-only sessions. The AI worker split onto a Mac Mini over WireGuard worked.

What broke

The VPN-to-Mac-Mini link is brittle — host sleep can drop the tunnel and the AI features degrade until it reconnects (graceful degradation is in place but the failure mode is still surprising). alphaTab blocks Turbopack (requires a webpack plugin), which means no Turbopack adoption until alphaTab ships ESM properly. Qwen inference latency is 30-90 seconds per generation on the local compute box. Redis has no replication — jobs lost on restart without careful persistence tuning. PWA and offline practice tools slipped out of v1.2.

Roles

I set 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 myself. Claude Code built the Fastify routes, the Next.js frontend, the AI worker, and the Ansible playbooks. The generate-on-read pattern (recurring lesson slots, practice set sessions computed on query) was a shared decision; the three-step S3 upload was Claude's proposal that I accepted.

Etyde (Music Learning Platform)

Overview

Etyde is a production-ready music learning platform connecting private music teachers with students through practice-centric workflows. It's the most substantial project in the portfolio (~77K lines of TypeScript/SQL), professionally architected with three complete milestones shipped across 780 commits over 18 days of development.

Core purpose: Replace 3-4 separate tools teachers currently use with a single platform covering lesson management, practice tracking, sheet music rendering, and growth visualization.

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

Key Features

Teaching & Planning:

  • Lesson management with plans, outcomes, assets, notes
  • Structured practice plans (warmup, drills, repertoire, freeform sections)
  • Teacher reflections on student progress
  • Lesson scheduling with RRULE patterns, timezone handling
  • Calendar views + iCal feed export

Practice & Tracking:

  • Practice sessions with live timer, auto-complete after 3min inactivity
  • Sheet music rendering (PDF, Guitar Pro, MIDI with playback via alphaTab)
  • Integrated metronome (BPM, time signature, visual+audio) and tuner
  • Notation section selection, track controls (mute/solo, notation/tablature toggle)
  • Practice calendar with template scheduling

Growth & Progress:

  • Student goals (1-3 concurrent) with auto-tracking
  • Repertoire tracking (pieces with instrument, 5-stage learning progress)
  • Growth dashboard (multi-dimensional)
  • Teacher reflections

AI Studio (v1.2):

  • AI-powered practice sessions (goal + repertoire -> tailored sessions)
  • Practice Sets (multi-session sequences with progressive difficulty)
  • AI notation generation (AlphaTex rendered as sheet music exercises)
  • Quality gates (89-94% success rate) with graceful fallback

Other:

  • Parent portal (read-only: practice activity, lessons, goals)
  • Real-time messaging via Supabase Realtime
  • Dark mode, responsive design, WCAG compliance

Architecture

Tech Stack

LayerTechnology
FrontendNext.js 15 + React 19 + Tailwind CSS 4 + shadcn/ui
Backend APIFastify 5 + Node.js 22
DatabasePostgreSQL 16 via Supabase (with RLS)
ORMDrizzle ORM (hand-written migrations)
AuthSupabase Auth (magic link + password)
EmailResend + React Email
StorageS3-compatible (MinIO local, AWS/R2 production)
Job QueueBullMQ + Redis
AIOllama (Qwen 32B Q4_K_M) on Mac Mini
Sheet MusicalphaTab (Guitar Pro, MIDI, AlphaTex rendering)
Monorepopnpm workspaces + Turborepo
TestingVitest (649 test files), Playwright (17 E2E specs)
DeploymentDocker Compose + Ansible + Traefik + Watchtower

Monorepo Structure

apps/
  web/           # Next.js frontend
  api/           # Fastify backend (30+ route groups)
  landing/       # Landing page
packages/
  db/            # 34 Drizzle schema files, migrations, RLS
  shared/        # Zod validators (single source of truth)
services/
  ai-worker/     # BullMQ worker (Mac Mini + Ollama)
deploy/
  ansible/       # Idempotent infrastructure playbook
  staging/       # Docker Compose + env template
  production/    # Docker Compose + env template
e2e/
  tests/         # 17 Playwright specs

Deployment Architecture

  • Hetzner VPS: Next.js + Fastify + PostgreSQL + Redis + MinIO + Supabase + Traefik
  • Mac Mini: AI Worker (BullMQ consumer + Ollama) via WireGuard VPN

Key Patterns

  1. Three-step S3 upload (presign -> upload -> confirm) — bypasses API for large files
  2. RLS from day one — Multi-tenant isolation at DB layer, not application layer
  3. Generate-on-read — Recurring entities (lesson slots, practice set sessions) computed on query, not materialized
  4. Graceful degradation — AI notation fails 3x -> strip notation -> text-only session still delivered
  5. Live auto-save — No "Save" button; debounced mutations reduce cognitive load

Development History

780 commits over 18 days:

MilestoneDurationFocus
v1.0 MVP3 daysComplete teaching/learning loop, sheet music, practice tools, 43 plans
v1.1 Studio Foundations9 daysScheduling, calendar, parent portal, catalog, security, E2E tests
v1.2 AI Studio6 daysAI worker, practice generation, notation, Practice Sets

Velocity: 43 commits/day average; accelerating across milestones.

Strengths

  • Comprehensive documentation — Architecture docs with Mermaid diagrams, AI pipeline docs, testing docs, PITFALLS.md
  • Type safety throughout — Full TypeScript, Zod validators as single source of truth, Drizzle type-safe queries
  • Testing culture — 649 test files, 17 E2E specs, nightly runs, production smoke tests
  • Security by default — RLS, magic link auth, rate limiting, Helmet.js, CORS, input sanitization
  • Music domain authenticity — Proper terminology, alphaTab rendering, time signature support
  • DevOps maturity — Ansible playbook, Watchtower auto-updates, GitHub Actions CI/CD

Weaknesses & Risks

  • VPN link brittleness — Single point of failure for AI features; host sleep can drop the tunnel, though graceful degradation is in place
  • AI notation quality — 89-94% success rate; remaining failures need monitoring
  • Redis single point of failure — No replication; jobs lost on restart without proper persistence
  • alphaTab blocks Turbopack — Requires webpack plugin, preventing Next.js Turbopack adoption
  • Qwen inference latency — 30-90 seconds per generation on Mac Mini
  • PWA deferred — Offline practice tools not yet available

Connection to Other Projects

  • Roughneck — AI inference routed through Roughneck's plugin-based job queue (etyde-session, etyde-set plugins)
  • CNC — Health monitoring, error aggregation, and LLM-powered error classification
  • AbletonBuddy — Both in music domain; complementary (learning vs. production)