Uber Truck — marca

Memoria técnica del proyecto

Producto: Uber Truck — marketplace de capacidad logística ociosa (backhaul), Chile.
Documento: memoria técnica viva del repositorio y del despliegue Railway.
Versión documento: 4.4  |  Software: 0.0.129 (Cubik app móvil + API Railway)  |  Fecha: 25 may 2026  |  Backlog/Gantt: vivo — revisar semanalmente

← Documentación · Inicio app · Producción: uber-truck-production.up.railway.app · Probar (testers): /probar

Propósito y forma de mantenimiento

Este archivo es la referencia única de arquitectura, hitos, cronograma Gantt, próximos pasos y stack por capas. Actualizarlo cuando cambien migraciones Supabase, rutas API, reglas de cancelación/multas o el avance real frente al plan.

Formato Word: en la raíz del repo ejecutar npm run export:memoria-docxdocs/Memoria-tecnica-Uber-Truck.docx y copia en Downloads/Proyecto Uber Truck/. Pack completo: npm run export:all-docs.

Visión de producto

MVP final = una sola app web con funcionamiento lo más parecido posible a Uber (pedir → emparejar → viaje en curso → chat → cancelar → cuenta), adaptado a carga por camión. El usuario ya sabe usar Uber; la curva de aprendizaje debe ser mínima.

Objetivo comercial: ganar usuarios y viajes reales con esta app propia. Objetivo estratégico a futuro: demostrar tracción y ofrecer el producto como add-on / integración a plataformas grandes (ej. marketplace logístico o apps de movilidad), no reemplazarlas desde el día uno.

Descartado para el MVP: piloto paralelo con WhatsApp + Airtable fuera de la app. Todo el piloto y la operación van dentro de Uber Truck.

Resumen ejecutivo del stack

Embarcadores y transportistas usan la misma app (public/): publicar demanda u oferta, ver sugerencias de match, aceptar, seguir estados, chatear, cancelar y revisar multas/cuenta. Backend Node.js 20 + Express 4, datos en Supabase, auth JWT, deploy Railway, código en GitHub.

Principio de producto

Priorizar paridad de flujo Uber y usuarios activos en la app antes que integraciones B2B o Open Finance. Pagos in-app y mapa en vivo entran cuando el flujo base ya se usa sin fricción.

Paridad UX — Uber vs Uber Truck (MVP final)

Resumen may 2026: el MVP final de flujo está cerrado en producción (v0.0.129). Post-MVP ítems FCM y contraseña fuerte cerrados; recuperar clave con código listo pero bloqueado para multi-cuenta piloto hasta dominio Resend (ver DOMAIN-AND-EMAIL.md). Canvas plan: canvases/cubik-plan-native-escala.canvas.tsx.

MVP final — flujos core (cerrados)

Flujo tipo UberUber TruckEstado MVP
Pedir un viajeEmbarcador publica cargaHecho
Conductor disponible / aceptaTransportista publica capacidad y acepta matchHecho
Viaje en curso (estados)Propuesto → aceptado → en ejecución → completadoHecho
Chat con la otra parteChat in-app por match (+ presets en ruta)Hecho v0.0.97+
Cancelar con reglasModal motivos, acuerdo mutuo, multas sugeridasHecho
Iniciar sesión / registroEmail + contraseña (JWT)Hecho
NotificacionesCampana in-app; activos vs historial; archivo al cerrar viajeHecho v0.0.125
Mis viajesPestaña Mis viajes + banner viaje activo + calificaciónHecho v0.0.28+
Publicar / ofertarPedir flete / Ofertar ruta + mis cargas/ofertas (owner_user_id)Hecho
Buscando camionesSugerencias con estado «buscando…»Hecho
Precio oferta/demandaRango embarcador + oferta transportista + aceptación + tarifa sugerida calibradaHecho v0.0.105+
Declaración de carga y confianzaValor ref. CLP, guía, términos, incidentes drawerHecho v0.0.98+
Mapa / direcciónGoogle Maps origen–destino + distancia + navegar Maps/WazeHecho
Mapa en vivo / GPSUbicación transportista + mapa en viaje activoHecho v0.0.34+
Anti-bypass teléfonoBloqueo números en chat; botón Llamar (UI lista)Hecho v0.0.98
Incidentes / perfil shellDrawer incidente, shell Cuenta tipo UberHecho v0.0.97–0.0.98
Calificación ★Mutua 1–5 + chips por rol; reputación en tableroHecho v0.0.28–0.0.31
Perfil y cuentaEmpresa, billetera multi-cuenta, multas, comprobanteHecho v0.0.94+
Cubicación carga / ofertaPallets ↔ m³, preset, tipo camión, camión habitualHecho v0.0.90–0.0.93
Pago en app (piloto)Cubik Saldo piloto 10/5 — Pagar post-completed + notif transportistaHecho v0.0.100–0.0.104
Checkout UX (piloto)Drawer «Pagar con Cubik Saldo» + desglose por rolHecho v0.0.102+
QA automatizadoUnit + Playwright + CI GitHub + Laboratorio /qa-labHecho v0.0.125
App Android testersCapacitor + APK remoto/bundle + verify loginHecho v0.0.125
Distribución sin tienda/probar + APK + PWA iPhoneHecho jun 2026

Post-MVP — no bloquea demo ni piloto 25/50

Validar en orden: Checklist interactivo Post-MVP · Guía MD · API GET /api/post-mvp/status

