feat: Multi-strategy price voting system with user selection

- Add multi-strategy voting: runs JSON-LD, site-specific, generic CSS,
  and AI extraction methods in parallel
- Implement consensus voting to select the correct price when methods agree
- Add AI arbitration when extraction methods disagree
- Add PriceSelectionModal for users to select correct price when ambiguous
- Store preferred extraction method per product for faster re-checks
- Add database columns for preferred_extraction_method and needs_price_review

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
clucraft 2026-01-24 14:45:51 -05:00
parent 40c45b49c8
commit 4fd04cd160
10 changed files with 1259 additions and 12 deletions

View file

@ -1,6 +1,6 @@
import cron from 'node-cron';
import { productQueries, priceHistoryQueries, userQueries, stockStatusHistoryQueries, notificationHistoryQueries, NotificationType } from '../models';
import { scrapeProduct } from './scraper';
import { scrapeProduct, scrapeProductWithVoting, ExtractionMethod } from './scraper';
import { sendNotifications, NotificationPayload } from './notifications';
let isRunning = false;
@ -23,7 +23,15 @@ async function checkPrices(): Promise<void> {
try {
console.log(`Checking price for product ${product.id}: ${product.url}`);
const scrapedData = await scrapeProduct(product.url, product.user_id);
// Get preferred extraction method for this product (if user previously selected one)
const preferredMethod = await productQueries.getPreferredExtractionMethod(product.id);
// Use voting scraper with preferred method if available
const scrapedData = await scrapeProductWithVoting(
product.url,
product.user_id,
preferredMethod as ExtractionMethod | undefined
);
// Check for back-in-stock notification
const wasOutOfStock = product.stock_status === 'out_of_stock';