Book a Call
AI Product StudioEst. 2014
Music Education2025-2026
Angeles One

Angeles One

Five tools replaced. Zero compromises.

Angeles Academy of Music was running their entire operation across five disconnected systems. We built Angeles One from scratch: a complete CRM and business engine purpose-built for music education. 34 serverless functions. 166 API routes. 25 database tables with 95 migrations. 128 UI components across 26 views. AI-powered communication summaries. Every phone call, email, and text message tracked automatically across three location inboxes. RingCentral screen pop caller ID. Token-based withdrawal processing. Real-time sales dashboards. One platform replacing five, built in four months, owned outright by the client.

5
Systems Replaced
Opus1, Webflow, Sheets, AppSheet, and Zapier unified
34
Lambda Functions
Serverless compute powering every operation
4mo
Time to Ship
Enterprise-grade platform, startup timeline
$0/mo
SaaS Fees
Client owns everything, no subscriptions

Overview

Challenge

Five disconnected systems meant five logins, data in five places, and hours of manual reconciliation weekly. Opus1 for student records. Webflow for prospect capture. Google Sheets for reporting. AppSheet for internal workflows. Zapier gluing it all together. No unified communication tracking across locations. No AI capabilities. No real-time dashboards. And critically, no generic CRM could model what makes music education unique: parents as account managers for multiple children, students matched to instructors by instrument and location, lessons as ongoing subscriptions with pause/cancel/reactivate lifecycle, partial withdrawals with billing deadline logic, and family groupings where a single intake call creates an account manager, three students, six lessons, and a dozen related records in one atomic operation.

Solution

We built Angeles One from scratch as a complete replacement for all five systems. A React + Vite frontend with 128 components across 26 purpose-built views. A fully serverless backend: 34 AWS Lambda functions serving 166 API routes across 35 handler domains. Supabase PostgreSQL with 25 tables and 95 migrations modeling the entire music education lifecycle. 9 SQS queues with dead-letter queues for fault-tolerant async processing. RingCentral integration capturing every call, SMS, and voicemail with screen pop caller ID. Gmail API polling three location inboxes (Brentwood, Tarzana, and main office) every 60 seconds. AWS Bedrock with Claude generating AI summaries of every communication. Webflow webhook capture with GCLID tracking for Google Ads attribution and automatic generation of a 4-task follow-up cadence for the sales team. Stripe-integrated enrollment processing. A token-based withdrawal system with cryptographically secure links, per-lesson feedback collection, and automated cancellation cascades. DynamoDB-backed idempotency ensuring every webhook event processes exactly once across 40,000+ tracked events.

Outcome

One login replaced five. Staff went from toggling between disconnected tools to a single dashboard that surfaces information before they ask for it. When a parent calls, their full profile, lesson history, every prior communication, and AI-generated summaries pop automatically. When a prospect submits a form on the website, it appears in the pipeline within seconds with Google Ads attribution preserved and a 4-task follow-up cadence auto-generated at day 1, 4, 6, and 30. Staff claim prospects, work the tasks, and when a prospect converts to enrolled, remaining future tasks are automatically marked as "Unreached - Converted" so performance metrics stay accurate. When a student withdraws, the system handles deadline calculations, generates a secure parent feedback form, collects per-instructor ratings, and cascades status changes across all related records automatically. Real-time sales dashboards by location, staff member, and time period replaced weekly spreadsheet assembly. The complete activity feed tracks every internal action and every external communication in one unified timeline. The client owns the platform outright with no recurring SaaS fees, and the architecture was designed for their junior developers to maintain and extend.

The Story

The five-tool problem

Each system served a purpose. Opus1 tracked students and lessons. Webflow powered the marketing site and prospect forms. Google Sheets handled reporting and reconciliation. AppSheet managed internal workflows. Zapier tried to wire them all together.

On paper, it worked. In practice, staff toggled between five logins daily. Data lived in five places, and keeping it synchronized meant hours of manual reconciliation every week. When a parent called, no one had the full picture without checking multiple systems. When the team wanted performance numbers, someone had to pull data from three tools and assemble a report by hand.

The deeper problem was structural. Generic CRM platforms don't understand music education. The relationships are unique: parents are account managers for their children. A single family might have a parent managing three children, each studying different instruments, with different instructors, at different locations, on different schedules. Students get matched to instructors by instrument, location, and availability. Enrollments involve 16 discrete steps covering contact details, instrument selection, lesson scheduling, payment processing, and policy acknowledgment. Withdrawals can be partial (dropping one lesson while keeping another) and need billing deadline logic, feedback collection, and automated cleanup of downstream records.

