# ilp90/music-composer architecture

> Architecture diagram of the GitHub repository ilp90/music-composer, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-11). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ilp90/music-composer
- Repository: https://github.com/ilp90/music-composer

## Overview

Music Composer is a browser-based camera-and-gesture instrument: users point at a circle-of-fifths overlay to play notes, then record and manage sessions. The web app also supports password and optional Google sign-in; recordings can be queued locally and uploaded to S3 through the API. The API handles identity, sessions, and recording metadata, with DynamoDB-backed repositories. The compose and upload internals are represented from documented capabilities and source-index references; unsampled implementation links are marked unverified.

Main entry points: [`apps/api/src/routes/auth.ts`](https://github.com/ilp90/music-composer/blob/main/apps/api/src/routes/auth.ts) (Authentication routes), [`apps/web/src/features/compose/ComposeStage.tsx`](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/ComposeStage.tsx) (Camera composition stage), [`apps/api/src/app.ts`](https://github.com/ilp90/music-composer/blob/main/apps/api/src/app.ts) (Fastify application), [`apps/api/src/routes/google.ts`](https://github.com/ilp90/music-composer/blob/main/apps/api/src/routes/google.ts) (Google OAuth routes)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_compose["Gesture composition"]
  node_compose_page["Compose page<br/>[ComposePage.tsx]"]
  node_compose_stage["Camera composition stage<br/>[ComposeStage.tsx]"]
  node_hand_tracking["Hand tracking<br/>[handTracking.ts]"]
  node_chart_mapping["Chart and view mapping<br/>[viewMapping.ts]"]
  node_audio["Note audio engine<br/>[audioEngine.ts]"]
  node_recording_capture["Session recording<br/>[recorder.ts]"]
end

subgraph group_recordings["Recording management"]
  node_recordings_page["Recordings library<br/>[RecordingsPage.tsx]"]
  node_local_store[("Local recordings<br/>[localStore.ts]")]
  node_upload_queue["Upload queue<br/>[uploadQueue.ts]"]
  node_uploader["Multipart uploader<br/>[uploader.ts]"]
end

subgraph group_identity["Identity and sessions"]
  node_auth_ui["Sign-in and registration<br/>[LoginPage.tsx]"]
  node_auth_provider["Web auth provider<br/>[AuthProvider.tsx]"]
  node_api_client["API client<br/>[apiClient.ts]"]
  node_google_ui["Google sign-in UI<br/>[GoogleSignIn.tsx]"]
end

subgraph group_api["API and persistence"]
  node_api_app["Fastify application<br/>[app.ts]"]
  node_auth_routes["Authentication routes<br/>[auth.ts]"]
  node_google_routes["Google OAuth routes<br/>[google.ts]"]
  node_recording_routes["Recording routes<br/>[recordings.ts]"]
  node_session_service["Session service<br/>[sessions.ts]"]
  node_token_service["Token service<br/>[tokens.ts]"]
  node_users_repo["User repository<br/>[users.ts]"]
  node_refresh_repo["Refresh-token repository<br/>[refreshTokens.ts]"]
  node_attempts_repo["Login-attempt repository<br/>[loginAttempts.ts]"]
  node_recordings_repo["Recording metadata repository<br/>[recordings.ts]"]
  node_storage_service["Object storage service<br/>[storage.ts]"]
end

node_composer(("Composer user"))
node_camera(("Camera and microphone"))
node_dynamo[("DynamoDB")]
node_s3[("S3-compatible storage")]
node_google(("Google OAuth"))

node_composer -->|"opens"| node_compose_page
node_compose_page -.->|"renders"| node_compose_stage
node_compose_stage -.->|"uses feed"| node_camera
node_compose_stage -.->|"tracks hands"| node_hand_tracking
node_compose_stage -.->|"maps gestures"| node_chart_mapping
node_compose_stage -.->|"triggers notes"| node_audio
node_compose_page -.->|"records session"| node_recording_capture
node_recording_capture -.->|"captures audio"| node_audio
node_recording_capture -->|"queues recording"| node_upload_queue
node_composer -->|"manages sessions"| node_recordings_page
node_recordings_page -->|"reads local"| node_local_store
node_recordings_page -->|"manages uploads"| node_upload_queue
node_upload_queue -.->|"dispatches upload"| node_uploader
node_uploader -.->|"requests upload"| node_api_client
node_uploader -.->|"uploads parts"| node_s3
node_composer -->|"signs in"| node_auth_ui
node_auth_ui -.->|"offers option"| node_google_ui
node_auth_provider -->|"calls API"| node_api_client
node_api_client -.->|"sends requests"| node_api_app
node_api_app -->|"registers"| node_auth_routes
node_api_app -->|"registers"| node_google_routes
node_api_app -->|"registers"| node_recording_routes
node_auth_routes -->|"reads and writes"| node_users_repo
node_auth_routes -->|"checks attempts"| node_attempts_repo
node_auth_routes -->|"rotates tokens"| node_refresh_repo
node_auth_routes -->|"starts sessions"| node_session_service
node_auth_routes -->|"handles tokens"| node_token_service
node_google_routes -->|"authenticates"| node_google
node_google_routes -->|"finds users"| node_users_repo
node_google_routes -->|"starts sessions"| node_session_service
node_session_service -->|"stores refresh family"| node_refresh_repo
node_session_service -->|"signs access token"| node_token_service
node_recording_routes -->|"stores metadata"| node_recordings_repo
node_recording_routes -->|"manages objects"| node_storage_service
node_recordings_repo -.->|"reads and writes"| node_dynamo
node_users_repo -->|"reads and writes"| node_dynamo
node_refresh_repo -.->|"reads and writes"| node_dynamo
node_attempts_repo -.->|"reads and writes"| node_dynamo
node_storage_service -->|"manages objects"| node_s3

click node_compose_page "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/ComposePage.tsx"
click node_compose_stage "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/ComposeStage.tsx"
click node_hand_tracking "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/handTracking.ts"
click node_chart_mapping "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/viewMapping.ts"
click node_audio "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/audioEngine.ts"
click node_recording_capture "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/recorder.ts"
click node_recordings_page "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/recordings/RecordingsPage.tsx"
click node_local_store "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/recordings/localStore.ts"
click node_upload_queue "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/recordings/uploadQueue.ts"
click node_uploader "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/recordings/uploader.ts"
click node_auth_ui "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/auth/LoginPage.tsx"
click node_auth_provider "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/auth/AuthProvider.tsx"
click node_api_client "https://github.com/ilp90/music-composer/blob/main/apps/web/src/lib/apiClient.ts"
click node_google_ui "https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/auth/GoogleSignIn.tsx"
click node_api_app "https://github.com/ilp90/music-composer/blob/main/apps/api/src/app.ts"
click node_auth_routes "https://github.com/ilp90/music-composer/blob/main/apps/api/src/routes/auth.ts"
click node_google_routes "https://github.com/ilp90/music-composer/blob/main/apps/api/src/routes/google.ts"
click node_recording_routes "https://github.com/ilp90/music-composer/blob/main/apps/api/src/routes/recordings.ts"
click node_session_service "https://github.com/ilp90/music-composer/blob/main/apps/api/src/services/sessions.ts"
click node_token_service "https://github.com/ilp90/music-composer/blob/main/apps/api/src/services/tokens.ts"
click node_users_repo "https://github.com/ilp90/music-composer/blob/main/apps/api/src/repositories/users.ts"
click node_refresh_repo "https://github.com/ilp90/music-composer/blob/main/apps/api/src/repositories/refreshTokens.ts"
click node_attempts_repo "https://github.com/ilp90/music-composer/blob/main/apps/api/src/repositories/loginAttempts.ts"
click node_recordings_repo "https://github.com/ilp90/music-composer/blob/main/apps/api/src/repositories/recordings.ts"
click node_storage_service "https://github.com/ilp90/music-composer/blob/main/apps/api/src/services/storage.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_compose_page,node_compose_stage,node_hand_tracking,node_chart_mapping,node_audio,node_recording_capture,node_composer toneBlue
class node_recordings_page,node_local_store,node_upload_queue,node_uploader,node_dynamo,node_s3 toneAmber
class node_auth_ui,node_auth_provider,node_api_client,node_google_ui toneMint
class node_api_app,node_auth_routes,node_google_routes,node_recording_routes,node_session_service,node_token_service,node_users_repo,node_refresh_repo,node_attempts_repo,node_recordings_repo,node_storage_service toneRose
class node_camera,node_google toneIndigo
```

## Components

### Gesture composition

- [Compose page](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/ComposePage.tsx): `apps/web/src/features/compose/ComposePage.tsx`
- [Camera composition stage](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/ComposeStage.tsx): `apps/web/src/features/compose/ComposeStage.tsx`
- [Hand tracking](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/handTracking.ts): `apps/web/src/features/compose/handTracking.ts`
- [Chart and view mapping](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/viewMapping.ts): `apps/web/src/features/compose/viewMapping.ts`
- [Note audio engine](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/audioEngine.ts): `apps/web/src/features/compose/audioEngine.ts`
- [Session recording](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/compose/recorder.ts): `apps/web/src/features/compose/recorder.ts`

### Recording management

- [Recordings library](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/recordings/RecordingsPage.tsx): `apps/web/src/features/recordings/RecordingsPage.tsx`
- [Local recordings](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/recordings/localStore.ts): `apps/web/src/features/recordings/localStore.ts`
- [Upload queue](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/recordings/uploadQueue.ts): `apps/web/src/features/recordings/uploadQueue.ts`
- [Multipart uploader](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/recordings/uploader.ts): `apps/web/src/features/recordings/uploader.ts`

### Identity and sessions

- [Sign-in and registration](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/auth/LoginPage.tsx): `apps/web/src/features/auth/LoginPage.tsx`
- [Web auth provider](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/auth/AuthProvider.tsx): `apps/web/src/features/auth/AuthProvider.tsx`
- [API client](https://github.com/ilp90/music-composer/blob/main/apps/web/src/lib/apiClient.ts): `apps/web/src/lib/apiClient.ts`
- [Google sign-in UI](https://github.com/ilp90/music-composer/blob/main/apps/web/src/features/auth/GoogleSignIn.tsx): `apps/web/src/features/auth/GoogleSignIn.tsx`

### API and persistence

- [Fastify application](https://github.com/ilp90/music-composer/blob/main/apps/api/src/app.ts): `apps/api/src/app.ts`
- [Authentication routes](https://github.com/ilp90/music-composer/blob/main/apps/api/src/routes/auth.ts): `apps/api/src/routes/auth.ts`
- [Google OAuth routes](https://github.com/ilp90/music-composer/blob/main/apps/api/src/routes/google.ts): `apps/api/src/routes/google.ts`
- [Recording routes](https://github.com/ilp90/music-composer/blob/main/apps/api/src/routes/recordings.ts): `apps/api/src/routes/recordings.ts`
- [Session service](https://github.com/ilp90/music-composer/blob/main/apps/api/src/services/sessions.ts): `apps/api/src/services/sessions.ts`
- [Token service](https://github.com/ilp90/music-composer/blob/main/apps/api/src/services/tokens.ts): `apps/api/src/services/tokens.ts`
- [User repository](https://github.com/ilp90/music-composer/blob/main/apps/api/src/repositories/users.ts): `apps/api/src/repositories/users.ts`
- [Refresh-token repository](https://github.com/ilp90/music-composer/blob/main/apps/api/src/repositories/refreshTokens.ts): `apps/api/src/repositories/refreshTokens.ts`
- [Login-attempt repository](https://github.com/ilp90/music-composer/blob/main/apps/api/src/repositories/loginAttempts.ts): `apps/api/src/repositories/loginAttempts.ts`
- [Recording metadata repository](https://github.com/ilp90/music-composer/blob/main/apps/api/src/repositories/recordings.ts): `apps/api/src/repositories/recordings.ts`
- [Object storage service](https://github.com/ilp90/music-composer/blob/main/apps/api/src/services/storage.ts): `apps/api/src/services/storage.ts`

### Other components

- **Composer user**
- **Camera and microphone**
- **DynamoDB**
- **S3-compatible storage**
- **Google OAuth**

## Connections

- Composer user → Compose page: opens
- Compose page → Camera composition stage: renders
- Camera composition stage → Camera and microphone: uses feed
- Camera composition stage → Hand tracking: tracks hands
- Camera composition stage → Chart and view mapping: maps gestures
- Camera composition stage → Note audio engine: triggers notes
- Compose page → Session recording: records session
- Session recording → Note audio engine: captures audio
- Session recording → Upload queue: queues recording (evidence: `apps/web/src/features/compose/useRecording.ts`)
- Composer user → Recordings library: manages sessions
- Recordings library → Local recordings: reads local (evidence: `apps/web/src/features/recordings/RecordingsPage.tsx`)
- Recordings library → Upload queue: manages uploads (evidence: `apps/web/src/features/recordings/RecordingsPage.tsx`)
- Upload queue → Multipart uploader: dispatches upload
- Multipart uploader → API client: requests upload
- Multipart uploader → S3-compatible storage: uploads parts
- Composer user → Sign-in and registration: signs in
- Sign-in and registration → Google sign-in UI: offers option
- Web auth provider → API client: calls API (evidence: `apps/web/src/features/auth/AuthProvider.tsx`)
- API client → Fastify application: sends requests
- Fastify application → Authentication routes: registers (evidence: `apps/api/src/app.ts`)
- Fastify application → Google OAuth routes: registers (evidence: `apps/api/src/app.ts`)
- Fastify application → Recording routes: registers (evidence: `apps/api/src/app.ts`)
- Authentication routes → User repository: reads and writes (evidence: `apps/api/src/routes/auth.ts`)
- Authentication routes → Login-attempt repository: checks attempts (evidence: `apps/api/src/routes/auth.ts`)
- Authentication routes → Refresh-token repository: rotates tokens (evidence: `apps/api/src/routes/auth.ts`)
- Authentication routes → Session service: starts sessions (evidence: `apps/api/src/routes/auth.ts`)
- Authentication routes → Token service: handles tokens (evidence: `apps/api/src/routes/auth.ts`)
- Google OAuth routes → Google OAuth: authenticates (evidence: `apps/api/src/routes/google.ts`)
- Google OAuth routes → User repository: finds users (evidence: `apps/api/src/routes/google.ts`)
- Google OAuth routes → Session service: starts sessions (evidence: `apps/api/src/routes/google.ts`)
- Session service → Refresh-token repository: stores refresh family (evidence: `apps/api/src/services/sessions.ts`)
- Session service → Token service: signs access token (evidence: `apps/api/src/services/sessions.ts`)
- Recording routes → Recording metadata repository: stores metadata (evidence: `apps/api/src/routes/recordings.ts`)
- Recording routes → Object storage service: manages objects (evidence: `apps/api/src/routes/recordings.ts`)
- Recording metadata repository → DynamoDB: reads and writes
- User repository → DynamoDB: reads and writes (evidence: `apps/api/src/repositories/users.ts`)
- Refresh-token repository → DynamoDB: reads and writes
- Login-attempt repository → DynamoDB: reads and writes
- Object storage service → S3-compatible storage: manages objects (evidence: `apps/api/src/services/storage.ts`)
