Skip to content

Mobayilo Web App - Project Summary

Build a mobile-first, browser-based international calling web app:

  • Users sign up with email/password
  • Users top-up credits (pay-as-you-go)
  • Users place outbound calls from the browser (WebRTC) to real phone numbers (PSTN)

Website: https://mobayilo.com

  • Authentication (email/password, password reset)
  • Company seats (passwordless magic links)
  • Credits wallet (balance in cents) + transaction ledger
  • Stripe top-ups (one-time credit purchases)
  • Optional auto top-up (threshold-based)
  • Dialer UI (mobile-first) + Twilio Voice JS SDK
  • Recent numbers (server-side, per account)
  • Twilio webhooks validated + processed asynchronously
  • Call logging (status, duration) and cost deduction after completion
  • Rate lookup (price/min) by destination
  • Static pricing table (YAML) with company vs individual rates
  • Optional Caller ID verification for individual accounts (Twilio), server-enforced
  • Backend: Ruby on Rails 8.1
  • Frontend: Hotwire (Turbo + Stimulus) + Tailwind CSS
  • Database: PostgreSQL
  • Voice: Twilio Programmable Voice (WebRTC to PSTN)
  • Payments: Stripe (PaymentIntent + webhooks)
TokenHexUsage
action-blue#2A71E3Primary actions, call CTA, active states
action-blue-hover#1D5EC4Hover states for primary actions
soft-skygradientGlobal light background on app/marketing screens
apple-bluegradientDesktop hero backdrop for dialer/marketing surfaces
white#FFFFFFCard and frame surfaces
slate-900#0F172AMain text and headings
sky-100#E0F2FEBorders and subtle separators
RoleFont FamilyVariableUsage
HeadingsCormorant Garamondfont-headingPage titles, hero text, logo
BodyInconsolatafont-bodyInterface text, buttons, inputs
CodeGeist Monofont-monoCode snippets, technical logs
  • Buttons:
    • Radius: rounded-2xl
    • Vertical Padding: py-3 (standard), py-2 (compact)
    • Horizontal Padding: px-6 (standard)
  • Icons:
    • Library: Lucide / Heroicons (SVG)
    • Stroke: stroke-width="2"
    • Color: currentColor (inherit text color)
  • Layout:
    • Mobile (signed in): Full-screen iPhone app shell (shared/mobile_phone_shell) with in-frame navigation.
    • Mobile (signed out /home): Responsive marketing home (desktop-style content) for conversion.
    • Desktop: Responsive marketing + dialer layout with light blue theme.
  • Billing: per-started-minute.
  • Jobs: Solid Queue (Rails default).
  • Rate source: YAML table served via /api/rates/:iso (company seat sees company rates).
  • Desktop PageSpeed/Lighthouse hardening pass completed on development.
  • Replaced Google Fonts CDN usage with self-hosted WOFF2 font files; kept font-display: swap and added route-specific preloads on Home to avoid unused preload warnings.
  • Deferred third-party scripts (Simple Analytics, Tally) to first interaction; added analytics fallback load at 10s to preserve some bounce-session tracking.
  • Reduced critical request chain by removing external transparent texture dependency and replacing homepage feedback mail_to with internal contact route link.
  • Optimized large marketing images with responsive srcset/sizes and explicit dimensions to reduce oversized image downloads.
  • Minified production JS bundle (pnpm build) while preserving sourcemaps for dev (pnpm run build:dev --watch in Procfile.dev).
  • Split Twilio Voice SDK into a separate asset (app/javascript/twilio_sdk.js) and switched dialer controller to dynamic import, reducing unused JS on non-dialer paths.
  • Reduced main-thread long tasks by lazy-building country dropdown DOM entries in country_select_controller only when opened/searched.
  • Fixed Lighthouse non-composited animation flag by removing color-transition animation on the homepage calculator call-type toggle.
  • Aligned desktop /rates page with shared desktop marketing shell layout for consistency and easier maintenance.
  • Updated /how-it-works CTA behavior: single primary action routes signed-in users to /dial, signed-out users to /users/sign_in.
  • Twilio call reliability hardening: safer hangup/cancel flow, stale connect-attempt invalidation, and UI safety timeout.
  • Twilio voice webhook fail-safe added to always return TwiML under unexpected server exceptions.
  • Added production-safe callback base URL fallback (APP_BASE_URL support + HTTPS fallback in production).
  • Added regression test for webhook fallback behavior in twilio_controller_test.
  • Completed light-theme UI harmonization for mobile shell pages (Dialer, Contacts, History, Rates, Settings, sign-in/magic-link).
  • Preserved strict app-like shell for signed-in mobile while serving marketing-rich /home to signed-out mobile users.
  • Fixed Rates UX regressions (back-to-dialer placement, call type highlight mismatch, country dropdown readability).
  • Refined dialer spacing/font sizing to keep call controls fully visible in Safari mobile viewport.
  • Standardized top-right status labels to SIGN IN and ONLINE.
  • Fixed contact_path route generation bug in mobile shell/help center flow.
  • Fixed Cloudflare docs deploy workflow (pnpm/action-setup@v4, pinned pnpm, frozen lockfile install).
  • Added optional Caller ID verification flow for individual accounts with country-required national number + preview.
  • Integrated Twilio Outgoing Caller ID validation; handled “already verified” responses as success.
  • Added mobile-only “Back to dialer” button on legal pages (privacy/terms/cookies).
  • Added Simple Analytics script to the main layout.
  • Session timeout set to 30 days.
  • Mobile app-like shell for Contacts/History/Settings + Credits summary on mobile.
  • Mobile hamburger menus aligned with design and sign-in overlay kept inside phone frame.
  • Desktop pricing calculator uses searchable country picker + live rate API.
  • Admin can sync rates from YAML via Avo action; Twilio sync labeled clearly.
  • /dial gated behind authentication; public CTAs route to sign-in.
  • Styled static public/404.html error page aligned with brand.
  • Added R2 public CDN domain for Active Storage reads.
  • Flattened production DB config with cache/queue/cable fallbacks for local console access.
  • Docs now deploy via Cloudflare Pages project mobayilo-docs and are protected by Basic Auth.
Browser (Turbo/Stimulus + Twilio Voice JS)
↕ HTTPS
Rails (HTML + JSON endpoints + webhook handlers)
PostgreSQL (users, calls, rates, ledger)
↕ ↕
Stripe webhooks Twilio webhooks + TwiML
  • docs/PROJECT_STATUS.md - execution checklist and progress
  • docs/SETUP.md - environment variables + local dev webhooks
  • docs/PRD.md - requirements and open questions
  • docs/ARCHITECTURE.md - domain model and routes
  • Company allowlist: per-email allowlist vs domain-based allowlist
  • Number provisioning: company admin self-serve vs manual/admin-only (MVP)