No off-the-shelf tool models this. So the staff worked around limitations instead of through streamlined workflows. Every workaround was time spent on the software instead of on the students.

The Approach

Why this had to be built, not bought

Angeles Academy needed software that understood their business at a structural level. Not a CRM with a "students" field bolted on. A system where the entire data model, every table, every relationship, every workflow, was designed around how music education actually operates.

The data model we built spans 25 PostgreSQL tables across 95 migrations. Clients carry role flags (is_student, is_account_manager, is_dependent) that aren't mutually exclusive. A parent is an account manager. Their children are dependents and students. The client_relationships table models these connections explicitly with AccountManagerOf and DependentOf relationship types, complete with primary flags and date ranges. When you open a client profile, you see their family grouped together: the parent's account with each child's lessons, instructors, and enrollment history nested underneath.

Lessons are first-class entities, decoupled from enrollments. Each lesson tracks its own lifecycle (Active, Paused, Cancelled, Withdrawing) with its own instructor assignment, schedule, instrument, level, and tuition. A student can have multiple concurrent lessons. Pausing one doesn't affect others. Withdrawing from one triggers its own feedback flow while the rest continue. This granularity was impossible in the old system.

The enrollment pipeline models the actual intake call. When a parent calls to enroll three children, the staff member walks through a 16-section guided form: student type (Adult or Child), contact information with existing client search, instrument selection with admin-configurable scripts that change dynamically based on student type and proficiency level, studio location (Brentwood, Westwood, Tarzana, or Online), availability grid, lesson scheduling, instructor matching, pricing with discount support, policy acknowledgment checkboxes (tuition, makeups, substitutes, calendar), Stripe payment collection, and staff assignment. One atomic API call creates the account manager, all student records, all family relationships, all lesson records, all enrollment records, and all activity events. If anything fails, everything rolls back.

Communication tracking is truly unified. RingCentral integration captures every phone call, SMS, and voicemail via webhook subscriptions that auto-renew every 6 days. Gmail API integration polls three location inboxes (brentwood@, info@, and tarzana@angelesacademyofmusic.com) every 60 seconds using a service account with domain-wide delegation and history-based polling via SSM Parameter Store. Every communication is automatically matched to a client record by phone number or email address, normalized to E.164 format. Unmatched communications surface in a triage view. And every communication, whether it's a 30-minute phone call or a quick email, gets an AI-generated summary via AWS Bedrock so staff get context in seconds.

This level of domain specificity doesn't exist in generic software. It had to be built.

The Details

Everything connects through the activity feed

The activity feed is where everything comes together. Every client profile has a unified timeline that merges internal staff actions with external communications into one chronological view. When you open a client's profile, you see the complete story: when they were created as a prospect, every phone call and email exchange, when their manager was changed, when their child was enrolled, every instructor change, every note added, every lesson created or modified, and every withdrawal initiated or completed.

The system tracks over 20 distinct activity types. Internal actions like client_created, client_enrolled, managed_by_change, instructor_change, relationship_added, lesson_created, lesson_upgraded, lesson_downgraded, and withdrawal_initiated are logged automatically whenever staff take action anywhere in the platform. Each activity event records who performed the action, which staff member was involved, the previous and new values for any change, and structured metadata in JSONB for rich context.

Communication events from RingCentral and Gmail flow into the same timeline. A phone call shows the duration, direction, caller ID match, and AI summary. An email shows the subject, body preview, and which inbox it came through. SMS messages and voicemails each have their own transformer handling the specific data shape from their source system. The result is that when a parent calls about their child's lesson, the staff member sees not just the call history, but every enrollment change, instructor swap, note, and withdrawal attempt in one scrollable feed.

This is the kind of integration that falls apart with disconnected tools. When communications live in RingCentral, notes live in a CRM, and enrollment changes live in a spreadsheet, nobody has the full picture. Angeles One puts everything in one place, automatically, with zero manual data entry.

The Transformation

What we rebuilt

Client Lifecycle & Family Modeling

Clients flow through Prospect, Enrolled, Former, and Lost statuses with role flags (student, account manager, dependent) that model real family structures. Parents are first-class account managers for their children. The client_relationships table tracks AccountManagerOf and DependentOf connections. A single family view groups parents with all their children's lessons, instructors, and enrollment history.

Unified Communications

