New scrapers: - GBICS.com (BigCommerce, GBP prices, 10 categories, 78 products) - Juniper HCT (Next.js SSR parser, 475 transceivers with specs/EOL) - SFPcables.com (Magento store, 16 categories, 78 products) - Fluxlight (BigCommerce, 6 pages, 118 products) - Champion ONE (compatible vendor scraper) Scraper fixes: - 10Gtek: rewritten to parse HTML spec tables (152 products) - Flexoptix: fix price extraction from Magento Hyva HTML - Register all scrapers in CLI (--gbics, --juniper, --sfpcables, etc.) Hype Cycle Engine enhancements: - Data-driven enrichment from scraped vendor/price data - Revenue lifecycle prediction (peak year, decline, revenue index) - Regional adoption model (NA, China, APAC, Europe, RoW with lag coefficients) - New API endpoints: /enriched, /lifecycle, /regional/:tech DB growth: 89 → 1,168 transceivers, 0 → 416 prices, 6 vendors Qdrant: 1,162 products embedded with nomic-embed-text Research: Norton-Bass model, standards-to-market timelines, hype signals
54 lines
1.7 KiB
TypeScript
54 lines
1.7 KiB
TypeScript
/**
|
|
* Batch Research Runner — runs all Perplexity research modes sequentially
|
|
* and builds a comprehensive market intelligence report.
|
|
*
|
|
* Usage: PERPLEXITY_API_KEY=pplx-xxx tsx scripts/perplexity-batch-research.ts
|
|
*/
|
|
|
|
import { execFileSync } from 'child_process';
|
|
import { mkdirSync, writeFileSync, readdirSync, readFileSync } from 'fs';
|
|
|
|
const modes = ['competitors', 'market-trends', 'pricing', 'standards'];
|
|
const outputDir = 'storage/research';
|
|
|
|
mkdirSync(outputDir, { recursive: true });
|
|
|
|
async function runBatch() {
|
|
console.log('🔬 Transceiver Intelligence — Batch Research');
|
|
console.log('='.repeat(60));
|
|
|
|
for (const mode of modes) {
|
|
console.log(`\n▶ Running: ${mode}`);
|
|
try {
|
|
execFileSync('tsx', ['scripts/perplexity-research.ts', `--mode=${mode}`], {
|
|
stdio: 'inherit',
|
|
env: process.env,
|
|
});
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
} catch (error) {
|
|
console.error(` ✗ Failed: ${mode}`);
|
|
}
|
|
}
|
|
|
|
console.log('\n📊 Generating combined report...');
|
|
const files = readdirSync(outputDir).filter(f => f.endsWith('.json'));
|
|
const results = files.map(f => {
|
|
const data = JSON.parse(readFileSync(`${outputDir}/${f}`, 'utf-8'));
|
|
return { file: f, ...data };
|
|
});
|
|
|
|
const report = {
|
|
generated: new Date().toISOString(),
|
|
totalResearchFiles: results.length,
|
|
modes: results.map(r => r.mode),
|
|
results,
|
|
};
|
|
|
|
const reportPath = `${outputDir}/combined-report-${new Date().toISOString().split('T')[0]}.json`;
|
|
writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
console.log(`\n✅ Combined report: ${reportPath}`);
|
|
console.log(` ${results.length} research files processed`);
|
|
}
|
|
|
|
runBatch().catch(console.error);
|