MORBOSOS — Plataforma PPV Multi-Marca con cola global de mensajes
Un único backend Laravel que opera N marcas white-label (cada una con su dominio, logo, precios y catálogo de perfiles). Los usuarios pagan por mensaje enviado a "modelos" que en realidad son perfiles ficticios atendidos por una plantilla rotativa de operadores de chat a través de una cola FIFO global. El operador nunca elige perfil: el sistema le entrega el próximo mensaje pendiente y le da contexto (historial + guión).
Qué construimos exactamente
- Web por dominio (
marca1.com,marca2.com, etc.) con look propio. - Catálogo de perfiles "reales": foto, edad, ciudad, bio, intereses.
- Chat 1:1 con costo por mensaje visible antes de enviar.
- Compra de packs de créditos (más barato a mayor volumen).
- Push / email cuando "ella" responde.
- Pool de operadores anónimos atendiendo desde cualquier país.
- Cola FIFO global: el operador no elige, recibe el siguiente.
- Throughput máximo: al enviar respuesta cae el siguiente mensaje al instante, sin esperas.
- Notas por perfil-cliente: cualquier operador retoma con contexto sin necesitar locks.
- Sistema de reclutamiento + onboarding + tiers de pago por volumen.
Por qué este negocio funciona
El cliente paga entre €0,90 y €2,00 por mensaje. El operador cobra entre €0,08 y €0,20. La plataforma se queda con el resto: ~85–90% del bruto.
Los operadores responden con la mitad de extensión + pregunta abierta. El usuario nunca cierra el loop. Patrón gamificado validado por Chatwriters, Cloudworkers, Texting Factory.
No hay modelos que pagar, ni horarios fijos, ni dramas humanos. Los perfiles son ficticios. Operadores intercambiables y escalables 24/7 por zonas horarias.
El secreto técnico: la cola global
El cambio de paradigma que pediste en la conversación es el activo más importante del producto: a diferencia de OnlyFans/Fansly (1 creadora ↔ N fans, vínculo fuerte), aquí un mismo perfil ficticio es atendido por cualquier operador disponible. Eso significa:
- El operador nunca está ocioso (envía respuesta → cae el siguiente mensaje, del perfil que sea).
- Ninguna conversación queda parada por horario, vacaciones o cambio de turno.
- El "talento" es fungible: no dependes de ninguna persona específica.
SkaDate lo llama "Unassigned Chats". Cloudworkers/Texting Factory operan así internamente. Nosotros lo construimos como primitivo del sistema, no como add-on.
Diferenciador frente a la competencia
| Atributo | SkaDate | Cloudworkers/Texting Factory | OnlyFans / Fansly | MORBOSOS |
|---|---|---|---|---|
| Multi-marca white-label nativa | Add-on | No | No | Núcleo |
| Cola FIFO global como primitivo | Sí, secundaria | Sí (interna) | No aplica | Sí, primaria |
| Perfiles ficticios + notas por perfil | Sí | Sí | No | Sí, multi-operador |
| Pago por mensaje (PPV puro) | Sí | Sí | PPV opcional | Núcleo |
| Marketplace de operadores integrado | No | Sí, pero sin tu marca | No | Sí, dentro |
| Comisión configurable por marca | Limitada | No aplica | No | Sí |
Investigación de mercado — quién hace esto hoy
No estás inventando una categoría: estás replicando un modelo probado y madurando hace 10 años, pero integrando piezas que hoy están dispersas. Estos son los actores reales:
Mapa de competidores
Detalle por competidor
SkaDate / SimChat Console competencia técnica directa
Qué es: el software white-label más maduro para sitios de citas, con un módulo llamado SimChat Console donde los operadores atienden perfiles ficticios.
Cómo opera:
- Pool de "virtuals" (perfiles ficticios) gestionables desde el admin (incluye importación CSV).
- Cola de "Unassigned Chats": el operador toma el siguiente disponible.
- Triggers automáticos: mensaje cuando el usuario se registra, hace login, visita un perfil.
- Auto-archivo de chats inactivos > 6 horas.
- Integración con ChatGPT para responder cuando no hay operadores online.
- Estadísticas por agente y por virtual.
Dónde falla para nuestro caso: es single-tenant por instalación (cada cliente paga su instancia/licencia y monta su propia marca). No tiene operación multi-marca centralizada. Y el reclutamiento de operadores corre por cuenta del cliente.
Chatwriters · Cloudworkers · Texting Factory · Remotely4u competencia laboral
Estos no compiten contigo en producto, compiten contigo en captar mano de obra. Son marketplaces que reclutan operadores y los venden como servicio a sites de citas/adulto. Datos clave:
- Chatwriters: US-only, requiere ≥ 200 mensajes/semana. Pago €0,09–€0,12/msg en tiers. Onboarding con temario propio (reglas de estilo: responder con la mitad de extensión, siempre con pregunta).
- Cloudworkers: global, fundada 2015. Hiring promedio 7 días. Onboarding 1 hora por Skype/teléfono. Multi-idioma. Team leaders por idioma.
- Texting Factory: "fantasy chat" — explícito en que el usuario habla con personajes ficticios; jurídicamente más limpio.
Lección para nosotros: tenemos que construir nuestro propio embudo de captación con un onboarding más corto, payout más rápido (semanal) y una UI de chat mejor que la de ellos. Es la parte que mencionaste que faltaba.
AdultFriendFinder referencia B2C
Modelo: freemium + premium ($19,95–$39,95/mes) + créditos para regalos virtuales y unlock de fotos/videos.
Lo gris: mezcla perfiles reales con bots y chat hosts. No verifica género ni ubicación. Múltiples reseñas hablan de "miles de empleados fingiendo interés".
Lección: el usuario final tolera alta sospecha de fake con tal de tener interacción. Pero hace falta una capa de "verisimilitud": perfiles con datos consistentes, fotos no-stock, notas por conversación. Nuestro stack lo cubre nativamente.
Meete / toChat (y similares en España/LatAm) referencia regional
Sitios de citas pequeños operados desde España con perfiles ficticios. Cobran €1–€2 por mensaje. Han salido en reportajes (Xataka, Vice) explicando el modelo: contratan estudiantes/desempleados, los entrenan 1–2 días, y los ponen a operar 4–8 horas/día.
Lección: hay demanda comprobada en España y LatAm. La oportunidad real es regionalizar: crear marcas específicas por país/idioma con fotos y nombres locales (no usar los mismos perfiles en marcas distintas — riesgo de cross-detection).
Fuentes consultadas
Arquitectura técnica
Una sola API Laravel sirve a N frontends. Cada frontend resuelve su marca por dominio. Toda la lógica (cola, mensajes, pagos, retiros) vive en el backend.
Stack propuesto
| Capa | Tecnología | Por qué |
|---|---|---|
| API / Backend | Laravel 11 + PHP 8.3 | Tu stack actual (MangoX). Sanctum/JWT, queues nativas, Reverb para WS. |
| BD principal | MySQL 8 | Multi-tenant por brand_id en cada tabla. Suficiente hasta ~100M de filas. |
| Cola/Cache | Redis 7 | Dos colas FIFO (mensajes + operadores) emparejadas por dispatcher, rate limits, sesiones. |
| Jobs async | Laravel Horizon (Redis) | Procesar pagos, webhooks, notificaciones, archivado de chats. |
| WebSockets | Laravel Reverb | Push de mensajes al cliente y al operador en tiempo real. |
| Frontends públicos | Next.js 15 (App Router) | SSR + ISR por marca, SEO importante para captación orgánica. |
| Panel operador / admin | Inertia + React o React SPA | App rica, atajos de teclado, multi-tab. No necesita SEO. |
| Pagos | Stripe (intl) + MercadoPago (LatAm) + cripto (Coinbase Commerce) + Zelle manual | Cobertura geográfica y mitigación de bloqueos (el sector adulto sufre cierres de Stripe). |
| Storage media | Backblaze B2 + CloudFlare R2 + CDN | Más barato que S3, sin políticas anti-adulto de AWS. |
| Notificaciones | Firebase (push) + Resend/Postmark (email) + Twilio (SMS opcional) | Push para retención. |
| Observabilidad | Sentry + Grafana + Logtail | Errores, métricas de cola, latencias. |
Diagrama de arquitectura (alto nivel)
Detección de marca por dominio
Cada request entrante incluye el Host header. Un middleware lo resuelve contra la tabla brands y deja la marca en el contenedor:
// app/Http/Middleware/ResolveBrand.php
public function handle($request, $next) {
$host = $request->getHost();
$brand = Brand::query()
->where('domain', $host)
->orWhere('domain', 'LIKE', '%.'.$host)
->firstOrFail();
app()->instance('current.brand', $brand);
Config::set('brand.id', $brand->id);
return $next($request);
}
Toda query a perfiles, precios, mensajes, etc. arranca con ->where('brand_id', $brand->id) vía global scope Eloquent. Imposible filtrar mal y cruzar datos entre marcas.
Los 12 módulos del sistema
CRUD de marcas, dominios, logos, paleta, comisión, fee de suscripción.
Registro, OTP por email/SMS, Sanctum, scopes por rol, refresh tokens.
Fotos, bio, edad, ciudad, precio por mensaje, intereses, idiomas, estado.
Cola A (mensajes) + Cola B (operadores). Dispatcher empareja 1×1 vía BLPOP. Reasignación por timeout.
Reverb, eventos in/out, badges, sonido, historial paginado.
Cuaderno colaborativo: cualquier operador retoma con contexto.
Cada perfil tiene un guión base (tono, info, preferencias) que el operador ve siempre.
Recarga, descuento por mensaje, precio congelado al comprar pack, historial.
Tier de pago al operador, comisión a marca, retiros quincenales, payout multi-método.
Ingresos, perfiles top, operadores top, conversión, churn, fraude.
Landing, formulario, test de copy, entrenamiento, certificación.
Reportes, ban, logs de cada acción, detección de patrones sospechosos.
El corazón del sistema: dos colas que se emparejan
El sistema mantiene dos colas FIFO que se alivian entre sí: una de mensajes pendientes y otra de operadores disponibles. Un dispatcher toma uno de cada lado en cada turno y los empareja. Es la lógica de un despacho de taxis: cuando hay pasajero y hay taxi, sale el viaje. Cuando un operador responde, vuelve al final de la cola de operadores y espera el próximo match (que llega al instante si hay mensajes esperando).
Modelo de dos colas + dispatcher
Por qué dos colas y no una
Los operadores son atendidos en orden de llegada: el primero que se conectó es el primero que recibe mensaje. Nadie acapara, nadie queda olvidado.
Cuando hay oferta y demanda, el match es instantáneo. Cuando una cola se vacía, la otra simplemente espera (sin lookups raros, sin polling).
El admin ve en vivo: "Cola A: 142 mensajes esperando, Cola B: 8 operadores libres" → falta plantilla. O al revés: "operadores ociosos, falta tráfico de clientes".
Ciclo de vida del operador (la cola B)
- El operador se conecta al panel → entra al final de
queue:ops:es. - Espera (la espera es bloqueante en Redis con
BLPOP: cuesta cero, no consume CPU). - El dispatcher lo empareja con un mensaje → el match aparece en su pantalla.
- Responde y envía. En ese instante, el operador vuelve al final de
queue:ops:es. - Si hay mensajes pendientes en Cola A, el siguiente match es inmediato. Si no, espera.
Reglas duras del sistema
No reservamos perfiles para nadie. Cualquier operador puede atender cualquier perfil. La coherencia se mantiene con guión visible + notas obligatorias + historial completo, no con bloqueos. Esto maximiza el throughput.
Cada par de colas se separa por idioma (y opcionalmente por marca si una marca quiere su pool exclusivo): queue:msgs:es ↔ queue:ops:es, queue:msgs:en ↔ queue:ops:en. Un operador trilingüe se inscribe en N parejas.
Mensaje en Cola A > 4 horas sin match → se marca como stale y se reembolsa al cliente (mejora confianza). Configurable por marca.
Si después del match el operador no envía respuesta en 2 minutos → el mensaje vuelve a Cola A con prioridad alta, el operador es removido de Cola B (necesita reactivarse). Si lo repite > X veces/día, baja su tier.
Variante: Cola B no es FIFO pura sino "sorted set" por tier. Los operadores oro se matchean antes que los bronce. Premia productividad. Activable por marca.
Cliente premium suscrito → su mensaje entra al frente de Cola A. Beneficio comercial real: "tu mensaje siempre llega primero a un operador".
Reglas duras de la cola
Cuando un operador envía una respuesta, el sistema le entrega el siguiente mensaje disponible al instante. No reservamos perfiles. No esperamos 30 segundos por si llega otro del mismo perfil. La regla es simple: respondió → ya tiene otro.
El operador nunca está ocioso. La productividad se maximiza. La coherencia se mantiene con guión + notas + historial siempre visibles, no con locks.
No existe UNA cola, existen N: queue:msg:es, queue:msg:en, queue:msg:brand_42 (si una marca quiere su propio pool). El operador declara qué colas atiende y solo consume de las que matchean.
Mensaje en cola > 4 horas sin respuesta → se marca como stale y se reembolsa al cliente (mejora confianza). Configurable por marca.
Operador toma mensaje pero no responde en 2 minutos → el sistema lo devuelve a la cola con prioridad alta. Si el operador hace esto > X veces/día, baja su tier de pago.
Estados de un mensaje
stale y archived son terminales.Pseudocódigo del dispatcher
Un proceso por idioma (Laravel command supervisado) se queda esperando que las dos colas tengan al menos un elemento cada una. Cuando ocurre, hace el match y vuelve a esperar.
// php artisan dispatcher:run --lang=es
// Un proceso por idioma · ligero · bloqueante en Redis
while (true) {
// BLPOP bloquea hasta que haya un mensaje. Cuesta 0 CPU.
[$_, $msgId] = Redis::blpop(["queue:msgs:{$lang}"], 0);
// Ahora necesitamos un operador libre. Tomamos del principio (FIFO).
[$_, $opId] = Redis::blpop(["queue:ops:{$lang}"], 0);
// Match → asignar
$msg = ClientMessage::find($msgId);
$msg->update([
'status' => 'assigned',
'assigned_op_id' => $opId,
'assigned_at' => now(),
]);
// Empuja el mensaje al panel del operador vía WebSocket
broadcast(new MessageAssigned($msg, $opId))->toOthers();
// Watchdog: si en 2 min no responde, devolvemos el mensaje a Cola A
// y removemos al operador de Cola B
dispatch(new MatchTimeoutCheck($msg->id, $opId))->delay(now()->addMinutes(2));
}
Cuando el operador envía la respuesta:
// POST /api/operator/messages/{id}/reply
public function reply(Request $r, $msgId) {
$op = auth()->user();
$msg = ClientMessage::findOrFail($msgId);
// Validar reglas (longitud, pregunta, anti-fuga)
$this->validateReply($r->body, $msg->body);
// Guardar respuesta + acreditar comisión
OperatorReply::create([...]);
Wallet::credit($op->id, $op->tier->per_message_pay);
// **Clave**: devolver al operador a la cola B al final
Redis::rpush("queue:ops:{$op->lang}", $op->id);
// Push al cliente
broadcast(new ClientReplied($msg, $r->body));
return ['ok' => true];
}
Conexión y desconexión del operador:
// Operador abre el panel
public function goOnline() {
Redis::rpush("queue:ops:{$op->lang}", $op->id);
}
// Operador cierra panel · timeout · idle
public function goOffline() {
Redis::lrem("queue:ops:{$op->lang}", 0, $op->id);
}
Modelo económico
Cada mensaje es una transacción con tres partes: el cliente paga, el operador cobra, la plataforma se queda con el spread (menos la comisión que pasa a la marca si la marca no es tuya).
Precios al cliente — packs de créditos
Replicamos la curva de precios validada por el mercado (Chatwriters / Meete / toChat). El cliente nunca compra mensajes sueltos: siempre packs, con descuento creciente.
| Pack | Mensajes | Precio total | Coste por msg | Descuento |
|---|---|---|---|---|
| Trial | 3 | €6,00 | €2,00 | — |
| Pequeño | 10 | €18,00 | €1,80 | 10% |
| Medio | 15 | €25,00 | €1,67 | 17% |
| Estándar | 20 | €30,00 | €1,50 | 25% |
| Plus | 63 | €90,00 | €1,43 | 29% |
| VIP | 120 | €135,00 | €1,13 | 44% |
| Whale | 240 | €210,00 | €0,88 | 56% |
Precio congelado al comprar pack
Si subes el precio mañana, los packs comprados hoy se gastan al precio antiguo. Implementación: el pack guardaprice_per_msg_at_purchase y cada mensaje deduce de ahí.
Pago al operador — tiers por volumen semanal
Replicamos el patrón "más mensajes = mejor tarifa" que usa Chatwriters y otros (gamifica la productividad y reduce rotación).
| Tier | Mensajes/semana | Pago por msg | Pago semanal típico |
|---|---|---|---|
| Bronce | 0 – 375 | €0,09 | hasta €33,75 |
| Plata | 376 – 775 | €0,10 | €37,60 – €77,50 |
| Oro | 776 – 1.975 | €0,11 | €85,36 – €217,25 |
| Platino | > 1.975 | €0,12 | €237 – €500+ |
Mínimo obligatorio para mantenerse activo: 200 msg/semana. Si baja 2 semanas seguidas → pausa automática del operador (libera slot para reclutar).
Calculadora interactiva
Otras fuentes de ingreso (multi-revenue)
€9,99–€29,99/mes. Beneficios: descuento permanente 10% en packs, badge VIP, acceso a fotos bloqueadas, prioridad en cola (su mensaje cae primero a operadores).
El operador desde el chat puede mandar "una foto que cuesta €5". El cliente paga para verla. Reparto 70/30. Implementación: tabla media_unlocks.
Iconos de regalo (rosa €0,50, oso €2, anillo €10). Microtransacción típica que sube ARPU. La "modelo" agradece en pantalla. Reparto 80/20.
Si vendes el software como white-label a un tercero, le cobras 15–25% de su revenue (modelo SaaS). Suma marketplace + plataforma.
Roles y pantallas
Cuatro roles. Cada uno ve un producto distinto. La calidad de la operación depende de la calidad de la UI del operador (es donde se gana o se pierde productividad).
🟦 Cliente final
El "usuario" que paga.
Pantallas:- Landing de marca con CTA "regístrate y empieza a hablar".
- Registro express (email + edad + ciudad + foto opcional).
- Catálogo de perfiles: cards con foto, edad, ciudad, "online ahora".
- Perfil del modelo: galería + bio + precio/msg + botón "Enviar mensaje".
- Chat 1:1: cada mensaje muestra costo antes de enviar + saldo restante.
- Comprar pack (modal + pasarela de pago).
- Historial de transacciones.
- Notificaciones (push, email, in-app).
- Configuración: privacidad, cerrar cuenta, soporte.
- "Te quedan X mensajes" (no euros — reduce fricción).
- "Sofía suele responder en 2 minutos" (anclaje de expectativa).
- Confirmación obligatoria primera vez que envía: "Este mensaje cuesta 1 crédito" + checkbox "no mostrar de nuevo".
🟩 Operador (chat writer)
El humano que escribe por los perfiles ficticios.
Pantallas:- Dashboard: mensajes hoy / semana / mes, tier actual, ganancias, ranking.
- Chat principal: el sistema le entrega el siguiente. No elige. Layout 3 columnas:
- Izquierda: identidad del perfil (foto, nombre, edad, ciudad, guión).
- Centro: historial completo + caja de respuesta.
- Derecha: notas del perfil-cliente + datos del cliente (ciudad, intereses).
- Atajos de teclado: Ctrl+Enter enviar, Tab cambiar perfil, F2 ver guión, F3 ver notas, Ctrl+S guardar nota rápida.
- Respuestas rápidas: snippets predefinidos por perfil ("hola, ¿qué tal tu día?").
- Histórico de conversaciones: búsqueda por cliente, fecha, perfil.
- Wallet: ganancias, payouts, solicitar retiro.
- Formación: cursos cortos, test de estilo, actualizaciones del temario.
- Validación: respuesta no puede ser < 30% ni > 80% del largo del mensaje del cliente.
- Validación: respuesta debe terminar con
?(pregunta) — warning si no, no bloqueo. - Anti-fuga: detecta números de teléfono, links externos, palabras prohibidas — los reemplaza o bloquea.
- Sonido + flash de tab cuando entra nuevo mensaje.
🟨 Brand Admin
Dueño de UNA marca (puede ser tú, puede ser un cliente tuyo si lo vendes white-label).
Pantallas:- Dashboard ejecutivo: ingresos, clientes activos, mensajes enviados, top perfiles, top operadores, conversión registro→primera compra.
- CRUD de perfiles: subir foto, escribir bio, definir personalidad, precio/msg, idiomas, intereses.
- Operadores asignados: cuáles atienden esta marca, productividad, calidad.
- Precios y packs: ajustar packs específicos de la marca.
- Reportes: ingresos diarios/mensuales, exportar CSV, drill-down por perfil/operador.
- Moderación: ban de clientes, reportes de operadores, auditoría.
- Personalización: logo, colores, dominio, textos legales, política de reembolso.
🟥 Super Admin (tú)
Vista global del negocio. Tu cabina de mando.
Pantallas:- Dashboard global: revenue total, por marca, por país, por perfil, por hora del día.
- Gestión de marcas: crear, suspender, configurar comisiones, asignar admins.
- Gestión de operadores (pool global): aprobar, suspender, ajustar tier, revisar disputas.
- Cola en vivo: latencia, mensajes pendientes, operadores online por idioma, alertas.
- Tesorería: balance por método de pago, payouts pendientes, comisiones cobradas, conciliación.
- Auditoría: logs de cada acción crítica (login admin, cambio de precio, ban, payout aprobado).
- Anti-fraude: alertas (cliente que recarga mucho y reclama, operador que toma y suelta, pago disputado).
- Configuración global: feature flags, integraciones, secrets.
Esqueleto visual del chat del operador
Captación + onboarding de operadores
Esta es la parte que mencionaste que faltaba en la conversación. Es estratégica: sin operadores no hay producto. Y los marketplaces actuales (Cloudworkers, Chatwriters) ya están compitiendo por la misma mano de obra.
Pipeline de captación
Detalle de cada etapa
Etapa 1–2 · Tráfico y landing
Campañas en Facebook, Instagram, TikTok dirigidas a: mujeres 18–40, estudiantes, desempleados, madres en casa, latinoamericanos con buen español. Mensaje clave: "trabaja desde casa chateando · €200–€500/semana · sin jefe". Landing con calculadora de ingresos potencial + testimonios + FAQ.
Etapa 3 · Formulario inicial
Datos: nombre, email, país, idiomas dominados (autoevaluación con escala), edad (verifica 18+), horario disponible, experiencia previa. Sin foto, sin DNI en esta etapa (reducir fricción).
Etapa 4 · Test de copywriting (autoevaluación automática)
Sistema le muestra 3 conversaciones simuladas y le pide responder. Algoritmo evalúa:
- Longitud (regla del 30–80% del cliente).
- Termina con pregunta (regex).
- Sin contradicciones obvias con el guión dado.
- Sin info personal del operador.
- Sin links externos / teléfonos.
Score >= 70/100 pasa a revisión humana.
Etapa 5 · Revisión humana (team leader)
Un team leader (rol nuevo) revisa el test y decide aprobar/rechazar. SLA: 24h. Si rechaza, da feedback estandarizado por categorías. Si aprueba, le manda invitación al curso.
Etapa 6 · Curso de 1 hora (asíncrono)
Video corto (15 min) + temario PDF + 5 casos prácticos. Cubre: reglas de longitud, técnica de "siempre pregunta", anti-fuga, manejo de objeciones, qué decir cuando el cliente quiere conocerla en persona, qué hacer si pregunta por cosas sensibles.
Etapa 7 · Examen final
15 preguntas mezcla teoría + práctica. Aprueba con 12/15. Si reprueba, puede repetir 2 veces más con 24h entre intentos.
Etapa 8 · Periodo de prueba (1 semana)
Operador activo pero con flag probation = true. Cada mensaje que envía pasa por una segunda revisión (team leader o sistema con LLM). Si comete < 5 errores en 100 msgs, queda firme.
Etapa 9 · Operativo · Tier Bronce
Empieza a producir. Vista de wallet visible. Primer payout disponible al cumplir el mínimo (€50 acumulado).
Etapa 10 · Retención y crecimiento
Bonus por antigüedad (€20/mes después de 6 meses), bonus por referidos (€30 por cada operador que él trae y aprueba el periodo de prueba), gamificación (badges, leaderboards opcionales), capacitaciones nuevas para subir tier.
Métricas que vigilas como Super Admin
Modelo de datos y API
Schema MySQL simplificado + endpoints REST principales. Todo es multi-tenant por brand_id.
Diagrama ER (simplificado)
Endpoints API críticos
| Método | Endpoint | Quién | Qué hace |
|---|---|---|---|
| POST | /api/auth/register | Público | Registro cliente · marca por dominio |
| POST | /api/auth/login | Público | Login con email/OTP · devuelve token |
| GET | /api/profiles | Cliente | Lista perfiles públicos de su marca · paginado · filtros |
| GET | /api/profiles/{id} | Cliente | Detalle perfil + fotos + precio |
| POST | /api/conversations/{id}/messages | Cliente | Envía msg · valida saldo · descuenta · LPUSH cola |
| GET | /api/conversations | Cliente | Sus conversaciones · paginado |
| GET | /api/packs | Cliente | Packs disponibles de su marca |
| POST | /api/purchases | Cliente | Inicia compra · devuelve URL de pasarela |
| POST | /api/webhooks/stripe | Stripe | Webhook · acredita pack · 3 reintentos · idempotente |
| GET | /api/operator/next-message | Operador | Recibe el siguiente match · push vía WebSocket |
| POST | /api/operator/messages/{id}/reply | Operador | Envía respuesta · valida reglas · acredita comisión |
| POST | /api/operator/conversations/{id}/notes | Operador | Agrega nota al cuaderno |
| POST | /api/operator/withdraw | Operador | Solicita retiro · valida mínimo |
| GET | /api/brand/dashboard | Brand admin | KPIs de la marca |
| CRUD | /api/brand/profiles | Brand admin | Gestiona sus perfiles ficticios |
| GET | /api/super/dashboard | Super admin | Vista global multi-marca |
| POST | /api/super/brands | Super admin | Crea nueva marca + dominio |
| GET | /api/super/queue/stats | Super admin | Estado en vivo de las colas Redis |
Eventos WebSocket (Reverb)
| Canal | Evento | Quién escucha |
|---|---|---|
private-conversation.{id} | message.received | Cliente y operador asignado |
private-operator.{id} | queue.next | Operador (le cae msg nuevo) |
private-operator.{id} | balance.updated | Operador (cambió wallet) |
private-client.{id} | balance.updated | Cliente (descontó msg) |
private-brand.{id} | dashboard.tick | Brand admin (KPIs en vivo) |
private-super | queue.health | Super admin (alertas) |
Roadmap de ejecución
MVP en 8 semanas con 1 marca y 1 idioma. Después escalamos. No intentes lanzar 3 marcas a la vez: vas a quemar foco.
Fase 0 · Pre-trabajo (1 semana antes del MVP)
- Comprar 2–3 dominios buenos (idealmente
.comen idiomas distintos). - Hosting separado para producción (VPS con buena CPU y red — Hetzner CCX23 o similar).
- Dar de alta cuentas: Stripe (cuesta), MercadoPago, Backblaze, Firebase, Sentry, dominio TLS.
- Bolsa inicial de fotos: comprar set de ~50 fotos coherentes (mismo "modelo") en stocks que no sean tan obvios (no Pexels). Alternativa: generación con Flux/SDXL — coherencia con LoRA.
- Plantilla de guiones de personalidad x 10 perfiles ficticios (CSV listo).
MVP · 8 semanas (sprints de 1 semana)
Semana 1 · Fundaciones
Repo Laravel 11. Auth Sanctum. Tabla brands + middleware de detección. CRUD básico de users con roles. Seeders. Tests base.
Semana 2 · Perfiles + frontend público
CRUD profiles (con upload a B2). Endpoint público /api/profiles. Frontend Next.js con landing, listado, detalle. SEO básico.
Semana 3 · Chat + cola Redis
Tabla conversations + client_messages. Endpoint enviar mensaje (validar saldo, descontar, LPUSH cola). Reverb instalado. Eventos básicos.
Semana 4 · Panel operador
App SPA. Login operador. queue:ops push del match vía WS. Layout 3 columnas. Atajos teclado. Validación de reglas (longitud + pregunta).
Semana 5 · Monedero + packs + Stripe
Tabla packs y purchases. Endpoint comprar. Webhook Stripe con cola de reintentos. Precio congelado. Wallet del cliente. Historial.
Semana 6 · Comisiones + payouts
Tier de operadores. Cálculo automático por volumen semanal (cron). Withdraw requests. Aprobación manual desde admin.
Semana 7 · Notas + guiones + moderación + push
Tabla notes, UI del cuaderno. Anti-fuga (filtros teléfonos/links). Push Firebase. Email transaccional. Moderación: ban, reportar.
Semana 8 · Hardening + lanzamiento beta
Tests E2E. Rate limiting. Audit logs. Pruebas con 5 operadores reales y 20 clientes invitados. Ajustes. Go-live cerrado.
Fase 2 · Crecimiento (meses 3–6)
- Captación de operadores con landing dedicada + ads.
- Segunda marca (mismo backend, dominio nuevo, paleta nueva).
- Suscripción premium.
- Contenido bloqueado (PPV media) — operadores pueden mandar fotos pagables.
- App móvil (Expo / React Native) — mismo backend. Plan detallado en la tab "Apps móviles": arranca cuando 1 marca alcance el gate de tracción.
- Reportes avanzados + exportación CSV.
- A/B testing de packs y de copy del onboarding.
Fase 3 · Escalado (meses 6–12)
- Multi-idioma real (EN, PT, FR).
- Pagos con cripto (USDT/USDC vía Coinbase Commerce o NowPayments).
- Anti-fraude avanzado (ML para detectar patrones de chargebacks).
- Marketplace de operadores como producto separado (vendes "operadores certificados" a sites de terceros).
- Integración con LLM (Llama 3.3 / Mistral) para asistir al operador con sugerencias (no autoresponder).
- White-label SaaS — vendes el sistema a terceros con comisión recurrente.
Equipo mínimo recomendado para MVP
Laravel + Next.js. Tú (o un freelance probado).
UI de marca, landings, branding por dominio.
Aprueba operadores, revisa periodos de prueba, escribe temario.
Después de MVP, agregas: 1 dev mobile, 1 community/marketing, más team leaders por idioma.
Apps móviles — planificación post-tracción
Las apps móviles no son MVP. Son la apuesta de Fase 2/3 cuando ya tengas 1 marca con tracción demostrada: clientes recargando, operadores produciendo, churn controlado. Lanzar móvil antes es quemar foco y dinero en algo que aún no tiene product-market fit. Pero el backend ya está preparado para soportarlas desde el día 1.
No tocamos móvil hasta que una marca cumpla, durante 4 semanas seguidas:
- ≥ 300 clientes activos pagando.
- ≥ 20 operadores estables (no churn 2x al mes).
- ≥ €15.000/mes de revenue.
- Métrica blanda: NPS de operadores ≥ 30 (con encuesta breve).
Si una sola marca llega ahí, móvil pasa a ser inversión racional. Si ninguna llega en 6 meses, hay un problema más profundo que móvil no va a resolver.
Las tres apps
🟩 MORBOSOS Operator
Una sola app · global · multi-idioma.
Para qué:- Operadores responden la cola FIFO desde cualquier lugar.
- Push prioridad alta con sonido distintivo.
- Tracking de tier en vivo + wallet + retiros.
- Modo "siguiente disponible" en una sola pantalla, optimizado para una mano.
com.morbosos.operator
Por qué importa: en Cloudworkers/Chatwriters los operadores que tienen app móvil producen ~30% más. Movilidad = retención.
🟥 MORBOSOS Admin
Una sola app · uso interno · MFA obligatorio.
Para qué:- Brand admins ven KPIs en tiempo real desde el celular.
- Aprobar retiros en 2 toques.
- Alertas push: cola saturada, fraude, pago disputado.
- Super admin: vista multi-marca + intervención rápida.
com.morbosos.admin
Por qué importa: una alerta de "cola en rojo, 200 mensajes esperando" llega y respondes desde donde estés.
🟦 Apps de marca (N apps)
Una app por dominio · white-label · distribución pública.
Para qué:- Cliente final paga y chatea desde móvil.
- Cada marca = su propia app, su propio ícono, su propio nombre en tiendas.
- Push tipo "Sofía te respondió" — el gancho de retención más fuerte que existe.
- Compras de packs vía web (no in-app) por la comisión de Apple del 30%.
app.venezueladigital.marca1, marca2, …
Por qué importa: el ARPU móvil suele duplicar al web (push + always-on).
Diagrama: tres apps, un backend
Stack móvil
| Capa | Tecnología | Por qué |
|---|---|---|
| Framework | React Native + Expo (managed) | Un codebase TS para iOS + Android. EAS Build firma y publica. |
| Routing | Expo Router | File-based, deep links nativos, transiciones por defecto. |
| State | Zustand + TanStack Query | Ligero, predecible, sincroniza con el backend. |
| Auth | Sanctum tokens + SecureStore | Mismo flujo que web. Tokens en Keychain/Keystore. |
| WebSocket | Pusher.js / laravel-echo | Conecta a Reverb del backend. Reconexión automática. |
| Push | Expo Push API → APNS + FCM | Una sola integración para ambas tiendas. |
| Pagos | Stripe SDK · pagos vía web link | Evita 30% de Apple IAP. Web checkout con deep link de retorno. |
| Updates | expo-updates (OTA) | Parches sin re-subir a tiendas (excepto cambios nativos). |
| CI/CD | EAS + GitHub Actions | Build automático en push a main. |
| Analytics | PostHog o Mixpanel | Funnel de retención, eventos custom. |
| Crash reporting | Sentry RN | Mismo Sentry que el backend. |
Cómo se comparte código entre las N apps de marca
Monorepo con un paquete @morbosos/mobile-core que contiene el 95% del código. Cada app de marca es un wrapper mínimo que:
- Importa
@morbosos/mobile-core. - Define su
brandId,apiBaseUrl,theme,logoAsset. - Tiene su propio
app.jsoncon bundle id, ícono, splash, nombre. - Su pipeline EAS empaca con esa config.
// apps/marca1/App.tsx
import { MorbososApp } from '@morbosos/mobile-core';
import theme from './theme.json';
export default () => (
<MorbososApp
brandId="marca1"
apiBaseUrl="https://api.morbosos.com"
theme={theme}
appName="Marca 1"
/>
);
Agregar la marca 4 = duplicar carpeta + cambiar 5 strings + correr eas build. Costo marginal por marca: 1 día de trabajo.
Plan de ejecución móvil
Hito 0 · Gate de tracción cumplido
1 marca con métricas verdes durante 4 semanas (ver arriba). Hasta entonces, cero código móvil escrito.
Fase Mobile-1 · Operator App (4 semanas)
Es la app con mayor retorno inmediato. Operadores móviles producen más. Empezamos por aquí.
- Sem 1: scaffolding Expo + auth + navegación.
- Sem 2: integración del dispatcher móvil (recibe match, responde, regresa a cola).
- Sem 3: push notifications + sonido prioridad alta + wallet + retiros.
- Sem 4: beta con 10 operadores · ajustes · TestFlight + Internal Testing.
Fase Mobile-2 · App de la primera marca (4 semanas)
Lanzamos sólo para la marca con más tracción. Aprendemos antes de escalar a N.
- Sem 1: estructura del monorepo + paquete core + theming.
- Sem 2: catálogo de perfiles + chat + WS.
- Sem 3: compra de packs vía web link + push.
- Sem 4: revisión por tiendas (App Store + Play) · soft launch.
Fase Mobile-3 · Admin App (2 semanas)
Una vez los flujos web están estables. App ligera, sin floritura.
- Sem 1: dashboard, KPIs, lista de retiros pendientes.
- Sem 2: push de alertas, aprobar/rechazar en 2 toques, MFA.
Fase Mobile-4 · Escalar a N marcas (~1 día por marca)
Cada nueva marca = clonar config en el monorepo + correr eas build + subir a tiendas.
Coste estimado del programa móvil
Riesgos específicos del programa móvil
- Apple rechaza apps "adult-leaning": mitigación = registrar como "social/dating", screenshots suaves, descripción no explícita.
- Google Play tolera más pero exige verificación de edad y aviso explícito.
- Apple 30% IAP: evitable pagando vía web link (deep link de retorno). Riesgo: si Apple cambia política puede sacarte de la tienda.
- App rejection en revisión: presupuestar 2–3 iteraciones de revisión por marca nueva.
- Mantener N apps es trabajo: cada release del core hay que rebuild y republicar las N. EAS Build + script lo automatiza pero requiere disciplina.
No tocar móvil hasta el mes 4–6. Cuando una marca alcance las métricas del gate, empieza por Operator App (4 semanas) — es la inversión con mayor ROI inmediato. Después 1 app de marca. Admin app puede vivir más tiempo como PWA antes de necesitar nativo.
Riesgos y mitigaciones
No te decimos qué hacer con los abogados — eso ya está cubierto por ti. Aquí están los riesgos operativos y técnicos que afectan al producto, ordenados por probabilidad × impacto.
Matriz
| Riesgo | Probabilidad | Impacto | Mitigación principal |
|---|---|---|---|
| Cierre de cuenta Stripe / PayPal (sector adulto) | Alta | Crítico | Múltiples pasarelas desde día 1 (MP, cripto, Zelle). Marca "fantasy chat" / "dating" en MCC, no "adult". Reserva caja. |
| Operador filtra a cliente sospechoso (le dice que es ficticia) | Media | Alto | Anti-fuga en UI (filtra palabras clave). Audit log. Penalización: 0 pago + ban inmediato. Cláusula contractual. |
| Chargebacks masivos de clientes que reclaman | Media | Alto | Mensaje claro en checkout: "servicio digital, no reembolsable". 3-D Secure obligatorio. Reserva del 10% del revenue. Disputas con prueba (chats). |
| Inconsistencia entre operadores en el mismo perfil | Media | Medio | Notas obligatorias + guión visible + historial completo en pantalla. Capacitación. Penalización por incoherencias detectadas. |
| Fotos detectables como stock (cliente busca en Google Images) | Alta | Medio | Fotos generadas con IA (Flux + LoRA por perfil para coherencia) o compradas con licencia exclusiva. Rotar set cada 3 meses. |
| Cola se llena en pico (mensajes pendientes > operadores online) | Media | Medio | Alertas a Super Admin si pending > X. Reclutar más operadores. Auto-reembolso si stale > 4h. AI fallback opcional (configurable por marca). |
| Operador clave deja la plataforma | Baja | Bajo | El diseño con cola FIFO + notas hace que ninguno sea irremplazable. Pool grande. Bonus por antigüedad. |
| Filtración de DB / leak | Baja | Crítico | Encriptación at-rest. Mensajes cifrados con clave por brand. Backups encriptados. Acceso DB solo desde VPC. Rotación de claves. |
| Bot/scraper inundando la cola (mensajes desde cliente fake) | Media | Medio | Rate limit por cliente (X msgs/min). hCaptcha en registro y compra. Reglas anti-fraude (cliente recarga + envía 50 msgs en 5 min = flag). |
| Reputación pública del proyecto (Trustpilot, Reddit) | Media | Medio | Marca "fantasy chat" explícita en términos. Sistema de reembolso amistoso. Soporte al cliente 24/7 (mínimo email). |
Decisiones técnicas a tomar ya
3 opciones:
- Stock licenciado exclusivo (ej. agencias específicas): caro pero limpio.
- Generadas con IA (Flux + LoRA por personaje): casi gratis y únicas, pero requiere setup técnico y la regulación de imagen sintética sube.
- Compra a modelos reales (cesión de derechos): mejor calidad, más caro y trazable.
Mi voto: mix de 2 + 3 — IA para volumen, modelos reales para los perfiles "top" de cada marca.
Tres posibilidades:
- Cero AI: humano 100%. Más auténtico pero más caro y limitado.
- Sugerencias inline: el operador ve 3 borradores generados y elige/edita. Aumenta productividad ~50%, mantiene control.
- Autoresponder de fallback: si nadie está online, AI responde (como SkaDate). Cuidado: cae la calidad.
Mi voto: empieza con 1. En Fase 3 agrega 2 (cuesta poco con Haiku 4.5 / Mistral). Evita 3 salvo emergencia.
Pros: pasarela alternativa si Stripe te cierra, anonimato para clientes que lo valoran, mercado adulto cripto-friendly. Contras: ramp-up para clientes no técnicos, volatilidad si no liquidas inmediato.
Mi voto: NO en MVP. Sí en Fase 2 con Coinbase Commerce o NowPayments (USDT/USDC).
El backend ya es multi-marca desde el diseño, pero cada marca consume foco: branding, fotos, ads, soporte. Lanzar 3 a la vez triplica el costo de lanzamiento sin triplicar revenue.
Mi voto: 1 marca al MVP. Segunda marca al mes 4 cuando ya tengas el playbook de captación. Tercera al mes 8.
Tus comentarios consolidados
Todo lo que escribiste en cada sección queda guardado en este navegador (localStorage). Aquí puedes verlo todo junto, exportarlo y pasárselo al equipo como mejoras o aclaraciones.
- Cada sección tiene su propio bloque "💬 Comenta". Lo que escribas se guarda automáticamente al hacer "Agregar comentario".
- Los datos viven solo en este navegador. Si borras la caché del navegador o abres el archivo en otro lado, no estarán.
- Cuando estés listo, usa "Copiar como Markdown" para pegarlo en el chat con el equipo o "Descargar JSON" para guardar el backup.