Compartir notas sin conflictos de fusión

Product

Antes, en cada espacio de trabajo de Notez había exactamente una persona. Desde la v0.3.0 pueden tener varias: invitas a alguien por correo y compartes con esa persona las notas, las etiquetas, los tableros y el chat de IA que trabaja sobre todo ello.

Lo interesante es lo que dejé fuera.

La función que todos piden primero

"¿Pueden dos personas editar la misma nota a la vez?"

En el sentido de Google Docs (dos cursores en un párrafo, caracteres que se intercalan a medida que se escriben), no. Es un problema difícil de verdad, y resolverlo bien exige CRDT o transformaciones operacionales, una conexión persistente por cada documento abierto y reescribir cómo se guarda una nota: ya no como un documento, sino como un flujo de operaciones que se reproducen.

Es una buena función. También es casi un producto entero por sí sola, y habría retrasado meses la posibilidad de compartir para cubrir un caso que, en una app de notas, es raro. La gente no suele escribir el mismo párrafo a la vez. Escribe notas distintas, o la misma nota en momentos distintos.

Así que diseñé la función para lo que pasa de verdad, e hice que el caso raro fuera seguro en lugar de fluido.

Lo que pasa de verdad

Tres cosas, por orden de importancia.

Quieres saber que hay alguien más. Si abres una nota que un compañero tiene abierta, su avatar aparece junto al estado de guardado. Se actualiza cada pocos segundos y desaparece más o menos un minuto después de que cierre la nota.

Es deliberado: muestra presencia, no indicadores de escritura. Responde a "¿hay alguien más aquí ahora mismo?", la pregunta que te hace esperar o seguir adelante. Es un hash de Redis por nota con un TTL de 60 segundos y un sondeo periódico, sin WebSocket ni reparto de suscripciones. La función entera son unas pocas docenas de líneas, y si Redis deja de estar disponible un momento, la nota se sigue abriendo y guardando.

Quieres saber quién cambió algo. El estado de guardado ahora dice Editado por Sam · hace 4 minutos cuando el último cambio no fue tuyo, y muestra solo la hora cuando lo fue. Junto con los 30 días de historial de versiones que ya guarda cada nota, "¿cómo era esto antes de que Sam lo tocara?" tiene respuesta.

La autoría de los cambios resultó ser lo que la gente más quería de la colaboración, y cuesta dos columnas.

No quieres perder trabajo. Esta es la que importa.

Rechazar el guardado

El fallo de compartir de forma ingenua es silencioso y total: abres una nota, editas diez minutos, guardas, y tu versión reemplaza la que tu compañero guardó hace ocho minutos. No sale ningún error. Su trabajo simplemente desaparece, y ninguno de los dos se entera hasta que alguien nota que falta un párrafo la semana siguiente.

Ahora Notez da a cada nota un número de versión. Cuando tu editor carga una nota, recuerda la versión que vio, y cada guardado envía ese número de vuelta. La actualización se ejecuta así:

SQL
UPDATE "Note" SET ... WHERE id = $1 AND "contentVersion" = $2

Si alguien guardó mientras tanto, la versión ya no coincide, la cláusula WHERE no encuentra ninguna fila y la escritura no se produce. Ves un aviso con el nombre de quien cambió la nota y un botón Recargar.

El detalle importante es que la protección está en la cláusula WHERE y no en un if encima. Comprobar y luego escribir deja una ventana entre la comprobación y la escritura; es pequeña, pero dos guardados que llegan en el mismo instante son justo el caso en que la protección tiene que aguantar. Al hacer que la versión forme parte de la condición de la actualización, decide la base de datos, de forma atómica, y el segundo en escribir pierde.

Perder es el resultado correcto. La alternativa a rechazar una escritura es adivinar cómo combinar dos versiones de un párrafo, y adivinar mal es peor que un error honesto, porque una combinación equivocada parece que funcionó.

Lo que no hice, a propósito

  • Sin permisos por nota. El acceso es por espacio de trabajo. Todos los invitados pueden leer todo lo que hay en él, incluida la papelera. Las ACL por nota suponen una comprobación de permisos en cada ruta de lectura, una interfaz para gestionarlas y una carga de soporte de gente que no entiende por qué no ve una nota. Si necesitas un límite, crea un segundo espacio de trabajo: son gratis y están totalmente aislados.

  • Sin comentarios. Un hilo de comentarios es una pequeña red social. Ahora no.

  • Sin cursores en vivo. Ver arriba.

  • Sin cobro por puesto. Los miembros no necesitan su propio plan. Los puestos salen del plan del propietario: 3 en el plan Gratis, 10 en Pro y 25 en Ultra, y todo lo que guarda el espacio de trabajo cuenta para el límite del propietario.

Dónde está el límite

Se comparte por espacio de trabajo, y los espacios de trabajo ya eran la frontera de aislamiento en Notez: el chat de IA solo ve el actual y una clave MCP está ligada a uno solo. Esa propiedad se mantiene al compartir: invita a un compañero a Trabajo y no obtendrá nada de Personal, ni en la búsqueda, ni a través de la IA, ni con una clave.

Eso se aplica en el servidor, en cada petición, y es la razón por la que elegí el espacio de trabajo como unidad para compartir en lugar de inventar una nueva.

Si lo has guardado todo en un solo espacio de trabajo y ahora quieres compartir una parte, primero mueve esas notas a un espacio de trabajo propio y después invita.


Los detalles, en Compartir un espacio de trabajo con otras personas. Todo lo que incluyó la versión: v0.3.0.

Sigue leyendo