Flujo / capacidadUber TruckEstadoVentana
Login Gmail / AppleOAuth Google + Sign in with AppleBloque E — post-pilotoQ3 2026+
Recuperar contraseñaEnlace por correo (Resend)Código validado; piloto bloqueado sin dominio propioP0 — dominio
Política contraseña + cambio en app8+ chars, mayúscula, número; Seguridad en Cuenta APKHecho v0.0.128
Pago en app (prod)Wallet real + retención al «En ruta»; escrow 10/5P0 siguienteSem 2–8 piloto
Llamadas enmascaradasTwilio Proxy — botón LlamarUI lista v0.0.98; proxy pendienteSem 2–4
Push móvil (FCM)Token Android + envío servidorCerrado — 3 push en 2.º plano
GPS background (app cerrada)Plugin Capacitor / módulo nativo liteSpike sem 4–9 si piloto lo exigeVer canvas nativo
App iOS nativaTestFlight / App StoreHoy PWA vía /probarPost escala
Escrow checkout en rutaRetención al «Marcar en ruta» (prod)Diseño cerrado; wallet real primeroCon U7 prod

Parte I — Hitos del proyecto

Fase 0 — Descubrimiento y legal

Objetivo

Entrevistas en nodo industrial (San Bernardo / RM), validación de precio/comisión y borrador legal + seguro piloto.

Estado (jun 2026)

En curso — paralelo al MVP digital ya desplegado y demo comercial.

Fase 1 — MVP final app tipo Uber (producto único)

Objetivo

Cerrar la paridad de flujo en la misma app: mis viajes por cuenta, copy y pasos al estilo Uber, piloto con 20 viajes reales hechos 100% en la plataforma (hito M2).

Estado jun 2026

MVP flujo cerrado (v0.0.129). Pendiente operacional: dominio/correo Resend20 viajes M2 + piloto 25 empresas / 50 transportistas — no más pantallas core.

Fase 2 — Núcleo digital (ya en producción)

Lo realizado (adelantado vs Gantt oct 2026)

Pendiente en fase 2 (post-MVP prod)

Fase 3 — Piloto confianza

KYC manual, ratings bidireccionales (adelantado — mayo 2026), microseguro POC, 100 viajes digitales (M4). Pendiente: reputación visible en tablero Emparejar (M3).

Fase 4 — Escala producto

Match semi-automático por corredor, dashboard embarcador frecuente, informe red de capacidad (M5).

Fase 5 — Estrategia add-on (visión, post-tracción)

Con métricas de uso (viajes, retención, NPS), empaquetar capacidad ociosa como módulo integrable (API + widgets) para socios tipo marketplace o apps de movilidad. Requiere MVP propio maduro y casos de éxito en Chile.

Cronograma del proyecto — vista Gantt

Las fechas son orientativas (jun 2026 – mar 2027). El Gantt detallado por mes está en este mismo documento (no hace falta abrir otro archivo).

Leyenda

EstiloSignificado
HechoEntregado en repo / producción
En cursoTrabajo activo
PlanificadoNo iniciado o pendiente de priorización
Fuera del trimestre

Resumen por fases

FaseNombreInicioFinDuración
0Descubrimiento y legal2026-06-012026-06-284 sem
1MVP final app (paridad Uber + piloto)2026-06-012026-08-3112 sem
2MVP digital v12026-08-012026-10-2512 sem
3Piloto escalado + confianza2026-10-012027-01-3116 sem
4Producto B2B (SaaS)2027-02-012027-03-318 sem

Diagrama Gantt por fase (trimestres)

Fase 2026 T2
abr–jun
2026 T3
jul–sep
2026 T4
oct–dic
2027 T1
ene–mar
0 · Descubrimiento En curso Plan
1 · MVP final app Paridad cerrada Piloto 25/50 + M2 Operación
2 · MVP digital Hecho Hecho Wallet prod Escala
3 · Confianza Plan En curso
4 · SaaS Plan

Hitos (milestones)

HitoFecha planEstado real (10 jun 2026)
M1 Descubrimiento + legal28-jun-2026En curso
M3 MVP digital en producción25-oct-2026Hecho (adelantado jun 2026)
M2b Demo comercial + plan piloto 25/5013-jun-2026Esta semana
M2 20 viajes en la app (piloto corredor)31-ago-2026P0 operación
M4 100 viajes digitales31-ene-2027Pendiente
M5 Match semi-auto + SaaS31-mar-2027Pendiente

Métricas de control

MétricaMeta M2Meta M4
Emparejamientos exitosos20100
Tiempo medio match< 4 h< 1 h (digital)
Take rate15% (10% + 5%)15% efectivo
NPS transportista≥ 7≥ 8

Interpretación 25 may 2026: MVP flujo cerrado (v0.0.129); FCM y contraseña fuerte cerrados; SQL prod 23/23 OK; foco = dominio Resend (P0) → demo comercial → piloto 25/50 → 20 viajes M2. Wallet prod y Twilio en cola P0; OAuth/iOS fuera de alcance inmediato. cubik.cl y cubik.com ocupados — variante compuesta sin renombrar app.

Piloto M2 — corredor único (liquidez)

El cuello de botella del marketplace no es el código sino la oferta y demanda simultánea. El piloto M2 se concentra en un corredor para lograr densidad operacional.

ElementoDefinición
Corredor principalRM (origen, ej. San Bernardo / nodo industrial) ↔ Valparaíso / San Antonio (destino)
Meta semanal liquidez≥ 3 cargas publicadas y ≥ 2 ofertas activas en el mismo corredor
Meta M220 matches completed en ese corredor (jul–ago 2026)
Ancla1 transportista ruta fija + 2–3 embarcadores PYME del nodo

Detalle operativo: Piloto M2 — corredor, KPIs y riesgos.

KPIs marketplace — piloto M2

