Skip to content

MVP Analysis & Proposal

Date: 2026-01-19 Status: Draft for Review

This document analyzes the current project documentation set (docs/) and proposes specific implementation paths to align any conflicting specifications. The primary goal is to ensure the Rails 8.1 + Hotwire stack is correctly implemented.

  • Observation: Earlier source material referenced a different stack than the current target. The current docs specify Ruby on Rails 8.1 + Hotwire.
  • Risk: Following older material blindly can lead to building the wrong system.
  • Proposal: Rails 8.1 is the single source of truth for the stack. The backend is a monolith using Hotwire (Turbo/Stimulus), not a separate API + SPA.
  • Observation: PRD asks for “Individual (email/pass)” and “Company Seats (magic link)”.
  • Proposal:
    • Use devise for the primary User model (Individuals & Company Admins).
    • Use passwordless (or devise-passwordless) for a separate CompanySeat model or a specific login flow for seats to meet the “magic link” requirement without complexity.
  • Observation: “Open questions” ask about rounding (per-minute vs per-second).
  • Proposal: Per-started-minute for MVP.
    • Reasoning: Simplifies the ledger logic and user communication (“2 credits/min”). Reduces risk of micro-transaction calculation errors in the first iteration.
  • Observation: WebRTC requires short-lived tokens.
  • Proposal:
    • Implement strict rack-attack rules on the /api/calls/token endpoint.
    • Enforce E.164 normalization on the server side using the phony gem before passing numbers to Twilio.

3. Implementation Proposal (Rails 8.1 Optimized)

Section titled “3. Implementation Proposal (Rails 8.1 Optimized)”

Instead of a generic “SPA + API” flow, we will use standard Rails patterns:

  • Controllers: standard MVC for logic.
  • Views: ERB with Turbo Frames for partial updates (e.g., balance updates, call status).
  • Real-time: Use Turbo::Streams over ActionCable for call status updates (ringing -> connected -> ended), pushed directly from Twilio webhook callbacks.

The schema concepts are solid but need adaptation for Rails conventions (snake_case vs camelCase).

  • Users: credit_balance (cents), default_caller_id.
  • Calls: sid, duration (integer seconds), cost_cents.
  • Transactions: amount_cents, source_type (polymorphic association or enum).
  • Job Queue: Use Solid Queue (Rails 8 default) instead of Sidekiq/Redis to simplify the stack.
  • Asset Pipeline: Propshaft + esbuild (via jsbundling-rails) to support the Twilio Voice SDK properly.
  1. Initialize Rails 8.1 App: rails new mobayilo --css=tailwind --javascript=esbuild.
  2. Domain Modeling: Create User (Devise) and Transaction models first to establish the “Wallet”.
  3. Twilio Integration: Implement the TokenGenerator service and TwiML controller.
  4. Frontend: Build the Dialer using Stimulus controllers to wrap the twilio-voice SDK.
  5. Billing: Implement the Stripe webhook handler and the Call Cost Calculator service.
  • Stack: Rails 8.1 monolith + Hotwire.
  • Billing (MVP): per-started-minute rounding.
  • Jobs: Solid Queue (DB-backed, Rails default).