89 lines
3.4 KiB
TypeScript
89 lines
3.4 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { claimAnonymousData } from '@/lib/server/user/claim-data';
|
|
import { auth } from '@/lib/server/auth/auth';
|
|
import { db } from '@/db';
|
|
import { audiobooks, documents, userDocumentProgress, userPreferences } from '@/db/schema';
|
|
import { count, eq, ne } from 'drizzle-orm';
|
|
import { getOpenReaderTestNamespace, getUnclaimedUserIdForNamespace } from '@/lib/server/testing/test-namespace';
|
|
|
|
async function checkClaimMigrationReadiness(): Promise<NextResponse | null> {
|
|
const [legacyRows] = await db
|
|
.select({ count: count() })
|
|
.from(documents)
|
|
.where(ne(documents.filePath, documents.id));
|
|
|
|
if (Number(legacyRows?.count ?? 0) > 0) {
|
|
return NextResponse.json(
|
|
{ error: 'Document metadata migration is still pending. Wait for startup migrations to complete.' },
|
|
{ status: 409 },
|
|
);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
async function getClaimableCounts(
|
|
unclaimedUserId: string,
|
|
): Promise<{ documents: number; audiobooks: number; preferences: number; progress: number }> {
|
|
const [[docCount], [bookCount], [preferencesCount], [progressCount]] =
|
|
await Promise.all([
|
|
db.select({ count: count() }).from(documents).where(eq(documents.userId, unclaimedUserId)),
|
|
db.select({ count: count() }).from(audiobooks).where(eq(audiobooks.userId, unclaimedUserId)),
|
|
db.select({ count: count() }).from(userPreferences).where(eq(userPreferences.userId, unclaimedUserId)),
|
|
db.select({ count: count() }).from(userDocumentProgress).where(eq(userDocumentProgress.userId, unclaimedUserId)),
|
|
]);
|
|
|
|
return {
|
|
documents: Number(docCount?.count ?? 0),
|
|
audiobooks: Number(bookCount?.count ?? 0),
|
|
preferences: Number(preferencesCount?.count ?? 0),
|
|
progress: Number(progressCount?.count ?? 0),
|
|
};
|
|
}
|
|
|
|
export async function GET(req: NextRequest) {
|
|
try {
|
|
const session = await auth?.api.getSession({ headers: req.headers });
|
|
if (!session || !session.user) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const readiness = await checkClaimMigrationReadiness();
|
|
if (readiness) return readiness;
|
|
|
|
const testNamespace = getOpenReaderTestNamespace(req.headers);
|
|
const unclaimedUserId = getUnclaimedUserIdForNamespace(testNamespace);
|
|
const counts = await getClaimableCounts(unclaimedUserId);
|
|
return NextResponse.json({ success: true, ...counts });
|
|
} catch (error) {
|
|
console.error('Error checking claimable data:', error);
|
|
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
export async function POST(req: NextRequest) {
|
|
try {
|
|
const session = await auth?.api.getSession({ headers: req.headers });
|
|
if (!session || !session.user) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const readiness = await checkClaimMigrationReadiness();
|
|
if (readiness) return readiness;
|
|
|
|
const testNamespace = getOpenReaderTestNamespace(req.headers);
|
|
const unclaimedUserId = getUnclaimedUserIdForNamespace(testNamespace);
|
|
const userId = session.user.id;
|
|
|
|
const result = await claimAnonymousData(userId, unclaimedUserId, testNamespace);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
claimed: result
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Error claiming data:', error);
|
|
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
|
|
}
|
|
}
|