KPICálculo (resumen)Meta M2
Match rateCargas con match aceptado / cargas con ≥1 propuesta≥ 60%
Tiempo a matchMediana publicación → accepted< 4 h
Cancelación post-asignaciónCancelados tras accepted / total aceptados< 10%
Viajes completadosmatches.completed en corredor piloto20
Take rate efectivo15% (10% embarcador + 5% transportista) sobre agreed_price_clpRegistrar en piloto
Tiempo respuesta carrierPropuesta → oferta CLP< 2 h laboral
NPS ambos rolesEncuesta manual post-viaje≥ 7
Repetición embarcador 60 d≥ 2 cargas mismo embarcador≥ 30%

Matriz de riesgos operacionales

RiesgoMitigación pilotoResponsable
Robo / extravío011 declaración, incidentes, términos, seguro manualTransportista + seguro
Carrier fantasmaRegistro empresa, KYC manualPlataforma + embarcador
Declaración falsa cargaValor ref. + guía/folio; sin SII auto aúnEmbarcador
No-show / retrasoEstados, multas, chatTransportista
Daño mercaderíaIncidente damage; foto entrega (roadmap)Partes
Disputa «app paga»Intermediación explícita; tabla cobertura en anexo pilotoPlataforma aclara

Cobertura — quién responde (resumen)

La plataforma no transporta ni reembolsa el valor declarado de la mercadería por defecto. Transportista ejecuta el flete; embarcador declara con veracidad; Uber Truck facilita match, registro, chat, incidentes y reglas de cancelación.

Tabla completa: anexo piloto §4 · términos cargo-trust-v1.

Próximos pasos — backlog vivo (25 may 2026)

Prioridad: P0 bloquea piloto; P1 siguiente entrega; P2 planificado. Actualizar al cerrar cada release o semana de piloto. Detalle comercial: PLAN-COMERCIAL-PILOTO.md · canvas cubik-plan-native-escala.

IDPActividadEntregableVentanaEstado
Cerrado — MVP digital y paridad UX
U1SQL 004–030 en Supabase prodChat, notif, banco, ratings, FCM, billeteraMay–Jun 2026Hecho
U4Scopes por rol + registro empresashipper/carrier/adminMay 2026Hecho
U4b–fPrecio, confianza, calificaciones, reputación tablero010–014 SQL + UIMay 2026Hecho
U5UX paridad Uber completaCubik móvil, cubicación, billetera, chat, incidentesJun 2026Hecho v0.0.90–0.0.125
U7aCubik Saldo piloto 10/5SQL 026, pilot-pay, badges, notifJun 2026Hecho v0.0.100–0.0.104
U7mMultas + comprobante + banco obligatorioSQL 022–025, bank-gateMay 2026Hecho v0.0.57
U13QA automatizado + LaboratorioPlaywright, unit, CI, /qa-labJun 2026Hecho v0.0.125
U14Notificaciones activas vs historialnotification-visibility.jsJun 2026Hecho v0.0.125
U15Memoria v4.3 + docs hubGantt, paridad MVP cerrada, plan comercial10 jun 2026Hecho
U16Push FCM validado en teléfono físicoSegundo plano + acciones viajeMay 2026Cerrado
U17Contraseña fuerte + cambio clave APKpassword-policy.js, Seguridad Cuentav0.0.128Cerrado
U18Resend forgot/reset en prodErrores visibles, cooldown 2 min, /health mailv0.0.129Código cerrado
U19SQL verificación prod 23/23 + 014RUN_VERIFY_ALL_MIGRATIONS.sqlMay 2026Cerrado
En curso — comercial y piloto (sem 1–16)
E0P0Dominio propio + Resend verificadoEMAIL_FROM=noreply@…DOMAIN-AND-EMAIL.mdInmediatoBloqueante piloto correo
C1P0Demo comercial juevesWeb prod + APK remoto; cuentas demo; guión DEMO-GUION.mdSem 1 (9–13 jun)Esta semana
C2P0Checklist demo (login, emparejar, qa:lab)6 ítems canvas «Antes del jueves»Sem 1En curso
C3P0Onboarding piloto 25 empresas + 50 transportistasKYC manual + banco; corredor RM–VSem 2–5Siguiente
C4P0APK bundle firmado testerscubik-android.apk dedicado pilotoSem 2–3En cola
U6P0Piloto 20 viajes corredor RM ↔ V/San AntonioM2 — liquidez + densidadSem 6–13 (jul–ago)P0 operación
U6bP1KPIs marketplace M2 (semanal)Match rate, tiempo, NPS — anexo pilotoSem 6–13Doc listo
Cola P0/P1 — producto post-MVP
U7P0Cubik Saldo prod + escrow en rutaWallet, ledger, retención; tier $1MSem 2–8En cola
U7dP0Twilio Proxy llamadasTWILIO_MATCH_PROXY_NUMBERSem 2–4UI lista v0.0.98
C5P1Spike GPS background (Capacitor)Plugin + servicio Android si piloto lo exigeSem 4–9Plan canvas
C6P1Validar push FCM en teléfono físicoSegundo plano + acciones de viajeSem 1–3Hecho 10 jun 2026
U6cP1Reputación v0Cancelaciones + incidentes por cuentaPost 5 viajesPlan
U6dP1Evidencia entregaFoto + timestampPost-piloto cortoPlan
Escala — sem 10+ (50+ empresas / 200 camiones)
C7P1Auditoría costo Maps 200 camionesPresupuesto ~USD 2.100/mes infraSem 10–12Plan
C8P1Decisión go/no-go nativo liteUmbral: >40 camiones mapa o quejas GPSSem 12Plan
C9P2Play Store closed testing / MDMDistribución flota escalaSem 10+Plan
Fuera de alcance inmediato
U4dP2PDF guía + validación SII/DTEStorage + facturadorPost-pilotoPlan
U10P2Login Gmail + Apple (bloque E)OAuth — post-pilotoPost-M2Diferido
U11P1Panel admin KPIs pilotoViajes, GMV, NPS — ver pitch panelCon M2Diseño listo
U8P2KYC manual ampliadoFase 3 operativaOct 2026+Plan
U9P2Match semi-auto corredorAlgoritmo v1Feb 2027Plan

