fix(preflight): Apply stored fingerprint to task browser

- Add WorkerFingerprint interface with timezone, city, state, ip, locale
- Store fingerprint in TaskWorker after preflight passes
- Pass fingerprint through TaskContext to handlers
- Apply timezone via CDP and locale via Accept-Language header
- Ensures browser fingerprint matches proxy IP location

This fixes anti-detect detection where timezone/locale mismatch
with proxy IP was getting blocked by Cloudflare.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Kelly
2025-12-13 16:40:52 -07:00
parent 5ea92e25af
commit 023cfc127f
22 changed files with 3083 additions and 5 deletions

View File

@@ -0,0 +1,113 @@
/**
* Test script for Treez platform client
* Tests the new Treez integration with Best Dispensary
*
* Usage: npx ts-node scripts/test-treez-client.ts
*/
import {
fetchProductsByStoreId,
} from '../src/platforms/treez';
import { TreezNormalizer } from '../src/hydration/normalizers/treez';
const TEST_STORE_ID = 'best';
async function main() {
console.log('='.repeat(60));
console.log('Treez Platform Client Test');
console.log('='.repeat(60));
console.log(`Test Store: ${TEST_STORE_ID}`);
console.log('');
try {
// Test 1: Fetch products from store
console.log('[Test 1] Fetching products from Treez store...');
const result = await fetchProductsByStoreId(TEST_STORE_ID);
console.log('');
console.log('[Results]');
console.log(` Store: ${result.store.name}`);
console.log(` Store ID: ${result.store.storeId}`);
console.log(` Products captured: ${result.products.length}`);
console.log(` Scroll count: ${result.scrollCount}`);
if (result.products.length > 0) {
console.log('');
console.log('[Sample Products (first 5)]');
for (const p of result.products.slice(0, 5)) {
console.log(` - ${p.name}`);
console.log(` Brand: ${p.brand || 'N/A'}`);
console.log(` Category: ${p.category || 'N/A'} / ${p.subcategory || 'N/A'}`);
console.log(` Price: ${p.price ? '$' + p.price : 'N/A'}`);
console.log(` THC: ${p.thcPercent !== null ? p.thcPercent + '%' : 'N/A'}`);
}
// Test 2: Normalize products
console.log('');
console.log('[Test 2] Testing normalizer...');
const normalizer = new TreezNormalizer();
// Build a fake payload structure
const fakePayload = {
id: 'test-payload',
dispensary_id: 9999,
crawl_run_id: null,
platform: 'treez',
payload_version: 1,
raw_json: { products: result.products },
product_count: result.products.length,
pricing_type: null,
crawl_mode: null,
fetched_at: new Date(),
processed: false,
normalized_at: null,
hydration_error: null,
hydration_attempts: 0,
created_at: new Date(),
};
const normalized = normalizer.normalize(fakePayload);
console.log(` Products normalized: ${normalized.products.length}`);
console.log(` Brands extracted: ${normalized.brands.length}`);
console.log(` Categories extracted: ${normalized.categories.length}`);
console.log(` Errors: ${normalized.errors.length}`);
if (normalized.products.length > 0) {
console.log('');
console.log('[Sample Normalized Product]');
const np = normalized.products[0];
console.log(` External ID: ${np.externalProductId}`);
console.log(` Name: ${np.name}`);
console.log(` Brand: ${np.brandName}`);
console.log(` Category: ${np.category}`);
console.log(` Type: ${np.type}`);
console.log(` Strain: ${np.strainType}`);
console.log(` THC: ${np.thcPercent !== null ? np.thcPercent + '%' : 'N/A'}`);
console.log(` CBD: ${np.cbdPercent !== null ? np.cbdPercent + '%' : 'N/A'}`);
console.log(` Image: ${np.primaryImageUrl?.slice(0, 60) || 'N/A'}...`);
const pricing = normalized.pricing.get(np.externalProductId);
if (pricing) {
console.log(` Price (cents): ${pricing.priceRec}`);
}
}
}
console.log('');
console.log('='.repeat(60));
console.log('TEST PASSED');
console.log('='.repeat(60));
} catch (error: any) {
console.error('');
console.error('='.repeat(60));
console.error('TEST FAILED');
console.error('='.repeat(60));
console.error(`Error: ${error.message}`);
console.error(error.stack);
process.exit(1);
}
}
main().catch(console.error);