Every phone call, email, SMS, and voicemail captured automatically across three location inboxes. RingCentral webhook integration with screen pop caller ID so staff see full client profiles when the phone rings. Gmail API polling via service account with domain-wide delegation every 60 seconds using history-based incremental sync with SSM-persisted state. E.164 phone normalization and automatic client matching. Unmatched communications surface in a triage view. A backfill recovery endpoint can re-ingest the last N days of RingCentral or Gmail data with dry-run mode and idempotency checks, routing recovered items through the normal SQS pipeline.

AI-Powered Summaries

AWS Bedrock with Claude generates concise summaries of call transcripts, email threads, SMS exchanges, and voicemail transcriptions. Each summary captures the topic, action items, and sentiment. Async processing via a dedicated SQS queue with dead-letter queue means zero UI lag. Graceful degradation ensures communication events are never lost if AI processing fails.

Activity Feed & Audit Trail

Over 20 activity types tracked automatically: client creation, enrollment, instructor changes, manager reassignment, lesson modifications, withdrawal lifecycle events, notes, and relationship changes. Each event records who performed the action, previous and new values, and structured metadata. Merges with communication events into one unified timeline per client profile.

Enrollment Pipeline

A 16-section guided intake form supporting both Adult and Child enrollment modes. Covers student type, contact info with existing client search, instrument selection with admin-configurable scripts, proficiency level, studio location, availability grid, lesson scheduling, instructor matching, pricing with discounts, policy acknowledgment, Stripe payment, and staff assignment. One atomic API call creates all records or rolls back entirely. When the outcome is Prospect, the system auto-generates a 4-task follow-up cadence. When the outcome is Enrolled, all pending prospect tasks are bulk-completed with reached tasks marked "Enrolled" and future tasks marked "Unreached - Converted."

Smart Withdrawals

Token-based workflow using cryptographically secure 256-bit tokens (SHA-256 hashed). Staff initiates, parent receives a 30-day secure link. Public form collects per-lesson feedback: withdrawal reasons, instructor ratings (1-10), recommendation scores, and return likelihood with expected month. Deadline logic: request by the 15th means effective next month; after the 15th means two months out. Daily CRON at 2 AM PST processes deferred cancellations. Lessons transition Active to Withdrawing to Cancelled. Reversible within the deadline window.

Sales Dashboards & Revenue Tracking

Real-time KPIs by location (Brentwood, Westwood, Tarzana, Online), staff member, and time period. Company-wide performance with sales vs. withdrawals vs. goals. Lead conversion rates. Teacher retention and withdrawal metrics. Lesson adjustment tracking: when a student upgrades from 30 to 60 minutes or downgrades, the system logs the change as an activity event and calculates the net unit impact (in 30-minute units) for a CFO-level revenue view. Pre-CRM instructor and location baseline data is blended with live post-CRM metrics so the team can measure whether the new system actually improved performance. Daily and weekly breakdowns with 38 months of historical data. Snapshot saving for month-over-month comparison.

Data Migration & Sync

Complete import pipeline from legacy Opus1 CRM. CSV upload with staging, validation, deduplication by opus_client_id, and batch processing via FIFO SQS queue. DynamoDB-backed checkpointing enables auto-resume on Lambda timeout (supports 15-minute processing windows with up to 50 retries). Enrollment sync reconciles active student rosters with change preview and demotion detection before promoting to live database. Manual matching for ambiguous records. Zero data loss.

Architecture

The new foundation

A fully serverless, event-driven architecture across 7 CloudFormation stacks. 34 Lambda functions (ARM64, Node.js 20) serve 166 API routes via HTTP API Gateway. 9 SQS queues (4 FIFO + DLQ pairs, 1 standard + DLQ) power async processing with idempotency backed by DynamoDB (40,000+ tracked events). 5 EventBridge rules schedule Gmail polling, RingCentral subscription renewal, daily lesson cancellations, lesson adjustments, and dev data sync. Supabase PostgreSQL with row-level security as the primary datastore. Full dev/prod environment parity with separate Supabase instances, API stacks, and frontend deployments.

React + Vite Frontend

26 views, 128 components, 48,742 lines of source

React 18, TypeScript, Tailwind, Radix UI

Serverless API

34 functions, 166 routes, 29,457 lines of TypeScript

Node.js 20, AWS Lambda (ARM64), API Gateway

Supabase PostgreSQL

Full music education data model with row-level security

25 tables, 95 migrations, trigram indexes

DynamoDB

