Compare commits

..

No commits in common. "0893cea4895d7b9adc7b8bd16de25188eb0cb26d" and "818f66205b2fdd625743f17e6be9f47e922dfe05" have entirely different histories.

5 changed files with 14 additions and 100 deletions

View file

@ -54,7 +54,7 @@ export async function createList(name: string, color?: string, icon?: string) {
color: color ?? null,
icon: icon ?? null,
position: maxPosition + 1,
isInbox: false,
is_inbox: false,
}).catch(() => {});
return id;

View file

@ -3,7 +3,7 @@ import { syncOutbox } from '../schema';
import { randomUUID } from '@/src/lib/uuid';
import { useSettingsStore } from '@/src/stores/useSettingsStore';
type EntityType = 'task' | 'list' | 'tag' | 'taskTag';
type EntityType = 'task' | 'list' | 'tag' | 'task_tag';
type Action = 'create' | 'update' | 'delete';
/**

View file

@ -52,10 +52,7 @@ export async function setTagsForTask(taskId: string, tagIds: string[]) {
tagIds.map((tagId) => ({ taskId, tagId }))
);
}
// Send individual taskTag create operations (server expects entityId=taskId, data.tagId)
for (const tagId of tagIds) {
writeOutboxEntry('taskTag', taskId, 'create', { tagId }).catch(() => {});
}
writeOutboxEntry('task_tag', taskId, 'update', { task_id: taskId, tag_ids: tagIds }).catch(() => {});
}
export async function addTagToTask(taskId: string, tagId: string) {

View file

@ -176,12 +176,10 @@ export async function createTask(data: {
id,
title: data.title,
notes: data.notes ?? null,
completed: false,
completedAt: null,
priority: data.priority ?? 0,
dueDate: data.dueDate?.toISOString() ?? null,
listId: data.listId,
parentId: data.parentId ?? null,
due_date: data.dueDate?.toISOString() ?? null,
list_id: data.listId,
parent_id: data.parentId ?? null,
recurrence: sanitizedRecurrence,
}).catch(() => {});
@ -257,11 +255,10 @@ export async function updateTask(
title: task.title,
notes: task.notes,
completed: task.completed,
completedAt: task.completedAt ? new Date(task.completedAt).toISOString() : null,
priority: task.priority,
dueDate: task.dueDate ? new Date(task.dueDate).toISOString() : null,
listId: task.listId,
parentId: task.parentId,
due_date: task.dueDate ? new Date(task.dueDate).toISOString() : null,
list_id: task.listId,
parent_id: task.parentId,
recurrence: task.recurrence,
}).catch(() => {});
}

View file

@ -64,87 +64,12 @@ export async function GET(request: NextRequest) {
.where(inArray(slTaskTags.taskId, taskIds));
}
// Transform entities into the changes format expected by the mobile client
const changes: {
entity_type: string;
entity_id: string;
action: 'create' | 'update' | 'delete';
payload: Record<string, unknown>;
updated_at: string;
}[] = [];
for (const l of lists) {
changes.push({
entity_type: 'list',
entity_id: l.id,
action: l.deletedAt ? 'delete' : 'update',
payload: {
name: l.name,
color: l.color,
icon: l.icon,
position: l.position,
is_inbox: l.isInbox,
created_at: l.createdAt.toISOString(),
updated_at: l.updatedAt.toISOString(),
},
updated_at: l.updatedAt.toISOString(),
});
}
for (const t of tasks) {
changes.push({
entity_type: 'task',
entity_id: t.id,
action: t.deletedAt ? 'delete' : 'update',
payload: {
title: t.title,
notes: t.notes,
completed: t.completed,
completed_at: t.completedAt?.toISOString() ?? null,
priority: t.priority,
due_date: t.dueDate?.toISOString() ?? null,
list_id: t.listId,
parent_id: t.parentId,
position: t.position,
recurrence: t.recurrence,
created_at: t.createdAt.toISOString(),
updated_at: t.updatedAt.toISOString(),
},
updated_at: t.updatedAt.toISOString(),
});
}
for (const tag of tags) {
changes.push({
entity_type: 'tag',
entity_id: tag.id,
action: tag.deletedAt ? 'delete' : 'update',
payload: {
name: tag.name,
color: tag.color,
created_at: tag.createdAt.toISOString(),
updated_at: tag.createdAt.toISOString(),
},
updated_at: tag.createdAt.toISOString(),
});
}
for (const tt of taskTags) {
changes.push({
entity_type: 'task_tag',
entity_id: `${tt.taskId}:${tt.tagId}`,
action: 'update',
payload: {
task_id: tt.taskId,
tag_id: tt.tagId,
},
updated_at: new Date().toISOString(),
});
}
return NextResponse.json({
changes,
sync_token: new Date().toISOString(),
lists,
tasks,
tags,
taskTags,
syncedAt: new Date().toISOString(),
});
}
@ -237,14 +162,9 @@ async function processOperation(op: SyncOperation, userId: string) {
} else if (action === 'update') {
await verifyOwnership(slTasks, entityId, userId);
const raw = { ...(data as Record<string, unknown>), updatedAt: now } as Record<string, unknown>;
// Remove id from payload to avoid overwriting primary key
delete raw.id;
if (raw.dueDate !== undefined) {
raw.dueDate = raw.dueDate ? new Date(raw.dueDate as string) : null;
}
if (raw.completedAt !== undefined) {
raw.completedAt = raw.completedAt ? new Date(raw.completedAt as string) : null;
}
await db.update(slTasks)
.set(raw)
.where(and(eq(slTasks.id, entityId), eq(slTasks.userId, userId)));