Apéndice: estructuras de datos mínimas (manifiesto, fragmento y estado)

Este apéndice ofrece recomendaciones de estructuras de datos mínimas para la «fragmentación en paralelo + transferencia reanudable + reintentos idempotentes». El objetivo es permitir una concurrencia de alto rendimiento y una recuperación fiable tras los fallos, sin transacciones complejas.

Principios generales

  • Objetos grandes frente a estado pequeño: los fragmentos y el manifiesto son objetos grandes almacenados en el almacenamiento de objetos; el estado es pequeño y se guarda en un almacén de estado.
  • Claves únicas e idempotencia: un fragmento DEBE poder direccionarse de forma única mediante (transferId, fileId, chunkIndex) para permitir retransmisiones idempotentes.
  • Capacidad de recuperación: el estado DEBE expresar el «conjunto completado» para que la recuperación pueda omitir las partes ya completadas.
  • Sin filtración de datos sensibles: las claves de objeto y el estado DEBERÍAN evitar incrustar campos sensibles como el correo electrónico o los nombres de archivo originales (que estén cifrados o no depende de tu política de privacidad).

A.1 Campos mínimos del manifiesto

El manifiesto es el «punto de entrada único» del receptor para la descarga y el reensamblado. Recomendaciones mínimas:

  • manifestVersion: DEBE. Se usa para las actualizaciones de compatibilidad (p. ej., 1).
  • transferId: DEBE. Identificador único de la sesión de transferencia.
  • createdAt / expiresAt: DEBERÍA. Para la gestión del ciclo de vida y las indicaciones en la interfaz.
  • policy: DEBERÍA. Un resumen de la política (límites del número de descargas, requisito de contraseña, si se permite compartir antes de que termine la subida, etc.).
  • files[]: DEBE. Descripción de la lista de archivos (como mínimo, tamaños de archivo e intervalos de fragmentos).
  • chunking: DEBE. Incluye chunkSize y cómo se calcula chunkCount, o chunkCount por archivo.
  • objectKeyRule: DEBE. Derivar las claves de objeto de (transferId, fileId, chunkIndex), o proporcionar una tabla de correspondencia explícita.

A.1.1 Campos mínimos de files[]

  • fileId: DEBE. Identificador único del archivo (no uses el nombre de archivo como clave única).
  • size: DEBE. Tamaño en bytes.
  • mime: PUEDE. Para mostrarlo y para sugerencias de descarga.
  • name: PUEDE. Si quieres un conocimiento cero estricto y una filtración mínima, omite name o guarda un nombre cifrado.
  • chunkCount: DEBE. Número de fragmentos de este archivo.
  • chunkOffset: PUEDE. Si varios archivos comparten un chunkIndex global, hace falta un desplazamiento; en caso contrario, puede omitirse.

A.1.2 Campos de integridad y verificación (opcionales pero recomendados)

  • chunkHashes[]: DEBERÍA. Verificación por fragmento (uno o una combinación de hash, longitud y etag).
  • fileHash: PUEDE. Suma de verificación del archivo completo (se verifica tras la descarga).
  • ciphertextLength: PUEDE. Comprobaciones de coherencia de longitud a nivel de texto cifrado (sin necesidad del texto plano).

A.2 Objetos de fragmento: restricciones mínimas

  • Direccionamiento único: un fragmento DEBE poder direccionarse de forma única mediante (transferId, fileId, chunkIndex).
  • Subida idempotente: volver a subir el mismo fragmento NO DEBE alterar el estado final (puede sobrescribirse o rechazarse, pero el comportamiento debe ser coherente).
  • Metadatos mínimos: el servidor PUEDE registrar únicamente la longitud del texto cifrado, la hora de escritura, el etag o la versión, etc., para la observabilidad y la resolución de problemas.

A.2.1 Regla de claves de objeto (ejemplo)

  • /transfers/{transferId}/chunks/{fileId}/{chunkIndex}
  • /transfers/{transferId}/manifest

Restricción: las claves de objeto DEBEN permitir la limpieza masiva por el prefijo transferId; las claves de objeto DEBERÍAN evitar incluir información de negocio sensible.

A.3 Registros de estado: campos mínimos

El estado responde a «el progreso de subida y descarga y la recuperación». Debe ser pequeño y rápido de leer y escribir.

  • transferId: DEBE.
  • status: DEBE. Valores sugeridos: UPLOADING / READY / DELETED / EXPIRED.
  • uploadedSet: DEBE. Conjunto de fragmentos completados; DEBERÍA comprimirse con un mapa de bits o un conjunto de rangos.
  • uploadedBytes: DEBERÍA. Para mostrar el progreso y comprobar cuotas (puede derivarse de los fragmentos, pero mantenerlo es más rápido).
  • downloadCount: PUEDE. Si aplicas límites al número de descargas, debe registrarse y actualizarse de forma atómica (los detalles dependen de tu almacenamiento).
  • expiresAt: DEBERÍA. Para aplicar la caducidad y la limpieza en segundo plano.

A.3.1 Salida mínima de una API de recuperación

Para las transferencias reanudables, el servidor DEBERÍA poder devolver:

  • El estado de la transferencia (UPLOADING/READY/DELETED/EXPIRED)
  • uploadedSet (conjunto de fragmentos completados)
  • Un resumen de la política (p. ej., cuota superada, caducada, si se permite continuar la subida)

Nota: límites respecto al documento técnico sobre seguridad y privacidad

  • Este apéndice solo describe las «estructuras y restricciones» necesarias para la transferencia y el almacenamiento.
  • Para los campos de cifrado, cómo se transporta o deriva el material de claves y el comportamiento de fallo en cerrado ante errores de autenticación, consulta el documento técnico sobre seguridad y privacidad.