2 changed files with 32 additions and 6 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { db } from '@/db/client';
|
||||
import { slLists, slTasks, slTags, slTaskTags } from '@/db/schema';
|
||||
import { eq, and, gte } from 'drizzle-orm';
|
||||
import { eq, and, gte, isNull } from 'drizzle-orm';
|
||||
import { requireAuth, parseBody } from '@/lib/api';
|
||||
import { rateLimit } from '@/lib/rateLimit';
|
||||
import { syncPushSchema, type SyncOperation } from '@/lib/validators';
|
||||
|
|
@ -197,14 +197,36 @@ async function processOperation(op: SyncOperation, userId: string) {
|
|||
switch (entityType) {
|
||||
case 'list': {
|
||||
if (action === 'create') {
|
||||
const d = (data as Record<string, unknown>) || {};
|
||||
const incomingIsInbox = d.isInbox as boolean | undefined;
|
||||
|
||||
// If the incoming list is an inbox, check for an existing inbox and merge
|
||||
if (incomingIsInbox) {
|
||||
const [existingInbox] = await db
|
||||
.select()
|
||||
.from(slLists)
|
||||
.where(and(eq(slLists.userId, userId), eq(slLists.isInbox, true), isNull(slLists.deletedAt)));
|
||||
|
||||
if (existingInbox && existingInbox.id !== entityId) {
|
||||
// Reassign all tasks from the old inbox to the new one
|
||||
await db.update(slTasks)
|
||||
.set({ listId: entityId, updatedAt: now })
|
||||
.where(and(eq(slTasks.listId, existingInbox.id), eq(slTasks.userId, userId)));
|
||||
// Soft-delete the old inbox
|
||||
await db.update(slLists)
|
||||
.set({ deletedAt: now, updatedAt: now })
|
||||
.where(eq(slLists.id, existingInbox.id));
|
||||
}
|
||||
}
|
||||
|
||||
await db.insert(slLists).values({
|
||||
id: entityId,
|
||||
userId,
|
||||
name: (data as Record<string, unknown>)?.name as string || 'Untitled',
|
||||
color: (data as Record<string, unknown>)?.color as string | undefined,
|
||||
icon: (data as Record<string, unknown>)?.icon as string | undefined,
|
||||
position: (data as Record<string, unknown>)?.position as number | undefined,
|
||||
isInbox: (data as Record<string, unknown>)?.isInbox as boolean | undefined,
|
||||
name: d.name as string || 'Untitled',
|
||||
color: d.color as string | undefined,
|
||||
icon: d.icon as string | undefined,
|
||||
position: d.position as number | undefined,
|
||||
isInbox: incomingIsInbox,
|
||||
}).onConflictDoNothing();
|
||||
} else if (action === 'update') {
|
||||
await verifyOwnership(slLists, entityId, userId);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,12 @@ async function seed() {
|
|||
.from(slLists)
|
||||
.where(and(eq(slLists.userId, userId), eq(slLists.isInbox, true)));
|
||||
|
||||
// Use the same fixed inbox ID as the mobile app to avoid duplicates during sync
|
||||
const INBOX_ID = '00000000-0000-0000-0000-000000000001';
|
||||
|
||||
if (existing.length === 0) {
|
||||
await db.insert(slLists).values({
|
||||
id: INBOX_ID,
|
||||
userId,
|
||||
name: 'Inbox',
|
||||
isInbox: true,
|
||||
|
|
|
|||
Loading…
Reference in a new issue