Add complete end-to-end AI-powered quote extraction workflow: - Disable PB SDK auto-cancellation to support parallel batch requests - Add required runtime dependencies for AI processing and document parsing - Implement AI settings backend, operator UI, and REST API routes - Add quote ingestion, insight population, and manual re-run AI endpoints - Build service layers for quote items, AI settings, and structured item insights - Fix attachment upload handling and quote item history blob parsing - Add supporting migrations, smoke tests, and shared utility functions - Export previously private helper functions for cross-service reuse
27 lines
1.2 KiB
TypeScript
27 lines
1.2 KiB
TypeScript
import "./_env";
|
|
import { getAdminPocketBase } from "../../src/lib/server/pocketbase-admin";
|
|
async function main() {
|
|
const pb = await getAdminPocketBase();
|
|
const quotes = await pb.collection("quotes").getFullList({
|
|
filter: 'email_message_id ~ "smoke-minimax"',
|
|
});
|
|
console.log(`found ${quotes.length} smoke quotes`);
|
|
for (const q of quotes) {
|
|
const items = await pb.collection("quote_items").getFullList({ filter: `quote = "${q.id}"` });
|
|
for (const it of items) {
|
|
await pb.collection("quote_items").delete(it.id);
|
|
console.log(` deleted item ${it.id}`);
|
|
}
|
|
try { await pb.collection("quotes").delete(q.id); console.log(` deleted quote ${q.quote_number}`); }
|
|
catch (e) { console.log(` quote delete failed: ${e.message}`); }
|
|
if (q.customer) {
|
|
try { await pb.collection("customers").delete(q.customer); console.log(` deleted customer ${q.customer}`); }
|
|
catch (e) { console.log(` customer delete skipped: ${e.message}`); }
|
|
}
|
|
if (q.company) {
|
|
try { await pb.collection("companies").delete(q.company); console.log(` deleted company ${q.company}`); }
|
|
catch (e) { console.log(` company delete skipped: ${e.message}`); }
|
|
}
|
|
}
|
|
}
|
|
main().catch((e) => { console.error(e); process.exit(1); });
|