Idempotency (40K+ events), import/sync job checkpointing

On-demand, GSI, TTL auto-cleanup

SQS Event Processing

Communications, AI summaries, client imports, enrollment sync

4 FIFO + 1 standard queue, all with DLQs

EventBridge Scheduler

Gmail polling (60s), subscription renewal (6d), daily CRON jobs

5 production rules

RingCentral Integration

Calls, SMS, voicemail capture + screen pop caller ID

JWT auth, webhook subscriptions

Gmail Integration

3 location inboxes polled every 60s via History API

Service account, domain-wide delegation

AWS Bedrock

AI communication summarization pipeline

Claude 3 Haiku + Sonnet fallback

Stripe

Payment collection embedded in enrollment flow

Stripe.js + React Stripe Elements

CI/CD Pipeline

Auto-deploy dev on push, manual trigger for prod

GitHub Actions, SAM, S3 deploy

Technology Stack

The modern toolkit

React
ReactFrontend
TypeScript
TypeScriptLanguage
Tailwind CSS
Tailwind CSSStyling
Node.js
Node.jsBackend
AWS Lambda
AWS LambdaCompute
PostgreSQL
PostgreSQLDatabase
Stripe
StripePayments
AWS S3
AWS S3Storage
AWS
AWSInfrastructure

The Result

See what emerged

Client Management

The central hub for all client relationships. Clients flow through Prospect, Enrolled, Former, and Lost statuses with role flags for student, account manager, and dependent. Trigram-indexed fuzzy search. Bulk actions. Staff assignment.

Client Directory

Searchable list with status filters, role filters, managed-by filters, sorting, and inline actions

Client Profile

Complete client view with at-a-glance card, contact info, recent activity, and quick actions

Contact Details

Phone numbers, emails, address, location, and linked webform submissions

Family Relationships

Account managers and dependents displayed with cross-linking to each family member's profile

Lessons Tab

All active and historical lessons with instrument, instructor, schedule, and status management

Notes

Paginated notes with timestamps, creator info, and add-new functionality

Activity Feed & Communications

A unified timeline merging 20+ internal activity types with communications from RingCentral and Gmail. Every phone call, email, SMS, voicemail, enrollment change, instructor swap, and note in one chronological view per client.

Activity Timeline

Chronological feed of all internal actions and external communications with expandable details

Call Tracking

Inbound and outbound calls with duration, direction badge, AI summary, and recording link

Email Tracking

Gmail-captured emails with subject, body preview, inbox source, and AI summary

Staff Action Log

Instructor changes, manager reassignment, enrollment events, and lesson modifications with before/after values

All Communications

Filterable view of all phone, email, SMS, and voicemail events across the entire platform

Unmatched Triage

Communications not yet linked to clients, surfaced for manual matching so nothing falls through

Enrollment Pipeline

A guided 16-section intake supporting Adult and Child enrollment modes. One atomic API call creates account managers, students, family relationships, lessons, enrollments, and activity events. Admin-configurable scripts guide staff through each section.

Student Type Selection

Adult vs. Child toggle that configures the entire form flow

Contact Information

Parent/guardian details with existing client search and phone number formatting

Student Manager

Add, edit, and remove child students with per-student lesson configuration

Instrument & Level

Instrument selection with conditional scripts that adapt based on student type and proficiency level, plus visual variant styling

Availability Grid

Day and time slot selector for lesson scheduling across locations

Policies & Payment

Policy acknowledgment checkboxes, Stripe payment collection, and staff assignment

Screen Pop Caller ID

When the phone rings, RingCentral triggers a screen pop that instantly surfaces the caller's full client profile, lesson history, recent communications, and AI summaries before the staff member even picks up. Special alerts flag blacklisted clients, celebrity clients, and prospect status so staff know the context before they answer. If the number doesn't match any record, the screen pop redirects to a new client form with the phone number pre-filled.

Caller ID Lookup

Instant phone number match against all client records with E.164 normalization

Client Alerts

Blacklisted, celebrity, and prospect status flags surface immediately so staff know context before answering

New Client Fallback

Unrecognized numbers redirect to a new client form with the phone number pre-filled

Sales Dashboards & Revenue Tracking

Real-time analytics replacing manual spreadsheet assembly. Recharts-powered visualizations with bar charts, trend lines, and pie charts. 38 months of historical data with snapshot saving for month-over-month comparison. Pre-CRM baseline blending for before/after ROI measurement. Lesson adjustment tracking with net unit revenue impact.

