6.7 KiB
Aquí tienes la documentación completa generada en formato README.md a partir de la arquitectura y el código de tu API.
Documentación de la API: Notas Encriptadas (E2EE)
Esta API proporciona el backend para una aplicación de notas con sincronización Offline-First y Cifrado de Extremo a Extremo (E2EE). Está construida sobre Node.js con Express y utiliza PostgreSQL (vía Sequelize) como base de datos.
🏗 Arquitectura y Flujo de Datos
El sistema sigue un patrón estructurado en capas para separar responsabilidades:
-
Punto de Entrada e Inicialización: El archivo
app.jsinicializa Express, habilita CORS y permite payloads JSON de hasta 50MB. El archivoinitDB.jsse encarga de sincronizar los modelos con la base de datos PostgreSQL utilizando Sequelize. -
Enrutamiento Principal (
index.js): Todo el tráfico entra por/api. De ahí, el router principal distribuye las peticiones hacia/auth(autenticación),/user(datos del usuario) y/(sincronización). -
Controladores (
*Controller.js): Son la capa de seguridad y transporte. Validan que las peticiones vengan con un JWT válido en las cabeceras (Access Token), extraen eluserIdy envían los parámetros limpios a los servicios. -
Servicios (
*Service.js): Contienen toda la lógica de negocio profunda. Manejan la creación de tokens, el hasheo de contraseñas, las transacciones SQL y la lógica de resolución de conflictos durante la sincronización. -
Modelos (
.js): Definen las tablas y relaciones estructurales en la base de datos.
🗄 Modelos de Base de Datos y Relaciones
El esquema de la base de datos se distribuye en cuatro entidades principales interconectadas:
-
User (
User.js): Almacena elemailypassword(hasheado con bcrypt) del usuario. También guarda laencrypted_master_key, que es la llave maestra para desencriptar las notas, pero cifrada con la contraseña del usuario para asegurar el E2EE. Un usuario tiene muchas Notas, Categorías y RefreshTokens. -
Note (
Note.js): Guarda los datos cifrados de cada nota (title,body), su orden (position), versión en el servidor (serverVersion) y estados de borrado (delete,permanentDelete). -
Category (
Category.js): Guarda información visual (colorValue,iconCodePoint) y el nombre cifrado (encrypted_name) de las categorías. -
Relación Nota-Categoría: Las Notas y las Categorías tienen una relación de Muchos a Muchos (M:N) a través de una tabla intermedia llamada
NoteCategories. -
RefreshToken (
RefreshToken.js): Gestiona las sesiones multidispositivo. Guarda un token largo, seguro y único asociado aldeviceNamedel usuario. Si el usuario se elimina, sus tokens se borran en cascada.
🚀 Endpoints de la API
1. Autenticación (/api/auth)
Estos endpoints gestionan el registro, inicio de sesión y ciclo de vida de los tokens. El sistema usa un Access Token de corta duración (15 min) y un Refresh Token persistente en base de datos.
-
Registro de Usuario
-
Ruta:
POST /api/auth/register -
Body:
{ "email": "...", "password": "...", "encrypted_master_key": "...", "deviceName": "..." } -
Descripción: Comprueba que el usuario no exista, hashea su contraseña, crea la cuenta y automáticamente inicia sesión, devolviendo ambos tokens (Access y Refresh) y la llave maestra.
-
Inicio de Sesión
-
Ruta:
POST /api/auth/login -
Body:
{ "email": "...", "password": "...", "deviceName": "..." } -
Descripción: Verifica credenciales y crea una nueva sesión para el dispositivo (registrando un nuevo Refresh Token en DB). Retorna los tokens y la
encrypted_master_key. -
Refrescar Token
-
Ruta:
POST /api/auth/refresh -
Body:
{ "refresh_token": "..." } -
Descripción: Intercambia un Refresh Token válido por un nuevo Access Token limpio de 15 minutos.
-
Cerrar Sesión Local
-
Ruta:
POST /api/auth/logout -
Body:
{ "refresh_token": "..." } -
Descripción: Borra el Refresh Token proporcionado de la base de datos, revocando el acceso a ese dispositivo específico.
-
Borrado Total de Cuenta (Danger Zone)
-
Ruta:
DELETE /api/auth/delete-all-data -
Headers:
Authorization: Bearer <access_token> -
Descripción: Mediante una transacción de base de datos, borra irremediablemente todas las notas, categorías y sesiones (tokens) asociadas al usuario actual.
-
Listar Dispositivos Activos
-
Ruta:
GET /api/auth/getSessionsInfo -
Headers:
Authorization: Bearer <access_token> -
Descripción: Devuelve un listado de todos los dispositivos (
deviceName), fechas de creación y los IDs de los Refresh Tokens asociados al usuario.
2. Estadísticas de Usuario (/api/user)
-
Obtener Estadísticas
-
Ruta:
GET /api/user/stats -
Headers:
Authorization: Bearer <access_token> -
Descripción: Descarga parcialmente las notas y categorías de la base de datos (solo los campos pesados como títulos y cuerpos) para calcular el peso en bytes (RAM-friendly) del almacenamiento en la nube del usuario. Devuelve totales formateados (KB/MB).
3. Sincronización Offline-First (/api/sync)
Este endpoint único procesa de forma bidireccional los cambios ocurridos tanto en la app local como en la base de datos del servidor.
-
Endpoint de Sincronización
-
Ruta:
POST /api/sync -
Headers:
Authorization: Bearer <access_token> -
Body:
{
"lastSyncAt": "ISO String",
"changes": {
"categories": [ ... ],
"notes": [ ... ]
}
}
- Descripción y Flujo de Resolución:
-
Envuelve todo en una Transacción SQL para garantizar que o se guarda todo o no se guarda nada en caso de error.
-
Recorre las
categoriesentrantes. Si elidno existe, lo crea. Si existe, compara laserverVersion. Si la versión enviada coincide con la del servidor, actualiza los datos e incrementa la versión en el servidor. Si el servidor tiene una versión superior (conflicto), ignora el cambio del cliente y anota el ID para mandárselo de vuelta. -
Repite exactamente el mismo proceso de validación transaccional e inserción de datos para las
notes, actualizando también la tabla intermedia de categorías mediante el arraycategoryIdsentrante. -
Consulta a la base de datos cualquier nota o categoría cuyo
updatedAtsea mayor allastSyncAtproporcionado por el cliente, además de sumar los registros que hayan sufrido un conflicto de versión en los pasos anteriores. -
Devuelve al cliente un objeto estructurado con las notas y categorías actualizadas del servidor y el nuevo
serverTimestamp(momento exacto en el que acabó la sincronización).