No hacer aún: rewrite 100 % nativo, Open Finance, pricing dinámico completo, expansión multi-corredor sin liquidez. Priorizar operación piloto sobre más pantallas.

Gantt plan comercial — 16 semanas (9 jun – 29 sep 2026)

Alineado a canvases/cubik-plan-native-escala.canvas.tsx. Barras ████ = ventana activa por semana (S1 = 9–13 jun).

IDFase / tarea claveResp.S1S2S3S4S5S6S7S8S9S10S11S12S13S14S15S16Estado
C1Prep demo comercial (jueves)E/O████Esta semana
C2Verificar prod login + Emparejar + APK remotoE████Checklist canvas
C3Cuentas demo + viaje ejemplo embarcador/transportistaO████En curso
C4Onboarding piloto 25 empresas + 50 transportistasO/E████████████████Sem 2–5
C5APK bundle firmado + link testers pilotoE████Sem 2–3
C6Operación piloto + monitoreo Railway + soporte WhatsAppO/E████████████████████████████████Sem 6–13
U620 viajes completed corredor RM ↔ V (M2)O████████████████████████████████KPI M2
C7Spike GPS background (Capacitor / nativo lite)E████████████Paralelo S4–9
U7Wallet real + escrow en rutaE██████████████P0 prod
U7dTwilio Proxy (Llamar enmascarado)E██████Sem 2–4
C8Prep escala 50+ empresas / 200 camionesE/O████████████████████████████Sem 10–16
C9Auditoría costo Maps + decisión nativo (sem 12)E████Go/no-go
QA + Laboratorio + notificaciones archivadasEHecho v0.0.125

Gantt detallado por tarea (2026–2027)

Responsable: E=Equipo, O=Operaciones/piloto, L=Legal. Vista mensual complementaria al Gantt de 16 semanas.

IDTareaResp.InicioFin JunJulAgoSepOctNovDicEneFebMar Estado
C1Demo comercial + pitch piloto 25/50O/E09-jun13-junEsta semana
C4Onboarding piloto 25+50O/E16-jun11-jul████Planificado
0.1Entrevistas transportistas + PYMEO01-jun28-jun████En curso
0.2Validación precio / comisión 12–15%O15-jun15-jul████En curso
0.3Términos legales + seguro pilotoL01-jun30-jun████Borrador v011
1.1Mis cargas / mis ofertas (owner_user_id)EHecho
1.2Refino UX flujo tipo UberEHecho v0.0.125
1.3Piloto 20 viajes en la app (M2)O/E07-jul31-ago██████████P0
1.4Informe piloto (métricas + pitch)E15-ago15-sep██Plan
2.xMVP digital núcleo (API, UI, chat, multas, Cubik app)EHecho
2.11Cubik Saldo piloto 10/5 + QA + notificacionesEHecho v0.0.125
2.10bWallet prod + pasarela + escrow en rutaE16-jun31-ago████████P0
2.12Twilio Proxy llamadasE16-jun05-jul██UI lista
2.13GPS background (nativo lite spike)E30-jun31-ago████████Si piloto exige
3.1KYC + checklist vehículoO/E01-oct15-nov██Plan
3.2Ratings bidireccionalesEHecho
3.3Microseguro InsurTech POCL/O01-nov31-dic████Plan
3.4100 viajes digitales (M4)O01-nov31-ene██████Plan
4.1Match semi-auto corredorE01-feb28-feb██Plan
4.2Dashboard embarcador SaaSE01-feb31-mar████Plan
C8Prep escala 50+/200 camiones + auditoría MapsE/O15-sep29-sep████Sem 10–16

Avance fase 2 — resumen (10 jun 2026)

Bitácora de avance — 27 mayo 2026

ÁreaEntregadoNotas
Auth / loginErrores visibles, anti doble envío, sesión tras «Salir»Prod validado por usuario
UX emparejamientosBotón aceptar match destacado; confirmación antes de en ruta / finalizar / aceptar precioAnti doble clic
Calificaciones M1match_ratings, mutuo shipper↔carrier, modal estrellas, bloque en CompletadosSQL 012; POST …/rate
Calificaciones M2Chips por banda (★1–3 negativos, ★4–5 positivos), comentario obligatorio ★1–2SQL 013; rating-tags-catalog.json
Operación SupabaseTras migraciones: NOTIFY pgrst, 'reload schema';Evita PGRST204 en caché PostgREST
Fix servidorlistMatchRatings sin SELECT *; insert/update columnas mínimasLogs Railway sin ruido PGRST204
Fix clientesessionStorage por rol (matchId:carrier); limpieza al login/logoutTransportista puede calificar tras embarcador
Fix alcanceOfertas sin carrier_user_id: match visible si empresa coincideBackfill al ofertar precio
UX Mis viajesCompletados: listado vertical (más reciente arriba); sin botón «Abrir» → Emparejar«Gestionar viaje» solo en curso/negociación

Bitácora de avance — 29 mayo 2026 (v0.0.50–0.0.57)

