Ruteo core/daily por sufijo
En el modelo de rolling databases, los datos de
un local se reparten en varias bases CouchDB: una base core (catálogo y datos
estables) y una base daily por día de negocio. El dispositivo no conoce ni
envía el nombre físico de ninguna de esas bases: solo envía un sufijo lógico
(core o daily_<YYYYMMDD>), y el proxy de tables-socket compone el nombre
físico completo a partir del token.
Por qué un sufijo y no el nombre completo
Sección titulada «Por qué un sufijo y no el nombre completo»El nombre físico de una base depende de tres datos que el dispositivo no debe fijar por su cuenta:
- el
dbPrefix(entorno de deploy:testing/staging/prod), - el
companyId, - el
restaurantId.
companyId y restaurantId viven en el token JWT (resueltos por el
auth.middleware de tables-socket, no por el cliente), y el dbPrefix es
configuración del servidor. Si el dispositivo enviara el nombre físico completo,
el proxy lo duplicaría o, peor, lo mis-rutearía al empezar con _ (prefijo
vacío). Manteniendo el nombre físico en un solo lugar —el proxy— el cliente y el
servidor hablan siempre el mismo sufijo lógico.
El contrato de nombres
Sección titulada «El contrato de nombres»El parser y el constructor de nombres viven en un archivo de contrato
idéntico en ambos repos (tables-sdk/src/contracts/day-db-naming.ts y
tables-socket/src/contracts/day-db-naming.ts). Que el dispositivo y el servidor
parseen idéntico es crítico: un parser que difiera mis-rutea o dropea la base
equivocada.
El formato físico es:
core: <dbPrefix>_<companyId>_<restaurantId>_coredaily: <dbPrefix>_<companyId>_<restaurantId>_daily_<YYYYMMDD>Donde dbPrefix es el entorno (testing / staging / prod). Hay una sola base
daily por día (agrupa todos los tipos de documentos dinámicos), sin epoch: la
base de un día se crea una vez (idempotente).
Cómo compone el nombre el proxy
Sección titulada «Cómo compone el nombre el proxy»Toda lectura/escritura del cliente contra CouchDB pasa por el proxy de
tables-socket en /couchdb/* (autenticación HMAC; el cliente nunca accede a
CouchDB directo). El proxy toma el sufijo lógico de la ruta y lo expande:
buildTargetPath(originalPath, companyId, restaurantId) { let path = originalPath.replace(/^\/couchdb\/?/, '').replace(/^\//, ''); // path === 'core' | 'daily_20260622' | '_changes' | ... return `/${this.dbPrefix}_${companyId}_${restaurantId}_${path}`;}-
El dispositivo arma una petición CouchDB cuyo segmento de base es el sufijo lógico (
coreodaily_<YYYYMMDD>). -
El proxy resuelve
companyIdyrestaurantIddesde el token (AuthInfo), no desde la ruta. -
El proxy antepone el
dbPrefixde su configuración y compone el nombre físico completo, reenviando la petición a CouchDB con los headers HMAC.
Lado dispositivo: qué sufijo usar
Sección titulada «Lado dispositivo: qué sufijo usar»En el SDK, Database decide el sufijo de la base core según el flag
rollingDb del tenant:
- con
rollingDbactivo, el sufijo efectivo escore; - sin él (modo legacy / CORE-only), sigue siendo
tables-prod.
El SDK construye la URL remota reemplazando solo el último segmento de la ruta por
el sufijo lógico (_coreRemoteUrl → .../core), nunca por el nombre físico. El
cambio toma efecto al (re)inicializar el dispositivo; cambiar el flag en vivo
requiere re-bootstrap (re-login o reinicio).
El manifest expone el sufijo, no el nombre físico
Sección titulada «El manifest expone el sufijo, no el nombre físico»¿Y de dónde saca el dispositivo el sufijo daily_<YYYYMMDD> correcto del día? Del
documento singleton day_manifest, que el servidor escribe en la base core
(derivado de la tabla SQL day_databases) y el dispositivo lee. Es la fuente
server-authoritative y offline-capable de qué base daily está activa y
cuáles montar como overlay; reemplaza al reloj del dispositivo para decidir el día
de negocio. La dirección es única: SQL → core; el dispositivo nunca lo escribe.
Coherente con todo lo anterior, el manifest expone sufijos lógicos, no nombres físicos:
// tables-socket — buildCoreManifest (day-db-lifecycle.service.ts)const overlays = rows .filter((r) => r.state === 'DRAINING') .map((r) => ({ businessDay: r.businessDay, dbName: `daily_${r.businessDay}` }));Así, dispositivo y proxy hablan el mismo sufijo (daily_<YYYYMMDD>) y el nombre
físico vive en un solo lugar. La columna day_databases.dbName en SQL sí guarda el
nombre físico completo, pero solo para las operaciones server-side.
Resumen
Sección titulada «Resumen»- El dispositivo envía solo el sufijo lógico:
coreodaily_<YYYYMMDD>. - El proxy compone el nombre físico
<dbPrefix>_<companyId>_<restaurantId>_<sufijo>tomandocompanyIdyrestaurantIddel token ydbPrefixde su configuración. - El
day_manifest(encore, escrito por el servidor) le dice al dispositivo qué sufijodailyusar; también expone sufijos lógicos, no nombres físicos. - El contrato
day-db-naming.tses idéntico en SDK ytables-socketpara que ambos parseen igual.
Más sobre el ciclo de vida de las bases y la rotación diaria en rolling databases; sobre el proxy de CouchDB, JWT y HMAC en infraestructura.