Migrate PDF parsing to use ONNX Docling layout model for structured block extraction, enabling improved TTS segmentation and chaptering. Add compute backend abstraction for heavy tasks (alignment, layout parsing) with configuration via `OPENREADER_COMPUTE_MODE`. Integrate block-level locators and document settings for per-document PDF parsing options. Update S3 storage for parsed PDF JSON, add migration and schema changes, and extend client and server APIs for parsed data and settings. Remove legacy word highlight flag in favor of compute capability detection. - Add ONNX model download, local/none compute modes, and `onnxruntime-node` dependency - Update PDF viewer and TTS pipeline to use parsed blocks and block-level locators - Add document settings storage and APIs for per-document PDF options - Update S3 storage layout for parsed PDF JSON - Add admin/config/docs updates for new compute and parsing features - Remove obsolete word highlight runtime flag and UI BREAKING CHANGE: PDF parsing and word highlighting now require `OPENREADER_COMPUTE_MODE=local` and ONNX model; document settings and S3 layout updated; legacy word highlight flag removed.
76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import Database from 'better-sqlite3';
|
|
import { drizzle } from 'drizzle-orm/better-sqlite3';
|
|
import { eq } from 'drizzle-orm';
|
|
import { documents } from '../../src/db/schema_sqlite';
|
|
import { transferUserDocuments } from '../../src/lib/server/user/claim-data';
|
|
|
|
test.describe('transferUserDocuments', () => {
|
|
test('moves document rows to new user without PK conflicts', async () => {
|
|
process.env.BASE_URL = 'http://localhost:3003';
|
|
process.env.AUTH_SECRET = 'test-secret';
|
|
|
|
const sqlite = new Database(':memory:');
|
|
sqlite.exec(`
|
|
CREATE TABLE documents (
|
|
id TEXT NOT NULL,
|
|
user_id TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
type TEXT NOT NULL,
|
|
size INTEGER NOT NULL,
|
|
last_modified INTEGER NOT NULL,
|
|
file_path TEXT NOT NULL,
|
|
parse_status TEXT,
|
|
parsed_json_key TEXT,
|
|
created_at INTEGER,
|
|
PRIMARY KEY (id, user_id)
|
|
);
|
|
`);
|
|
|
|
const db = drizzle(sqlite);
|
|
|
|
const fromUserId = 'anon';
|
|
const toUserId = 'user';
|
|
|
|
await db.insert(documents).values([
|
|
{
|
|
id: 'doc-a',
|
|
userId: fromUserId,
|
|
name: 'a.pdf',
|
|
type: 'pdf',
|
|
size: 1,
|
|
lastModified: 1,
|
|
filePath: 'doc-a__a.pdf',
|
|
},
|
|
{
|
|
id: 'doc-b',
|
|
userId: fromUserId,
|
|
name: 'b.txt',
|
|
type: 'html',
|
|
size: 2,
|
|
lastModified: 2,
|
|
filePath: 'doc-b__b.txt',
|
|
},
|
|
// Existing row for the destination user (conflict on insert)
|
|
{
|
|
id: 'doc-a',
|
|
userId: toUserId,
|
|
name: 'a.pdf',
|
|
type: 'pdf',
|
|
size: 1,
|
|
lastModified: 1,
|
|
filePath: 'doc-a__a.pdf',
|
|
},
|
|
]);
|
|
|
|
const transferred = await transferUserDocuments(fromUserId, toUserId, { db });
|
|
expect(transferred).toBe(2);
|
|
|
|
const remainingFrom = await db.select().from(documents).where(eq(documents.userId, fromUserId));
|
|
expect(remainingFrom.length).toBe(0);
|
|
|
|
const remainingTo = await db.select().from(documents).where(eq(documents.userId, toUserId));
|
|
const ids = remainingTo.map((r) => r.id).sort();
|
|
expect(ids).toEqual(['doc-a', 'doc-b']);
|
|
});
|
|
});
|