Full Stack Engineer · Dec 2025 to PresentLive · Production Tutoring Marketplace

iPractis

Case Study

A two-sided online tutoring marketplace connecting students with top-rated tutors. Built for quality 1-on-1 learning: from discovery to payout, featuring flexible scheduling, integrated live video lessons, and reliable payments.

iPractis tutoring marketplace

What made it hard

Two-sided marketplace

Students book lessons with flexible timing. Tutors set their own rates and receive automatic payouts.

Auditable financial ledger

Balances are never simple editable numbers. Every transaction is derived directly from verified history.

Concurrent slot booking

Guarantees that simultaneous booking attempts across different timezones never result in a double booking.

Automated lesson lifecycle

Built-in workflows handle cancellations, rescheduling, and credits smoothly without manual intervention.

An immutable ledger for transparent billing

Instead of storing a mutable balance column that gets edited, every payment, lesson credit, platform fee, and refund is recorded as an immutable row. Balances are derived dynamically from transaction history, ensuring full auditability for both students and tutors.

To keep payments reliable and extensible, I structured billing flows using the Strategy pattern. This separates card checkouts, internal wallet credits, and PayPal tutor payouts behind a clean, interchangeable contract. Combined with a dedicated repository layer and strict database constraints, it eliminates race conditions and guarantees that tutor earnings are safeguarded until sessions are completed.

Clean Refunds

Refunds write new referencing entries instead of altering past records, keeping accounting history fully intact.

Payout Window

Tutor earnings clear after lesson completion rather than at checkout, providing a fair window to resolve issues.

Strategy Pattern

Payment methods use pluggable adapters, making it straightforward to add new payout rails without touching booking code.

Upgrading to in-platform LiveKit video

Earlier versions relied on external Google Meet links shared in calendar invites. While easy to set up initially, external meetings meant users had to leave the platform, attendance could not be confirmed automatically, and lesson completion required manual reporting.

To fix this, I migrated the classroom experience to an integrated LiveKit WebRTC video service. Lessons take place directly inside the web application with custom controls and screen sharing. The service verifies short-lived tokens against the active booking window, tracks participant presence in real time, and automatically marks lessons as completed once the session wraps up.

Verified Attendance

Webhooks track when students and tutors join and leave, automating completion and payout triggers.

Zero Friction

Students join high-quality WebRTC video calls directly in the browser with no external app installs.

Tokenized Rooms

Access tokens are scoped to the exact booking timeframe, ensuring only the assigned student and tutor can enter.

Isolated admin console and modular architecture

Managing platform operations required an internal tool for tutor vetting, dispute handling, and payout reviews. I built the admin console as an independent application with its own authentication pipeline, keeping internal staff controls completely isolated from the public student and tutor interface.

Both applications share a clean modular architecture organized into domains like lessons, billing, profiles, and catalog. Following the Repository and Adapter patterns kept business rules decoupled from external SDKs and database queries. Data deletions in financial or booking contexts are handled via soft deletes, ensuring historical integrity is always preserved.

Localization

Interface copy is pre-translated for optimal loading speed. Dynamic content such as tutor bios and lesson descriptions is translated on demand and cached by content hash, so any tutor profile update refreshes the cache immediately without serving stale data.

Observability & Queues

Sentry monitors client errors and silent background failures in production. For asynchronous workflows such as booking reminders, session notifications, and lesson status changes, a pub/sub queue pipeline executes scheduled background tasks smoothly without slowing down user requests.

Reflections & What I'd Do Differently

What worked well was committing to modular architecture and clean design patterns early. Using the Adapter pattern for external services, the Strategy pattern for payment rails, the Repository pattern for data operations, and a Pub/Sub queue for scheduled background tasks kept business logic clear and maintainable. Migrating from Google Meet to in-platform LiveKit video was also a major win, giving us reliable attendance tracking and keeping users inside the application.

What I would do differently: the project grew very fast, making strict folder structure discipline and boundary enforcement essential from the start. I should have set up a monorepo from day one to share schemas and UI components cleanly with the admin console, and spent more time on upfront design before building to avoid revising user flows later.

Walkthrough

ipractis — 1
ipractis — 2
ipractis — 3
ipractis — 4