Company Overview

Sales vs. withdrawals vs. goals with net growth trend lines and win rate percentage

Staff Performance

Per-staff sales tracking with rankings, conversion rates, and trending indicators

Location Breakdown

Side-by-side comparison across Brentwood, Westwood, Tarzana, and Online

Goal Tracking

Set and monitor sales targets by staff member and time period

Lead Conversions

Enrollment outcome distribution and daily/monthly conversion rate analysis

Lesson Adjustments

Track upgrades and downgrades with net unit impact in 30-minute units for CFO-level revenue analysis

Historical Baselines

Pre-CRM instructor and location metrics blended with live data for before/after performance comparison

Smart Withdrawals

Token-based withdrawal processing with 256-bit cryptographic tokens, 30-day expiration, billing deadline logic, per-lesson feedback collection, and automated status cascades. Daily CRON processes deferred cancellations at 2 AM PST.

Staff Initiation

Staff triggers withdrawal, system generates a secure SHA-256 hashed token with 30-day expiry

Parent Feedback Form

Public token-protected form collecting reasons, per-instructor ratings (1-10), recommendation scores, and return plans

Deadline Logic

Automatic calculation: before 15th means effective next month, after 15th means two months out

Prospect Pipeline & Task Cadence

Every new prospect, whether from a Webflow form or an enrollment call, automatically triggers a 4-task follow-up cadence at day 1, 4, 6, and 30. Staff claim prospects to take ownership, and all pending tasks reassign to the claiming staff member. Tasks only appear in the queue when their actionable date arrives. When a prospect converts to enrolled, reached tasks are marked "Enrolled" and unreached future tasks are marked "Unreached - Converted" so sales performance metrics stay accurate. Returning contacts who were formerly Lost or Former and re-engage via the website get their lifecycle reactivated back to Prospect with a fresh 4-task cadence, while all their previous history, withdrawal records, and communications are preserved for context.

Prospect Queue

Incoming leads with source tracking, GCLID for Google Ads attribution, and staff claim/unclaim system that reassigns all pending tasks

Auto-Generated Task Cadence

4 follow-up tasks created automatically at day 1, 4, 6, and 30 with actionable dates hidden until they're due

Task Calendar

Calendar sidebar showing task counts by date with filters for status, staff assignment, and task type

Task Completion

Record results, notes, and contact methods used (called, texted, emailed) when completing follow-up tasks

Home Dashboard

Quick stats showing prospect, enrolled, student, and account manager counts at a glance

Data Migration & Sync

Complete import pipeline from legacy Opus1 CRM with DynamoDB-backed checkpointing for fault-tolerant processing. FIFO SQS queues ensure ordered processing. Supports 15-minute Lambda windows with auto-resume on timeout.

CSV Import

Upload and parse CSV files with automatic deduplication by opus_client_id

Staging & Validation

Preview all records before promotion with match status, conflict detection, and manual matching for ambiguous records

Batch Promotion

Promote validated staging records to live database with rollback support and error tracking

Enrollment Sync

Reconcile active student rosters from Opus1 with demotion preview, exclusion lists, and bulk lesson creation

Staff Import

Bulk import of instructor and staff records from external systems

Customer Service & Case Management

Post-enrollment support and retention system. Staff track ongoing issues by type (Scheduling, Teacher Change, Withdrawal, Refund, MIA, Credit, Policy, Makeup, Recital, Referral, Watch, Add Lesson, Summer Travels) with priority levels, deadline tracking, overdue alerts, and staff assignment. Cases are tied to client records so the full context is always available.

Case Queue

Filterable list of open cases with priority badges (Urgent, Normal, Low), status tracking (In Progress, Watch, Stuck, Done), and deadline alerts

Case Details

Full case view with issue type, responsible client, assigned staff, notes, follow-up dates, and linked client profile

Bulk Actions

Reassign multiple cases, change priorities, and manage workload across the support team

Administration

Role-based access control with admin, staff, and readonly roles. User invitation and password reset flows via Supabase auth. Staff management with location preferences, roles, and credentials.

User Management

Create accounts, assign roles, enable/disable access, and send invitation emails

Staff Directory

Instructors and managers with roles, location preferences, contact info, and hire dates

Metric Baselines

Admin-only configuration for historical metric baselines and instructor performance tracking

Only accepting 1 new project in Q2

Ready to build something
extraordinary?

Let's discuss how we can bring your vision to life.

Book a Discovery Call