Refactor sync service to handle conflicted category and note IDs during synchronization
Despliegue Automático / desplegar (push) Successful in 1m25s
Despliegue Automático / desplegar (push) Successful in 1m25s
This commit is contained in:
+17
-10
@@ -41,7 +41,6 @@ const buildStoredNoteData = (incomingNote, existingNote = null) => {
|
|||||||
: (incomingNote.position ?? existingNote?.position ?? 0);
|
: (incomingNote.position ?? existingNote?.position ?? 0);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// categoryId eliminado de aquí
|
|
||||||
title: permanentDelete ? '' : incomingNote.title,
|
title: permanentDelete ? '' : incomingNote.title,
|
||||||
body: permanentDelete ? '' : incomingNote.body,
|
body: permanentDelete ? '' : incomingNote.body,
|
||||||
position,
|
position,
|
||||||
@@ -73,6 +72,10 @@ class SyncService {
|
|||||||
const incomingCategories = Array.isArray(changes.categories) ? changes.categories : [];
|
const incomingCategories = Array.isArray(changes.categories) ? changes.categories : [];
|
||||||
const incomingNotes = Array.isArray(changes.notes) ? changes.notes : [];
|
const incomingNotes = Array.isArray(changes.notes) ? changes.notes : [];
|
||||||
|
|
||||||
|
// ARRAYS PARA IDs DESFASADOS
|
||||||
|
const conflictedCategoryIds = [];
|
||||||
|
const conflictedNoteIds = [];
|
||||||
|
|
||||||
await sequelize.transaction(async (transaction) => {
|
await sequelize.transaction(async (transaction) => {
|
||||||
// --- SINCRONIZACIÓN DE CATEGORÍAS ---
|
// --- SINCRONIZACIÓN DE CATEGORÍAS ---
|
||||||
for (const incomingCategory of incomingCategories) {
|
for (const incomingCategory of incomingCategories) {
|
||||||
@@ -109,6 +112,8 @@ class SyncService {
|
|||||||
delete: Boolean(incomingCategory.delete),
|
delete: Boolean(incomingCategory.delete),
|
||||||
serverVersion: serverVersion + 1
|
serverVersion: serverVersion + 1
|
||||||
}, { transaction });
|
}, { transaction });
|
||||||
|
} else if (serverVersion > incomingBaseVersion) {
|
||||||
|
conflictedCategoryIds.push(existingCategory.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +121,6 @@ class SyncService {
|
|||||||
for (const incomingNote of incomingNotes) {
|
for (const incomingNote of incomingNotes) {
|
||||||
const permanentDelete = Boolean(incomingNote.permanentDelete);
|
const permanentDelete = Boolean(incomingNote.permanentDelete);
|
||||||
|
|
||||||
// Se verifica que sea 'string' para aceptar strings vacíos
|
|
||||||
if (!incomingNote.id || typeof incomingNote.title !== 'string' || typeof incomingNote.body !== 'string') {
|
if (!incomingNote.id || typeof incomingNote.title !== 'string' || typeof incomingNote.body !== 'string') {
|
||||||
throw new Error("Cada nota debe incluir id, title y body");
|
throw new Error("Cada nota debe incluir id, title y body");
|
||||||
}
|
}
|
||||||
@@ -138,7 +142,6 @@ class SyncService {
|
|||||||
serverVersion: 1
|
serverVersion: 1
|
||||||
}, { transaction });
|
}, { transaction });
|
||||||
|
|
||||||
// 👇 Actualizar la relación de muchos a muchos al crear
|
|
||||||
if (Array.isArray(incomingNote.categoryIds)) {
|
if (Array.isArray(incomingNote.categoryIds)) {
|
||||||
await newNote.setCategories(incomingNote.categoryIds, { transaction });
|
await newNote.setCategories(incomingNote.categoryIds, { transaction });
|
||||||
}
|
}
|
||||||
@@ -155,12 +158,11 @@ class SyncService {
|
|||||||
serverVersion: serverVersion + 1
|
serverVersion: serverVersion + 1
|
||||||
}, { transaction });
|
}, { transaction });
|
||||||
|
|
||||||
// 👇 Actualizar la relación de muchos a muchos al editar
|
|
||||||
if (Array.isArray(incomingNote.categoryIds)) {
|
if (Array.isArray(incomingNote.categoryIds)) {
|
||||||
await existingNote.setCategories(incomingNote.categoryIds, { transaction });
|
await existingNote.setCategories(incomingNote.categoryIds, { transaction });
|
||||||
}
|
}
|
||||||
} else if (serverVersion > incomingBaseVersion) {
|
} else if (serverVersion > incomingBaseVersion) {
|
||||||
// Conflicto de versiones... (implementación de duplicados omitida por ahora)
|
conflictedNoteIds.push(existingNote.id);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`serverVersion inválida en la nota ${incomingNote.id}`);
|
throw new Error(`serverVersion inválida en la nota ${incomingNote.id}`);
|
||||||
}
|
}
|
||||||
@@ -172,20 +174,25 @@ class SyncService {
|
|||||||
Category.findAll({
|
Category.findAll({
|
||||||
where: {
|
where: {
|
||||||
userId,
|
userId,
|
||||||
updatedAt: { [Op.gt]: lastSyncAt }
|
[Op.or]: [
|
||||||
|
{ updatedAt: { [Op.gt]: lastSyncAt } },
|
||||||
|
{ id: { [Op.in]: conflictedCategoryIds } }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
order: [['updatedAt', 'ASC']]
|
order: [['updatedAt', 'ASC']]
|
||||||
}),
|
}),
|
||||||
Note.findAll({
|
Note.findAll({
|
||||||
where: {
|
where: {
|
||||||
userId,
|
userId,
|
||||||
updatedAt: { [Op.gt]: lastSyncAt }
|
[Op.or]: [
|
||||||
|
{ updatedAt: { [Op.gt]: lastSyncAt } },
|
||||||
|
{ id: { [Op.in]: conflictedNoteIds } }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
// 👇 Le decimos a Sequelize que incluya la tabla Category para poder sacar los IDs
|
|
||||||
include: [{
|
include: [{
|
||||||
model: Category,
|
model: Category,
|
||||||
attributes: ['id'], // Solo necesitamos el ID para el array de Flutter
|
attributes: ['id'],
|
||||||
through: { attributes: [] } // Omite los datos de la tabla intermedia en el JSON final
|
through: { attributes: [] }
|
||||||
}],
|
}],
|
||||||
order: [['updatedAt', 'ASC']]
|
order: [['updatedAt', 'ASC']]
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user