ÁreaEntregadoNotas
Multas y bloqueo7 días (PENALTY_DUE_DAYS), gate operar, banner bloqueoSQL 022–024; penalty-gate.js
Pago declaradoDeudor: declarar + comprobante JPG/PNG/WebPSQL 025; claim-paid, payment-proof
Confirmación acreedorEmbarcador/transportista acreedor: ver comprobante, confirmar o rechazar (24 h)Sección «Pagos por confirmar»; modal revisión; no sube comprobante
ModeradorCasos soporte, chat moderador, cierre adminsupport_cases; botones solo rol admin
Cuenta bancariaObligatoria en prod para publicar/ofertar/emparejarbank-gate.js, BANK_ENFORCE
UX cuentaPanel multas siempre visible; viajes cancelados sin «Gestionar viaje»penalties-ui.js, trips-ui.js
Pendiente prod.Pasarela + validar tarjeta tipo UberDoc: PENALTY-AND-SUPPORT.md § Producción futura
Pendiente prod.Login Gmail (Google) + Apple + correo transaccionalDoc: AUTH-AND-EMAIL-ROADMAP.md

Deploy: Railway uber-truck-production.up.railway.app · rama main · versión app 0.0.57.

SQL pendiente usuario: ejecutar en Supabase RUN_022_023, RUN_024, RUN_025 (ver SQL-SUPABASE.md).

Archivos clave: src/lib/penalty-ledger.js, src/lib/penalty-payment.js, src/lib/bank-gate.js, src/routes/account.js, public/penalties-ui.js.

Bitácora de avance — 2 junio 2026 (Cubik v0.0.75–0.0.78)

ÁreaEntregadoNotas
Marca CubikShell móvil, splash, logo isotipo, bienvenida «Optimiza tus envíos»app-shell.js, generate-android-icons.cjs
Arranque appBundle local en APK; splash 500 ms; sin fetch tablero sin sesión; CORS https://localhostv0.0.76–0.0.77
Login móvilAlertas email vs contraseña; gate bienvenida sin legacy debajoauth-ui.js, src/lib/auth.js
Capacitor Androidcl.cubik.logistics; npm run cap:sync:bundle (default); APK npm run android:apk → DescargasUI en assets; API en Railway
Testers sin tiendaPágina /probar — Android (APK o PWA) + iPhone (PWA Safari)public/probar.html
Play Store (nombre)Decisión: Cubik Envíos Chile (solo Chile al publicar)USD 25 cuando suban prueba cerrada
Validado usuarioLogin admin OK; 2 emuladores (embarcador + transportista API 37); tiempos ~2 sJun 2026

Links operativos:

Comandos: npm run cap:sync:bundle · npm run android:apk · npm run cap:open:android

Bitácora de avance — 3 junio 2026 (Cubik v0.0.90–0.0.94)

ÁreaEntregadoNotas
Oferta transportistaParidad con publicar carga: pallets, m³, tipo camión, camión habitual en perfilSQL 029; load-capacity-ui.js; commits v0.0.90
Maps móvil embarcadorPublicar carga sin layout corrido; sugerencias Maps alineadas al inputmaps-ui.js, app-shell.css v0.0.91–0.0.92
FCM RailwayFCM_SERVICE_ACCOUNT_B64, health fcm.configured: true, device_tokensValidado en teléfono 10 jun 2026 — ver bitácora 10 jun
Cuenta bancariaValidador RUT + selector bancos Chile (lista API)v0.0.93; rut-chile-ui.js, chile-banks.js
Cubicación cargaSync pallets ↔ m³ (~1,2 m³/pallet); preset → Personalizado al excederload-capacity-ui.js v0.0.93
Billetera (tipo Uber)Varias cuentas bancarias: agregar, editar, eliminar, predeterminada; tarjetas listadasSQL 030 user_bank_accounts; API CRUD; v0.0.94
Validado usuarioPublicar carga OK prod; billetera sincronizada web ↔ APK; 2 cuentas bancarias en prodJun 2026
PendienteConfirmar recepción push en dispositivo físico (push-test)device_tokens registrado; ver § FCM

SQL usuario: ejecutar RUN_030_user_bank_accounts.sql en Supabase (migra cuenta legacy + multi-cuenta).

Deploy: commits 38dee51 (v0.0.93), f816bbe (v0.0.94) · Railway main.

Bitácora de avance — 10 junio 2026 (Cubik v0.0.127 — push FCM validado)

ÁreaEntregado / validadoNotas
Push FCM AndroidRecepción en dispositivo físico con app en segundo plano3 notificaciones push de acciones de viaje (tarde 10 jun); ítem 5 Post-MVP cerrado
Checklist Post-MVPAPI push_fcmvalidated; panel /post-mvp-checklistDoc: CUBIK-PUSH-FCM.md

Bitácora de avance — 25 mayo 2026 (Cubik v0.0.97–0.0.98 + diseño pagos)

