Un pase, una persona
Nuevo User.customerCode: MG- + 6 caracteres sin 0/O/1/I, @unique,
con backfill de los clientes existentes. Es el código que se lee en voz alta en el mostrador.
El pase en tu Wallet es tu única identidad con Mogos: un código, un QR, una persona. Lo muestras al llegar al Almacén Caracas, lo escaneamos y te llevas tus bultos.
Hoy el retiro del locker es un trámite de papel disfrazado de software. El admin tiene
una solicitud con texto libre y un botón «Completar»; complete() cambia el estado
y factura el fee, pero no sabe quién se llevó qué. Y del lado del cliente,
/account/storage sigue detrás de «Próximamente» desde mayo.
Sin guard de estado: dos clics, dos fees.
Nadie registra completedById ni la hora real de la entrega.
Ni receptor, ni cédula, ni firma, ni foto. La prueba
de entrega del flete existe (DeliverySignature); la del locker, no.
«cajas de repuestos» no es una entrada.
Las StorageEntry nunca pasan a WITHDRAWN y el locker sigue lleno en el sistema.
Se entrega primero y se cobra después; la mensualidad pendiente ni aparece en pantalla.
«Próximamente» desde el 19 de mayo. El modal promete «sin costos fijos» mientras el seed cobra tiers mensuales.
El esqueleto es real y sólido: módulo apps/api/src/storage/ completo (6 modelos, 6 controllers,
cotización polimórfica entityType: STORAGE, auditoría en las 6 tablas), pasarela embebida
PaymentPortalSheet, qrcode y CardsModule listos para reusar, y el QR del
flete que ya se escanea en Caracas. Esta propuesta termina lo que hay; no lo reemplaza.
Un pase por persona, con los mismos datos en Apple Wallet y Google Wallet. El código
MG-7F3K2Q es el nombre público del cliente; el QR lleva un token opaco que solo el
mostrador puede resolver. Marino de fondo, wordmark blanco y el punto rojo como remate del código:
la credencial se ve Mogos a un metro de distancia.
Mismos datos en las dos plataformas · el QR codifica MOG1.H9V4XN2B8RC6WJ5TQ3ZD7K, nunca el código ni la cédula
Nuevo User.customerCode: MG- + 6 caracteres sin 0/O/1/I, @unique,
con backfill de los clientes existentes. Es el código que se lee en voz alta en el mostrador.
El código de barras lleva MOG1.<token> — nunca un UUID ni la cédula. Solo
POST /wallet/verify (staff) lo resuelve. Revocable: Apple voided + push,
Google state: INACTIVE.
locations[] en Apple y Nearby Passes en Google: al llegar a WH-CCS-001
el teléfono ofrece el pase en la pantalla de bloqueo. El cliente no busca nada.
NFC en Apple exige un entitlement que se pide caso por caso. El QR no pide permiso a nadie, funciona en las dos plataformas y en una tarjeta impresa.
Estás cerca del Almacén Caracas. Muestra tu pase para retirar.
El pase lleva una sola ubicación, la del Almacén Caracas. Al acercarse, el teléfono lo sugiere en la pantalla de bloqueo; un toque y el QR está listo para el mostrador. Sin notificaciones push, sin app, sin buscar en el correo.
Es la misma credencial para todo lo que tenga listo: cajas de un flete
READY_FOR_PICKUP y bultos del locker.
Cuatro pasos y ninguno requiere instalar nada. La página detecta el dispositivo y ofrece la Wallet que corresponde; en escritorio, un QR que abre la misma página en el teléfono.
Tu Mogos ID está listoAgrégalo a tu Wallet: es tu credencial para retirar en Caracas.
En Chrome para iPhone ábrelo en Safari.
Enviarlo por WhatsAppÁbrelo en tu teléfono
Escanea con la cámara: es la misma página, abierta en tu teléfono y con tu sesión. Allí detecta el dispositivo y te ofrece la Wallet que corresponde.
¿Sin smartphone? Te imprimimos una tarjeta con el mismo QR.
No instala .pkpass. La página lo detecta y muestra «Ábrelo en Safari» con el enlace
listo para copiar; el email y el WhatsApp abren en Safari por defecto.
Se imprime una tarjeta PNG con el mismo QR — reusa CardsModule, con su throttle.
Mismo token, misma verificación en línea.
Se revoca y se reemite desde /account/mogos-id o por un operador. El token cambia,
el código no: el pase viejo deja de abrir al instante.
El locker sale de «Próximamente» con precio real: por uso hasta 10 CBM, plan mensual desde 10. Cuatro pantallas y ningún paso que el cliente no pueda terminar solo — reservar, ver sus bultos, retirar los que quiera, pagar el fee antes de ir y saber cuándo están en mostrador.
Reservar mi lockerPor uso hasta 10 CBM; desde 10 CBM, plan mensual.
¿Cuánto espacio?
Por usoMi lockerMOGOS-ALM-20260821-0003 · Almacén Caracas
Tus bultos
3Retirar bultosElige qué te llevas. Pagas el fee y te avisamos cuando estén en mostrador.
¿Qué retiras?
2 de 3Al entregar se liberan 3.7 CBM de tu locker.
Pagado. Te avisamos cuando tus bultos estén en mostrador
Al llegar, muestra tu Mogos ID en Caracas.
Reservar · Mi locker · Retirar · Pagado. El precio que ve el cliente es el del seed; el fee de retiro se paga antes de ir o en el mostrador. «Retiro listo» llega después, cuando los bultos ya están en mostrador.
Cuando el almacén pone los bultos en mostrador, el cliente lo sabe por tres canales a la vez.
La nota de entrega en PDF — quién retiró, qué bultos, firma y hora — llega por WhatsApp y queda en la cuenta.
Desde el cliente, mientras el retiro no esté entregado. Si ya pagó el fee, queda como saldo a favor.
«Pagas por uso hasta 10 CBM; desde 10 CBM, plan mensual». La versión actual promete «sin costos fijos», que contradice los tiers del seed (10–15 $400 · 15–20 $750 · 20–30 $1,000 · 30+ negociado).
El mostrador es la web del admin con la cámara del equipo — una ruta nueva, /pickups,
y ninguna app que instalar. El operador escanea el Mogos ID, ve todo lo que la persona tiene listo
(fletes y locker en una sola lista), cobra si hay saldo y entrega bulto por bulto.
El QR lleva un token opaco: el mostrador lo resuelve con POST /wallet/verify. Si el pase está revocado, no abre.
La foto del perfil, si existe, aparece en lugar de las iniciales. Un pase revocado no llega a esta pantalla: el escaneo avisa «pase no válido».
Una sola lista para la misma persona: fletes en READY_FOR_PICKUP y retiros del locker en READY. El operador marca qué se lleva hoy.
Entregar se habilita al registrar el pago. Si el cliente pagó desde el portal, esta pantalla ya sale al día.
El pago entra en la misma cotización del retiro (entityType: STORAGE) y el recibo se genera solo. Mensualidad y saldo del flete se revisan en el mismo paso.
Seis pasos, una pantalla. Escanear → identidad → qué tiene listo → saldo → bultos → quién
retira y firma → Entregado. Las entradas pasan a WITHDRAWN y el CBM se libera en la
misma transacción que crea el Handover.
Lo que quedó decidido con el usuario, y la consecuencia de cada regla en el sistema.
READY_FOR_PICKUP
y bultos del locker. Consecuencia: nuevo User.customerCode (MG- + 6 caracteres sin 0/O/1/I,
@unique) con backfill de los clientes existentes.WH-CCS-001 (La Florida), el único almacén con supportsStorage en
producción. El pase lleva esa única ubicación en locations[]./pickups en el admin, con la cámara del equipo. Sin app nueva, sin pistola:
el QR se lee con cualquier webcam o teléfono del operador.nav-feature-flags.ts deja de esconder /account/storage con este proyecto. Reservar,
guardar, retirar y pagar quedan a la vista del cliente.entryCode; el operador las confirma una a una; al entregar
pasan a WITHDRAWN y el CBM se libera. Nueva pivote StorageWithdrawalItem.MOG1.<22 chars base32 de Crockford>, nunca UUID ni cédula. Verificación en línea obligatoria en
POST /wallet/verify (solo staff). Revocable: Apple voided + push, Google state: INACTIVE.shipping-mark-label-spec.ts:36): un nombre, un concepto.Handover (flete | retiro de locker), con receptor, cédula,
receivedBy, firma, fotos, operador y almacén. La firma remota /f/<token> sigue viva para
entregas sin mostrador.Tres entidades nuevas, un estado nuevo y un ciclo de vida que hoy no existe. Todo lo demás es terminar y sanear lo que ya está escrito.
User.customerCode — MG-XXXXXX, @unique, backfill.WalletPass — token, plataforma, serial, estado, revokedAt; WalletPassDevice en fase 4.StorageWithdrawalItem — pivote retiro ↔ entrada; la entrada pasa a WITHDRAWN al entregar. Fase 2, con el mostrador.READY del retiro: los bultos están en mostrador. Fase 2.Handover — receptor, cédula, firma, fotos, operador, almacén; apunta a flete o a retiro.activate / suspend / terminate — hoy nada pasa una reserva de PENDING a ACTIVE.TrackedCronService: escribe currentBalance, nextBillingDate, billingCycleDay.PER_USE se cobra al retirar: días × CBM × $1.50, en la misma cotización que el fee.calculatePerUseCharge y calculateProRataAdjustment consiguen caller (el pro-rata, solo para el cierre).GET /storage/reservations* con scoping por actor; POST fuerza userId.GET /withdrawals/code/:code deja de usar @UUIDParam (hoy siempre 400).queryKeys.storage en los 3 hooks de mutación.complete() y diálogo de confirmación en la aprobación inline.En palabras: un User tiene un WalletPass y varias
StorageReservation; cada reserva guarda varias StorageEntry. Una
StorageWithdrawalRequest lista sus bultos en StorageWithdrawalItem, uno por
entrada. El Handover cierra un Freight o un retiro de locker — uno u otro —
con receptor, cédula, firma y operador.
Cinco fases, cada una con una superficie de verificación propia. Las fases 0 y 3 no tocan el esquema; la fase 4 puede esperar a que el mostrador ya esté rodando.
Scoping IDOR en /storage/reservations*, userId forzado al actor, /code/:code sin
@UUIDParam, keys de cache alineadas, botones muertos resueltos, guard de estado en complete()
y diálogo de confirmación en la aprobación. Solo código; nada de esquema.
User.customerCode + backfill, WalletPass, pase Apple generic firmado con
passkit-generator, GenericObject + JWT «Save to Wallet» en Google, página
/account/mogos-id con detección, email + WhatsApp «Tu Mogos ID está listo», POST /wallet/verify.
Ruta /pickups en el admin con cámara, identidad verificada, lista unificada de fletes y locker,
bloqueo por saldo con pago en el acto, Handover con receptor + cédula + firma + foto, nota de
entrega PDF por WhatsApp y email. Entregar bultos exige la pivote: StorageWithdrawalItem y el
estado READY del retiro entran acá, con el mostrador que los usa.
Sale de Próximamente. Reservar con precio real, el cliente elige sus bultos por entryCode, ciclo de
vida activate / suspend / terminate, cron mensual con TrackedCronService,
PER_USE cobrado al retirar y los cuatro avisos nuevos. Escribe columnas que ya existen
(currentBalance, nextBillingDate, billingCycleDay): ninguna tabla nueva.
Web service de Apple + APNs con WalletPassDevice, patch en tiempo real en Google, «N listos para
retirar» que cambia solo cuando llega un flete o un retiro pasa a READY, revocación por push.
| Prerrequisito | Dueño | Nota |
|---|---|---|
| Apple Developer Program | Mogos | Cuenta de la empresa, $99/año. Sin ella no se firma ningún pase. |
| Pass Type ID + certificado anual | crescō | Con la cuenta de Mogos; el certificado vence cada 365 días y WWDR G4 acompaña. |
| Google Wallet Console + Business Profile | Mogos | Demo mode inmediato; publicar toma hasta 2 días hábiles. |
| Service account + secretos en Render | crescō | Claves de Google, certificado Apple y passphrases en el Environment Group del API. |
| Assets del pase | crescō | Logo, icono y hero a @1x/@2x/@3x desde los vectores de la casa; nada se dibuja a mano. |
| Política de mostrador | Mogos | Quién puede entregar, qué pasa con un pase ajeno, horario de retiro y manejo de efectivo. |
Seis cosas que se discutieron y quedan fuera — con la razón, para que nadie las vuelva a abrir sin saber por qué se cerraron.
TIER_CHANGE_PLAN va al backlog; calculateProRataAdjustment solo se usa al cerrar.WH-CCS-001 tiene supportsStorage; el pase lleva una sola ubicación.El Mogos ID convierte el retiro en el momento más claro de la relación con Mogos: el cliente muestra, el operador escanea, el sistema sabe qué se llevó, quién y cuándo. Y el locker, por fin, deja de ser «Próximamente».