Quiero que me preguntes qué requerimientos estoy necesitando cubrir para recomendarme una solución de sincronización frontend-backend, con lectura y grabado en base de datos.
Perfecto. Antes de recomendar una arquitectura (REST, Inertia, Server Actions, WebSockets, polling, CQRS, cache local, sincronización optimista, etc.), necesito entender algunos aspectos de tu caso de uso.
Respondé lo que puedas:
1. Frecuencia de actualización
- ¿Los datos cambian sólo cuando el usuario hace acciones?
- ¿O pueden cambiar por otros usuarios/procesos mientras la pantalla está abierta?
2. Tiempo real
- ¿Necesitás que los cambios aparezcan casi instantáneamente?
- ¿Cuántos segundos de demora serían aceptables?
3. Volumen de datos
-
¿Cuántos registros suele manejar una pantalla?
- decenas
- cientos
- miles
- decenas de miles
4. Patrón de uso
- ¿Hay muchas más lecturas que escrituras?
- ¿O las escrituras son frecuentes?
5. Consistencia
- ¿Es crítico que el usuario vea siempre el estado más reciente de la base de datos?
- ¿O tolerás que vea datos levemente desactualizados durante algunos segundos?
6. Conflictos
- ¿Puede ocurrir que dos usuarios modifiquen simultáneamente la misma entidad?
- Si ocurre, ¿qué debería pasar?
7. UX
- ¿Querés que las modificaciones se reflejen instantáneamente en la UI (optimistic updates)?
- ¿O preferís esperar la confirmación del backend?
8. Navegación
-
¿Tu aplicación es principalmente:
- formularios
- CRUD administrativo
- dashboard
- editor complejo
- tiempo real colaborativo
- otra cosa?
9. Stack actual
-
¿Qué usás exactamente?
- React
- Inertia
- Laravel
- Vite
- TypeScript
- otra cosa
10. Estado frontend
-
¿Actualmente usás algo como:
- Context
- Zustand
- Redux
- React Query / TanStack Query
- SWR
- nada
11. Offline
- ¿La aplicación debe seguir funcionando sin conexión y sincronizar después?
12. Prioridades
Ordená estas prioridades:
- simplicidad
- rendimiento
- consistencia
- tiempo real
- facilidad de mantenimiento
- escalabilidad
13. Caso concreto
Describime una pantalla representativa:
"Tengo un odontograma. El usuario modifica piezas dentales, se guardan en Laravel y otros usuarios pueden verlo."
o el caso que corresponda.
Con esas respuestas puedo recomendarte una estrategia concreta de sincronización frontend ↔ backend ↔ base de datos en lugar de una lista genérica de tecnologías.
Con lo que describís, yo no usaría nada sofisticado (WebSockets, Zustand, Redux, CQRS, sincronización offline, etc.). Estarías pagando complejidad sin obtener beneficios.
Tu caso tiene varias características muy favorables:
- El odontograma completo es un único agregado lógico.
- El JSON es pequeño (decenas o cientos de KB como mucho).
- Las escrituras son poco frecuentes.
- No necesitás tiempo real.
- Priorizás simplicidad y mantenimiento.
- Preferís esperar la confirmación del backend.
- Querés consistencia fuerte.
Lo que implementaría
Backend
Una tabla:
odontogramas
-----------
id
version
contenido_json
updated_at
donde contenido_json es esencialmente el JSON que mostraste.
Frontend
Estado local:
const [odontograma, setOdontograma] =
useState<Odontograma>(props.odontograma)
const [guardando, setGuardando] =
useState(false)
Guardado
Cuando el usuario confirma una modificación:
setGuardando(true)
await router.post(
route('odontograma.guardar'),
odontograma
)
await recargar()
setGuardando(false)
donde:
async function recargar() {
router.reload({
only: ['odontograma']
})
}
o equivalente con fetch.
Lo importante: versionado optimista
Veo un posible problema:
"si dos usuarios intentan modificar la misma entidad no hay problema en bloquear al segundo"
Entonces agregaría:
{
version: 37,
...
}
al JSON.
Al guardar:
if ($request->version !== $odontograma->version) {
abort(409);
}
Si alguien guardó antes:
Usuario A abre v37
Usuario B abre v37
Usuario A guarda
→ v38
Usuario B guarda
→ 409 Conflict
y mostrás:
El odontograma fue modificado por otro usuario.
Recargue la pantalla.
Mejor todavía: lock pesimista
Como dijiste:
"no hay problema en bloquear al segundo"
haría esto.
Al abrir:
odontograma_locks
-----------------
odontograma_id
usuario_id
expires_at
El primer usuario adquiere el lock.
El segundo ve:
El odontograma está siendo editado por Juan Pérez.
y entra en modo lectura.
Qué NO usaría
No usaría:
- Redux
- Zustand
- MobX
- WebSockets
- SSE
- React Query
- SWR
- Event Sourcing
porque ninguna de esas herramientas resuelve un problema que realmente tengas.
Lo que sí me preocuparía
Al mirar el JSON veo que el odontograma es básicamente un documento.
Yo evitaría hacer:
POST agregar-caries
POST borrar-caries
POST agregar-fusion
POST agregar-diastema
POST agregar-protesis
etc.
Terminarías con decenas de endpoints.
Preferiría:
PUT /odontograma/:id
enviando el documento completo.
await axios.put(
`/odontograma/${id}`,
odontograma
)
El backend valida y persiste.
La complejidad queda concentrada en un único lugar.
Para tu stack (Laravel + Inertia + React + TS) mi recomendación concreta sería:
- Mantener el odontograma completo como un único documento JSON.
-
Estado local React simple (
useStateouseRefsegún corresponda). - Guardado explícito al confirmar cambios.
- Recarga desde backend después del guardado exitoso.
- Lock pesimista de edición por usuario.
-
Campo
versionpara detectar inconsistencias si el lock falla.
Eso te da una solución muy consistente y extremadamente simple de mantener.
No hay comentarios:
Publicar un comentario