ÁreaEntregado / decididoNotas
Chat en rutaTexto libre solo en in_progress; presets coordinación + carrusel horizontalcomms-ui.js, match-comms.js v0.0.97
IncidentesDrawer estilo Uber Eats (sin prompt nativo); notificaciones backendincident-ui.js, match-incidents.js v0.0.98
NavegaciónSelector Google Maps / Waze al pulsar «Navegar»live-map-ui.js, google-maps.js
Perfil y shellPestaña Cuenta + botonera Inicio / Opciones / Actividad / Cuentaapp-shell.js, app-shell.css
Contraparte visibleAvatar, nombre y empresa junto al estado del viajetrips-ui.js, enrich en API matches
Anti-bypassBloqueo teléfonos en chat; botón Llamar vía GET …/contactphone-guard.js, contact-ui.js
Twilio ProxyDocumentado en .env.example; número proxy pendiente contratoSemana siguiente
Modelo monetización10% fee embarcador + 5% comisión transportista sobre agreed_price_clp; take rate efectivo 15%Cada rol ve solo su % en UI y API
Cubik SaldoWallet tipo Uber Cash; sin efectivo en términos de usoImplementación próxima semana
Retención escrowAl Marcar en ruta (no al aceptar): retiene flete + 10% embarcadorEvita devoluciones por cancelación pre-salida
Publicar cargaSaldo mínimo 20% del budget_max_clp (garantía de seriedad)No es cobro del flete hasta en ruta
Tier formalidad< $1.000.000: saldo Cubik; ≥ $1M: factura + transferencia/saldo (sin cash)Umbral alineado tier sin efectivo
Checkout UX«Terminar y confirmar» estilo Uber Eats — resumen tarifas explícito por rol; flujo corto solo si flete < $1MPantalla ayuda «Cómo funciona el dinero»
Cubik Plus EmpresaSuscripción mensual futura → descuento % fee embarcador (tipo Uber One)Roadmap post-M2; placeholder en Cuenta

Deploy: Railway main · versión app 0.0.98 · APK cubik-android.apk.

Bitácora de avance — junio 2026 (Cubik Saldo piloto v0.0.99–0.0.104)

ÁreaEntregadoNotas
Cierre viajeDrawer confirmar entrega; push trip_completedv0.0.99
Cubik Saldo pilotoComisiones 10% embarcador + 5% transportista; sección en Cuenta; badges en Mis viajespayment-simulation.js, penalties-ui.js v0.0.100
Performance Mis viajesBatch API matches + precarga al loginv0.0.101
Botón PagarEmbarcador confirma pago simulado; SQL pilot_payment_statusSQL 026 · pilot-pay-ui.js · v0.0.102
Notificaciones pagopilot_payment visible en viajes completados; título «Embarcador pagó el flete»; enlace Mis viajesv0.0.103–0.0.104
UX transportistaBadges «Embarcador pagó» + «Cobro en gestión»; neto a recibirtrips-ui.js
Drawer pago webModal centrado abajo (360px) en desktoppilot-pay-drawer en theme.css
CampanaPanel abre al instante; Cubik Saldo carga en segundo planocomms-ui.js v0.0.104

API: POST /api/matches/:id/pilot-pay (solo embarcador, viaje completed). SQL: RUN_026_pilot_payment.sql.

Deploy: commits 96947cf (v0.0.102) → 7f09d15 (v0.0.104) · Railway main · APK cubik-android.apk.

Limitación piloto: sin movimiento real de dinero; label «Simulación piloto»; completed ≠ pagado hasta que el embarcador pulsa Pagar.

Bitácora de avance — 25 mayo 2026 (v0.0.105 — calibración tarifas)

ÁreaEntregadoNotas
Sugerencia fleteCoeficientes calibrados corredor RM–V vs piloto real e informe logísticomatch-price.js · defaults: $80k + $450/km + $22/kg (antes $120k + $750 + $45)
Ejemplo Renca–La Serena463 km, 12 t → rango sugerido ~$452k–$691k (centro ~$552k vs viaje ~$570k)POST /api/maps/budget-estimate
Config producciónVariables BUDGET_* en Railway / .envVer .env.example y DEPLOY.md
Comparación costosCanvas Cursor + brecha ~1,9–2,5× vs informe PDF (no comparable 1:1)canvases/comparacion-costos-transporte.canvas.tsx
ComisionesSin cambio: 10% embarcador + 5% transportistapayment-simulation.js

Deploy: commit a4336d7 (v0.0.105) · Railway main · comisiones piloto sin cambio.

Bitácora de avance — 25 mayo 2026 (v0.0.106 — UX urgencia y emparejar)

ÁreaEntregadoNotas
Urgencia al publicarMensaje dinámico Normal / Urgente / Flexible (copy comercial, piloto honesto)load-budget-ui.js
Sugerencias automáticas«Usar en Paso 2» vs «Crear propuesta ya» + texto explicativoapp.js
Oferta transportistaBotón grande «Enviar propuesta» en emparejamientos activostheme.css, input ancho

Bitácora de avance — junio 2026 (v0.0.107–0.0.125 — QA, Android y comercial)

ÁreaEntregadoNotas
Login welcome APKFix sintaxis auth-ui.js + pointerup en botones Comenzarv0.0.125 · web prod y bundle Android
QA automatizadoPlaywright (Pixel 5), 14 unit tests, workflow GitHub QA, smoke prod Railwaye2e/, tests/, .github/workflows/qa.yml
Laboratorio QAPanel gráfico /qa-lab — tortas, barras, catálogo de pruebasnpm run qa:lab · ver QA-AUTOMATIZADO.md
Android APKcap:sync:bundle, verify bundle, android:install, APK en DescargasRemoto = UI Railway; bundle = release planificada
NotificacionesArchivo al cerrar/cancelar viaje; historial separado de activosnotification-visibility.js · emparejamientos cerrados fuera de activos
Plan comercialPiloto 25 empresas + 50 transportistas; escala 50+/200 camiones; híbrido vs nativoCanvas cubik-plan-native-escala.canvas.tsx · PLAN-COMERCIAL-PILOTO.md

Deploy: commits 71de18570723d1 · Railway main · presentación comercial jun 2026.

Modelo de monetización, Cubik Saldo y checkout (diseño may 2026)

Estado jun 2026: piloto operativo (v0.0.100–0.0.104) con comisiones 10/5 y flujo pago post-completado simulado. Pendiente producción: wallet real, ledger, retención al «En ruta», recarga pasarela. GMV piloto no genera ingreso real (solo simulación en UI).

