🔧 Mechanics Management
💰 Pricing Configuration
⚙️ Global Pricing Settings
🔧 Services
🚗 Dispatch Logic
⚖️ Dispatch Scoring Weights (must total 100%)
💵 Profit Per Hour Thresholds
📊 Utilization Settings
🎯 Radius Settings
👷 Contractor Settings
📋 Job Board Settings
💰 Payout Settings
🏆 Payout Tiers
🎁 Bonuses
🚗 Travel Reimbursement
🏢 Business Information
📋 Business Details
📍 Service Area
🕐 Business Hours
Text shown to customers on the website
Check the days your business is closed
🌐 Timezone
📅 Scheduling Settings
Time slots shown on the booking calendar
👤 Admin Users Management
Manage who can access this admin portal via Google Sign-In
✅ Currently Signed In
📧 Allowed Google Accounts
These Google accounts can sign in to the admin portal. PIN access is always available as backup.
📍 Live Mechanic Locations
Track real-time GPS positions of all mechanics in the field
📚 MTMM System Documentation
v2.1.0🏠 Welcome to Mark The Mobile Mechanic Documentation
This comprehensive wiki covers all aspects of the MTMM platform including architecture, integrations, configurations, and operational procedures.
🛠️ Tech Stack
🏗️ System Architecture
High-Level Architecture
🔄 Voice AI Call Flow
1. 📞 Customer calls Vonage number (+1-469-414-1700)
2. 🌐 Vonage routes audio via WebSocket to Voice Stream Server
3. 🔀 Voice Stream Server routes to Cartesia AI Agent
4. 👂 Cartesia Ink STT transcribes customer speech
5. 🤖 GROQ LLM (Llama 3.3-70b) processes intent:
• Router Agent classifies intent (Llama 3.1-8b)
• Specialized Agent generates response
• N8N Tools called (slots, booking, etc.)
6. 🗣️ Cartesia Sonic TTS synthesizes response (Blake voice)
7. 🔊 Audio streamed back via WebSocket to customer
8. 📞 Customer hears natural AI voice response
💰 Cost: ~$0.065/minute (Vonage + Cartesia Agent)
💰 Cost Breakdown
Monthly Operating Costs
| Service | Provider | Monthly Cost | Notes |
|---|---|---|---|
| VPS Hosting | Hostinger | ~$5-10 | VPS with Docker support |
| Domain | GoDaddy / Azure DNS | ~$15/yr | optimus.systems (managed in Azure) |
| Phone Number | Vonage | $1.00 | +1-469-414-1700 |
| Vonage Voice/SMS | Vonage | $0.01/min | Telephony routing to Cartesia |
| Cartesia Agent Platform | Cartesia.ai | $0.06/min | Agent hosting fee |
| Cartesia Ink STT | Cartesia.ai | $0.13/hr | Speech-to-Text (~$0.002/min) |
| Cartesia Sonic TTS | Cartesia.ai | Included | Text-to-Speech (in agent fee) |
| GROQ LLM API | GROQ | ~$0.001/call | Llama 3.1/3.3 (generous free tier) |
| Google Maps API | ~$0-10 | Distance calculations | |
| Voice Call Total | ~$0.065/min | Vonage ($0.01) + Cartesia ($0.055) | |
| Est. Monthly (100 min calls) | ~$20-35 | Hosting + Voice + APIs | |
💡 Cost Breakdown Details
- Cartesia Agent Platform - $0.06/min hosting fee for voice agent
- Cartesia Ink STT - $0.13/hour (~$0.002/min) speech-to-text
- Cartesia Sonic TTS - Included in agent platform fee
- Vonage Telephony - $0.01/min for call routing
- GROQ LLM - Free tier (10k tokens/min), then ~$0.001/call
- Total per call minute - ~$0.065 (Vonage + Cartesia combined)
- HomeLab Fallback - KaniTTS/Whisper available at $0/min if needed
💸 Contractor Payout System
Tiered Percentage Model
Contractors earn a percentage of the customer payment, with tier progression based on completed jobs.
| Tier | Jobs Completed | Base Percentage |
|---|---|---|
| 🥉 Bronze | 0-24 | 55% |
| 🥈 Silver | 25-99 | 60% |
| 🥇 Gold | 100-249 | 65% |
| 💎 Platinum | 250+ | 70% |
🎁 Bonus Structure
🚗 Travel Reimbursement
- Rate: $0.67/mile (IRS 2024 rate)
- Minimum distance: 5 miles (no reimbursement under)
- Maximum cap: $50 per job
- Calculation: One-way distance from mechanic home base
⚙️ Configuration Files
Master Configuration
Master configuration file containing all secrets and settings. Never committed to git.
Configuration Flow
.MTMM-variables.json (Master - Private)
│
▼ sync-web-variables.js
│
.MTMM-web-variables.json (Public-safe)
│
▼ deploy.sh --sync-only
│
┌────────┴────────┐
▼ ▼
site-config.json site-config.json
(Main Website) (Team Portal)
Key Configuration Files
| File | Purpose | Location |
|---|---|---|
.MTMM-variables.json |
Master config with secrets | Project root |
.MTMM-N8N-variables.json |
N8N workflow config | Project root |
pricing-database.json |
Services and pricing | Project root |
site-config.json |
Public website config | website-legal/ |
🔐 Environment Variables
Required Environment Variables
| Variable | Service | Description |
|---|---|---|
GOOGLE_MAPS_API_KEY |
Distance/routing calculations | |
GOOGLE_CALENDAR_CLIENT_ID |
Calendar API OAuth | |
VONAGE_API_KEY |
Vonage | SMS and Voice API |
VONAGE_API_SECRET |
Vonage | SMS and Voice API |
STRIPE_SECRET_KEY |
Stripe | Payment processing |
GROQ_API_KEY |
GROQ | LLM inference API |
⚡ N8N Workflows
Active Workflows
Get Available Slots
Returns available appointment slots based on mechanic calendars and dispatch logic.
/webhook/get-available-slots
Create Appointment
Books an appointment, creates calendar event, sends confirmation.
/webhook/create-appointment
Get Appointment
Retrieves appointment details by ID or phone number.
/webhook/get-appointment
Cancel Appointment
Cancels appointment and removes calendar event.
/webhook/cancel-appointment
Config Server
Serves configuration to AI assistant and other services.
/webhook/config-server
MTMM Assistant
Multi-agent AI assistant for voice interactions.
/webhook/mtmm-assistant
🗣️ Voice AI System
Multi-Agent Architecture
The Cartesia AI Agent uses GROQ-powered multi-agent routing with specialized prompts:
Intent Router
Llama 3.1-8bFast intent classification
Scheduling Agent
Llama 3.3-70bAvailability, booking, confirmations
Quote Agent
Llama 3.3-70bPricing, service explanations
Information Agent
Llama 3.3-70bHours, location, services
Issue Agent
Llama 3.3-70bProblem diagnosis, urgency
Cancellation Agent
Llama 3.3-70bCancel/reschedule handling
Voice Processing Pipeline & Costs
| Component | Technology | Provider | Cost |
|---|---|---|---|
| Telephony | Vonage Voice API | Vonage | $0.01/min |
| Speech-to-Text | Cartesia Ink (ink-whisper) | Cartesia.ai | $0.13/hr (~$0.002/min) |
| Text-to-Speech | Cartesia Sonic 3 (Blake voice) | Cartesia.ai | Included in platform |
| Agent Platform | Cartesia AI Agent Hosting | Cartesia.ai | $0.06/min |
| LLM Router | Llama 3.1-8b-instant | GROQ | Free tier / ~$0.0005/call |
| LLM Response | Llama 3.3-70b-versatile | GROQ | Free tier / ~$0.002/call |
| Total Per Minute | ~$0.065 | ||
📅 Google Calendar Integration
Calendar Setup
Each mechanic has their own Google Calendar. Appointments are created as calendar events with full details.
Mechanic Calendar IDs
Calendar Event Structure
{
summary: "🔧 [Service] - [Customer Name]",
description: [
"📞 Phone: +1-xxx-xxx-xxxx",
"🚗 Vehicle: 2018 Toyota Camry",
"🔧 Service: Oil Change",
"💰 Estimate: $75",
"📍 Location: 123 Main St, Dallas TX",
"📋 Notes: Customer notes..."
],
start: { dateTime, timeZone },
end: { dateTime, timeZone },
location: "Customer address"
}
🌐 VPS Hosting Architecture
Infrastructure Details
| Property | Value |
|---|---|
| Provider | Hostinger VPS |
| IP Address | 212.38.95.250 |
| OS | Ubuntu 24.04.3 LTS |
| Domain | optimus.systems |
| Reverse Proxy | Traefik v2.x |
| Web Server | Nginx (Docker) |
Domain Routing
| Domain | Service |
|---|---|
markthemobilemechanic.optimus.systems |
Main website |
markthemobilemechanic.optimus.systems/admin |
Admin portal (this page) |
markthemobilemechanic.optimus.systems/team |
Team/mechanic portal |
n8n.optimus.systems |
N8N workflow automation |
🚀 Deployment Scripts
Deploy Commands
# Full deployment (config sync + file transfer)
cd vps-hosting && ./deploy.sh
# Sync config only (fast update)
./deploy.sh --sync-only
# Deploy N8N workflows
node deploy-n8n-workflows.js
# Deploy specific workflow
node deploy-assistant-workflow.js
Deployment Pipeline
1. 🔄 Run sync-web-variables.js
└─ Generates .MTMM-web-variables.json
2. 📤 rsync to VPS
└─ /opt/websites/sites/markthemobilemechanic.com/
3. 📋 Copy site-config.json
└─ To main site and team portal
4. ✅ Verify deployment
└─ Check file timestamps on VPS
📞 Vonage SMS/Voice
Vonage Configuration
| Setting | Value |
|---|---|
| Phone Number | +1-469-414-1700 |
| Application ID | ab8d48a7-ce50-4cea-a1c0-4499863cb587 |
| Voice Webhooks | Answer URL, Event URL |
| 10DLC Status | Registered |
SMS Templates
- Appointment Confirmation: Sent after booking
- Reminder (24h): Day-before reminder
- Reminder (1h): Hour-before reminder
- Cancellation: Appointment cancelled confirmation
🔔 Customer Notifications
Notification Flow
⭐ Rating SMS Workflow
Post-Service Rating Flow
Rating SMS Template
Thanks for choosing Mark The Mobile Mechanic! 🔧
Your [SERVICE] is complete.
Total: $[AMOUNT]
⭐ Rate your experience:
[RATING_LINK]
Questions? Reply to this message or call +1-469-414-1700
Workflow Triggers
| Trigger Method | Source | Action |
|---|---|---|
| 📲 Team Portal Button | Mechanic clicks "Mark Complete" | POST to /webhook/mtmm-complete-job |
| 💬 SMS Keyword | Mechanic texts "DONE" or "COMPLETE" | Vonage webhook triggers N8N |
| 📅 Calendar Update | Event status changed to complete | Calendar webhook triggers N8N |
Rating Response Handling
Rating Link Structure
https://markthemobilemechanic.optimus.systems/rate?
job=[JOB_ID]
&token=[SECURE_TOKEN]
&mechanic=[MECHANIC_ID]
Example:
https://markthemobilemechanic.optimus.systems/rate?job=apt_123abc&token=xyz789&mechanic=m_barry
🌐 Web Scheduling Workflow
Booking Flow Architecture
API Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/webhook/mtmm-check-available-slots |
POST | Get available time slots for a date |
/webhook/mtmm-create-appointment |
POST | Create new appointment booking |
/webhook/mtmm-cancel-appointment |
POST | Cancel existing appointment |
/webhook/mtmm-reschedule-appointment |
POST | Reschedule to new date/time |
Create Appointment Payload
{
"customerName": "John Smith",
"customerPhone": "+1-555-123-4567",
"customerEmail": "john@example.com",
"vehicleYear": "2020",
"vehicleMake": "Toyota",
"vehicleModel": "Camry",
"vin": "1HGBH41JXMN109186",
"serviceAddress": "123 Main St, Dallas, TX 75201",
"serviceId": "oil_change_standard",
"requestedDate": "2025-01-15",
"requestedTime": "10:00",
"notes": "Gate code: 1234"
}
Slot Calculation Logic
📊 SLOT AVAILABILITY CALCULATION
Business Hours: 8:00 AM - 6:00 PM (configurable)
Slot Duration: Based on service labor hours
For each mechanic:
1. Fetch Google Calendar events for date
2. Generate all possible slots in business hours
3. Remove slots that overlap with:
- Existing appointments
- Buffer time (15 min before/after)
- Blocked time (lunch, breaks)
4. Apply dispatch constraints:
- Service radius from customer location
- Mechanic skills match service requirements
- Mechanic active status
5. Return merged available slots across all mechanics
💬 SMS Scenarios
SMS Workflow Architecture
Customer SMS Scenarios
| Trigger | Template | Timing |
|---|---|---|
| 📅 Appointment Created | "Your appointment with Mark The Mobile Mechanic is confirmed for [DATE] at [TIME]. Reply HELP for assistance." | Immediate |
| ⏰ 24-Hour Reminder | "Reminder: Your mechanic will arrive tomorrow [DATE] at [TIME]. [MECHANIC] will service your [VEHICLE]. Reply CANCEL to cancel." | 24h before |
| ⏰ 1-Hour Reminder | "[MECHANIC] will arrive in about 1 hour for your [SERVICE]. Make sure your vehicle is accessible." | 1h before |
| 🚗 Mechanic En Route | "[MECHANIC] is on the way! ETA: [MINUTES] minutes. Track: [LINK]" | Dispatch |
| ⏱️ Running Late | "Update: [MECHANIC] is running about [DELAY] minutes late. New ETA: [TIME]. We apologize for the inconvenience." | If delayed |
| ✅ Service Complete | "Your service is complete! Total: $[AMOUNT]. Rate your experience: [LINK]" | On completion |
| ❌ Cancellation | "Your appointment for [DATE] has been cancelled. Questions? Call +1-469-414-1700" | On cancel |
Mechanic SMS Scenarios
| Trigger | Template |
|---|---|
| 🆕 New Assignment | "NEW JOB: [SERVICE] for [CUSTOMER] at [TIME]. Location: [ADDRESS]. Vehicle: [YEAR] [MAKE] [MODEL]. Reply OK to confirm." |
| ⚠️ Reassignment | "Job reassigned: [SERVICE] at [ADDRESS] moved to [NEW_MECHANIC]. Original time: [TIME]." |
| ❌ Job Cancelled | "CANCELLED: [SERVICE] at [TIME] for [CUSTOMER] has been cancelled by customer." |
| 🔔 Daily Summary | "Tomorrow's schedule: [COUNT] jobs. First: [TIME] at [ADDRESS]. Check Team Portal for details." |
Inbound Reply Handling
📥 CUSTOMER REPLY KEYWORDS
"CONFIRM" / "YES" / "OK"
└─ Mark appointment as confirmed
└─ Reply: "Thank you! Your appointment is confirmed."
"CANCEL" / "STOP"
└─ Initiate cancellation workflow
└─ Reply: "Your appointment has been cancelled."
"RESCHEDULE" / "CHANGE"
└─ Send booking link
└─ Reply: "To reschedule, visit: [BOOKING_LINK]"
"HELP" / "?"
└─ Reply: "Call us at +1-469-414-1700 or visit markthemobilemechanic.com"
"RUNNING LATE"
└─ Log delay notification
└─ Forward to assigned mechanic
📥 MECHANIC REPLY KEYWORDS
"OK" / "CONFIRMED"
└─ Mark job as acknowledged
"EN ROUTE" / "OTW"
└─ Trigger customer "mechanic en route" SMS
└─ Update job status to "in_transit"
"ARRIVED"
└─ Update job status to "in_progress"
"DONE" / "COMPLETE"
└─ Trigger completion workflow
🎯 Mechanic Dispatch System
Intelligent Dispatch Architecture
Dispatch Strategies
| Strategy | Distance | Workload | Skills | Best For |
|---|---|---|---|---|
hybrid_intelligent ⭐ |
40% | 35% | 25% | Default - balanced optimization |
geographic_optimized |
70% | 15% | 15% | Large service areas, fuel savings |
workload_balanced |
20% | 60% | 20% | Fair distribution, team morale |
skill_based |
15% | 20% | 65% | Specialized services |
round_robin |
- | - | - | Simple rotation, testing |
GPS Position Detection
🗺️ POSITION DETECTION ALGORITHM
┌─────────────────────────────────────────────────────────────────┐
│ For accurate distance calculations, the system determines │
│ where each mechanic will be at the requested appointment time │
└─────────────────────────────────────────────────────────────────┘
Priority 1: CURRENT APPOINTMENT LOCATION
├── Check: Is mechanic at a job during/before requested time?
├── Use: That job's service address
└── Why: Most accurate for same-day scheduling
Priority 2: PREVIOUS APPOINTMENT LOCATION
├── Check: Most recent completed appointment
├── Use: That job's service address
└── Why: Mechanic may still be in that area
Priority 3: BASE LOCATION (fallback)
├── Use: Mechanic's configured home/shop address
└── Why: Default starting point for new days
📊 EXAMPLE SCENARIO
────────────────────
Request: 2:00 PM appointment in Plano
Mechanic A:
└─ Has 11:00 AM job in Frisco (15 min away)
└─ Position used: Frisco address ✓
Mechanic B:
└─ No appointments today
└─ Position used: Base location (Haslet) ✓
Route Clustering Optimization
🎯 ROUTE CLUSTERING BONUS
When appointments are geographically clustered, mechanics receive
bonus points to encourage efficient routing:
┌─────────────────────────────────────────────────────────────────┐
│ Distance to Next Job │ Clustering Bonus Points │
├─────────────────────────────────────────────────────────────────┤
│ < 5 miles │ +20 points │
│ 5-10 miles │ +15 points │
│ 10-15 miles │ +10 points │
│ 15-20 miles │ +5 points │
│ > 20 miles │ No bonus │
└─────────────────────────────────────────────────────────────────┘
📈 REAL-WORLD IMPACT
────────────────────
Before clustering optimization:
└─ Average deadhead miles: 45 miles/day
After clustering optimization:
└─ Average deadhead miles: 28 miles/day
└─ 🎉 38% reduction in non-billable driving!
💡 EXAMPLE CALCULATION
────────────────────────
Scenario: 2:00 PM oil change in Plano
Mechanic A (in Frisco):
Base Score: 75
Distance: 8 miles
Cluster Bonus: +15 (within 10 miles of their next job)
FINAL: 90 ✅ SELECTED
Mechanic B (in Fort Worth):
Base Score: 82
Distance: 32 miles
Cluster Bonus: +0
FINAL: 82
Scoring Formula
// Hybrid Intelligent Strategy (default)
function calculateScore(mechanic, appointment) {
const weights = {
distance: 0.40,
workload: 0.35,
skills: 0.25
};
// Distance Score (0-100, closer = higher)
const distanceScore = Math.max(0, 100 - (distance * 2));
// Workload Score (0-100, fewer jobs = higher)
const maxJobs = 8; // Daily capacity
const workloadScore = ((maxJobs - todayJobs) / maxJobs) * 100;
// Skills Score (0-100)
const skillsScore = mechanic.skills.includes(service.category)
? 100 : 60; // Penalty for non-specialist
// Efficiency Multiplier
const efficiencyMultiplier = mechanic.efficiency || 1.0;
// Route Clustering Bonus
const clusterBonus = calculateClusterBonus(mechanic, appointment);
// Final Score
const baseScore = (
(distanceScore * weights.distance) +
(workloadScore * weights.workload) +
(skillsScore * weights.skills)
) * efficiencyMultiplier;
return baseScore + clusterBonus;
}
Mechanic Attributes
| Attribute | Type | Impact |
|---|---|---|
skills[] |
Array | Categories mechanic specializes in (brakes, electrical, etc.) |
efficiency |
Float (0.5-1.5) | Multiplier applied to final score. Higher = more preferred. |
serviceRadius |
Number (miles) | Max distance willing to travel. Jobs outside = ineligible. |
baseLocation |
Address | Home/shop address for distance calculation fallback. |
weight |
Number (1-10) | Priority weight for round-robin and tie-breaking. |
isActive |
Boolean | Must be true to receive assignments. |