Comisiones (take rate dual)

Rol%BaseVisibilidad
Embarcador10%agreed_price_clpSolo ve «Servicio Cubik (10%)»; no ve el 5% del transportista
Transportista5%agreed_price_clpSolo ve «Comisión Cubik (5%)»; no ve el 10% del embarcador
Plataforma (admin)15% efectivoGMV fletePanel admin: SHIPPER_FEE_PERCENT=10, CARRIER_FEE_PERCENT=5

Ejemplo flete $1.200.000: embarcador retiene/paga $1.320.000; transportista recibe $1.140.000; ingreso Cubik $180.000.

agreed_price_clp = monto negociado en oferta; comisiones se aplican después, no inflan el precio mostrado al aceptar.

Flujo de dinero (Cubik Saldo)

  1. Publicar carga: wallet_balance ≥ 0,20 × budget_max_clp.
  2. Aceptar match: aviso «El pago se retiene al marcar En ruta»; sin escrow aún.
  3. Marcar en ruta: retiene agreed_price_clp × 1,10 del embarcador; si saldo insuficiente → bloqueo + notificación al embarcador.
  4. Completar viaje: libera al transportista agreed_price_clp × 0,95; acredita comisiones a Cubik.
  5. Cancelación / devolución: crédito en Cubik Saldo (no cash); multas según política existente.

Tiers de formalidad (sin efectivo)

TramoMonto acordadoMétodo
A — PYME rápido< $1.000.000Cubik Saldo (+ transferencia para recargar)
B — Estándar B2B≥ $1.000.000Factura + saldo Cubik / transferencia registrada
C — Corporativo (futuro)> $1.500.000 o valor carga altoFactura obligatoria + escrow extendido

Umbral $1M alinea checkout corto (tipo Uber Eats imagen 1) vs resumen tarifas obligatorio (imagen 2).

Pantallas UX (referencia Uber Eats)

PantallaEmbarcadorTransportista
Confirmar flete (< $1M)Mapa ruta + opciones simples + «Siguiente»
Terminar y confirmar (siempre)Flete + Servicio 10% + total al en rutaFlete − Comisión 5% = neto a recibir
Cuenta → Cubik Saldo«Cómo funciona el dinero» (4 pasos + ejemplo)Misma ruta, copy solo 5%
Cubik Plus Empresa (futuro)Banner ahorro mensualidad vs % (tipo Uber One)Plan carrier opcional post-M2

Implementación técnica — piloto (hecho v0.0.100–0.0.104)

Implementación técnica — producción (pendiente)

Próxima etapa (jun 2026)

  1. P0 — Presentación comercial (jun): demo prod + APK remoto; pitch piloto 25 embarcadores + 50 transportistas.
  2. P0 — Piloto M2: 20 viajes completed corredor RM ↔ Valparaíso/San Antonio.
  3. P0 — Nativo lite: GPS background (Capacitor/plugin) si el piloto lo exige — sin rewrite UI.
  4. P1 — Wallet real + escrow en ruta (piloto 10/5 ya validado en simulación).
  5. P1 — Twilio Proxy: llamadas enmascaradas (botón Llamar ya en v0.0.98).
  6. P0 — Dominio + Resend: comprar variante Cubik; verificar DNS; EMAIL_FROM — bloqueante correo piloto.
  7. P2 — Push FCM: Cerrado — segundo plano, notificaciones de acciones.
  8. P2 — Contraseña fuerte + cambio en APK: Cerrado v0.0.128.
  9. P2 — Escala 50+/200: presupuesto Maps + infra (~USD 2.1k/mes) antes de marketing masivo.

Detalle estratégico: PROXIMOS-PASOS-ESTRATEGIA.md · Plan comercial: PLAN-COMERCIAL-PILOTO.md · QA: QA-AUTOMATIZADO.md · UX app: CUBIK-APP-UX.md

Parte II — Stack tecnológico por capas

Numeración de abajo hacia arriba y hacia el exterior (referencia en incidentes y actas).

Capa 01 — Node.js

Rol: runtime del servidor (src/server.js). Engines: ≥ 20. Problemas: puerto ocupado, versión distinta a prod → alinear Railway y package.json.

Capa 02 — Express.js

Rol: HTTP, JSON, estáticos public/, documentación /docs/, rutas /api/*, /health. Archivo: src/app.js.

Capa 03 — API REST

Rol: marketplace — ofertas, cargas, matches, auth, comms, cuenta. Auth: JWT en rutas protegidas. Rutas en src/routes/.

Capa 04 — Supabase (PostgreSQL)

Rol: persistencia; migraciones en supabase/migrations/. Proyecto prod: ljinhegtywixtbzjgjfn. Service role solo en servidor.

Capa 05 — Autenticación (JWT + bcrypt)

Rol: registro/login con email y contraseña; tabla users; roles shipper / carrier. Política contraseña: 8+ caracteres, letra, mayúscula, número (password-policy.js, v0.0.128).

Correo: forgot/reset con Resend en prod; piloto multi-cuenta bloqueado hasta dominio verificado (DOMAIN-AND-EMAIL.md). Pendiente: OAuth Google/Apple — AUTH-AND-EMAIL-ROADMAP.md.

Capa 06 — Lógica de dominio

Rol: src/lib/ — match, cancelación (match-cancel-reasons.js), precio (match-price.js), confianza/carga (cargo-trust.js), multas (penalty-ledger.js, penalty-payment.js, penalty-gate.js, bank-gate.js, payment-proof.js), repositorio.

Capa 07 — Servicios

Rol: src/services/ — Supabase client, comms, integraciones futuras (mapas, pagos).

Capa 08 — Frontend web + app móvil Cubik

Rol: public/ — SPA web + modo app (?app=1, PWA, Capacitor). Shell móvil: app-shell.js, app-shell.css. API remota vía api-base.js cuando UI va en bundle APK. Marca Cubik: brand-config.js, public/brand/.

Android: Capacitor 7, package cl.cubik.logistics, carpeta android/. Scripts: npm run android:apk, android:install:remote, android:verify. Distribución: /probar + APK bundle o remoto.

QA visual: /qa-lab — catálogo y gráficos de pruebas (npm run qa:lab).

Capa 09 — Experiencia producto (paridad Uber)

Rol: flujos, copy y pantallas en public/ alineados a «pedir → match → viaje activo → historial»; roles embarcador/transportista como pasajero/conductor. Piloto y validación solo dentro de esta app, no canales externos.

Capa 10 — Railway

Rol: hosting, variables de entorno, healthcheck /health, deploy desde GitHub main.

Capa 11 — Git y GitHub

Rol: versionado; nunca commitear .env. Workflow CI: .github/workflows/qa.yml (unit + Playwright local + smoke prod en main).

Capa 12 — Documentación HTML

Rol: memoria viva, Gantt y próximos pasos en un solo HTML; export Word vía html-to-docx. Hub: /docs/index.html.

Extensiones planificadas

Capa futuraTecnologíaFase
Mapas / geocodingGoogle Maps / Mapbox2+
Pagos in-appWebpay / Mercado Pago / Stripe Chile — validación tarjeta + cobro multas2.10b (pendiente)
Auth social + emailGoogle OAuth, Apple Sign In, ResendE (pendiente)
KYC / seguroAPIs terceros Chile3

Modelo de datos (resumen)

Entidades: users, vehicles, capacity_offers, load_requests, matches, match_messages, match_notifications, penalty_charges, match_incidents, match_ratings (012–014), trip_events (roadmap).

Calificaciones (012–014): tabla match_ratingsmatch_id, rater_role (shipper|carrier), stars, comment, tags (TEXT[]), tag_band (low|mid|high), rater_user_id (opcional, 014). UNIQUE (match_id, rater_role). En matches: delivery_note, completed_at.

Precio: load_requests.budget_min_clp, budget_max_clp; en matches: copia del rango, carrier_offer_clp, agreed_price_clp, price_status (migración 010).

Confianza / carga (011): en load_requests: cargo_description, declared_cargo_value_clp, has_dispatch_guide, dispatch_guide_folio, requires_cargo_insurance, legal_terms_version, terms_accepted_at. Tabla match_incidents (robo, daño, faltante, atraso, otro). Ver CARGO-TRUST.md y términos HTML.

Estados matches: proposed → (oferta transportista) → accepted (precio aceptado) → in_progress → completed | cancelled.

API REST — contrato MVP (mayo 2026)

MétodoRutaDescripción
GET/healthHealth + versión app
POST/api/auth/registerAlta empresa (shipper/carrier; admin con clave)
POST/api/auth/loginJWT
POST/GET/api/capacity-offersOferta (scope por rol)
POST/GET/api/load-requestsCarga + budget_* + declaración mercadería (términos obligatorios)
PATCH/api/load-requests/:id/budgetEmbarcador amplía rango
POST/api/maps/budget-estimateRango sugerido (km, peso, urgencia)
POST/PATCH/api/matchesPropuesta + estados viaje
PATCH/api/matches/:id/carrier-offerTransportista oferta CLP
PATCH/api/matches/:id/accept-offerEmbarcador acepta precio → accepted
POST/api/matches/:id/mutual-cancelAcuerdo mutuo
GET/api/matches/cancel-optionsMotivos y multas
GET/POST/api/comms/…Chat y notificaciones
GET/api/account/summaryMultas, billetera (bank_accounts[]), tarjetas
GET/POST/PATCH/DELETE/api/account/bank-accounts…Billetera multi-cuenta (v0.0.94)
GET/api/account/chile-banksLista bancos Chile (selector)
PATCH/api/account/bankUpsert cuenta predeterminada (compat legacy)
GET/POST/api/devices/push-status · push-test · push-tokenFCM Android (v0.0.81+)
POST/api/account/penalties/:matchId/claim-paidDeudor declara pago + comprobante (base64)
GET/api/account/penalties/:matchId/payment-proofImagen comprobante (JWT participante)
POST/api/account/penalties/:matchId/confirm-paymentAcreedor confirma recepción
POST/api/account/penalties/:matchId/dispute-paymentAcreedor rechaza (nota obligatoria)
POST/api/account/penalties/:matchId/mark-paidAdmin / moderador cierra multa
POST/GET/api/matches/:id/incidentsReportar / listar incidentes (JWT, participantes)
GET/api/matches/rating-tags/catalogCatálogo chips por rol (JSON)
POST/api/matches/:id/rateCalificar viaje completado (stars, comment, tags); 409 si ya calificó
GET/api/matchesLista matches + can_rate, my_rating, reputación contraparte

Reglas de negocio MVP

Seguridad y cumplimiento

Estructura del repositorio

uber-truck/ src/server.js, app.js, routes/, services/, lib/ supabase/migrations/ public/ ← UI + brand/logo.png docs/ ← memoria HTML (este archivo) canvases/ ← estado de avance (Cursor)

Fin del documento — v4.4 (25 may 2026): paridad MVP cerrada; FCM + contraseña cerrados; dominio Resend P0; backlog vivo + Gantt 16 sem; foco dominio → demo → 25/50 → M2.