Platform isolation:
- Rename handlers to {task}-{platform}.ts convention
- Deprecate -curl variants (now _deprecated-*)
- Platform-based routing in task-worker.ts
- Add Jane platform handlers and client
Evomi geo-targeting:
- Add dynamic proxy URL builder with state/city targeting
- Session stickiness per worker per state (30 min)
- Fallback to static proxy table when API unavailable
- Add proxy tracking columns to worker_tasks
Proxy management:
- New /proxies admin page for visibility
- Track proxy_ip, proxy_geo, proxy_source per task
- Show active sessions and task history
Validation filtering:
- Filter by validated stores (platform_dispensary_id + menu_url)
- Mark incomplete stores as deprecated
- Update all dashboard/stats queries
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
95 lines
3.3 KiB
TypeScript
95 lines
3.3 KiB
TypeScript
/**
|
|
* @deprecated DO NOT USE - This file is deprecated.
|
|
* Use store-discovery-dutchie.ts instead (HTTP/Puppeteer transport).
|
|
*
|
|
* This was the old curl-based store discovery handler.
|
|
* Kept for historical reference only.
|
|
*
|
|
* ---
|
|
* Original docs:
|
|
* Store Discovery Handler
|
|
*
|
|
* Per TASK_WORKFLOW_2024-12-10.md: Discovers new stores and returns their IDs for task chaining.
|
|
*
|
|
* Flow:
|
|
* 1. For each active state, run Dutchie discovery
|
|
* 2. Discover locations via GraphQL
|
|
* 3. Auto-promote valid locations to dispensaries table
|
|
* 4. Return newStoreIds[] for chaining to payload_fetch
|
|
*
|
|
* Chaining:
|
|
* store_discovery → (returns newStoreIds) → payload_fetch → product_refresh
|
|
*/
|
|
|
|
import { TaskContext, TaskResult } from '../task-worker';
|
|
import { discoverState } from '../../discovery';
|
|
|
|
export async function handleStoreDiscovery(ctx: TaskContext): Promise<TaskResult> {
|
|
const { pool, task } = ctx;
|
|
const platform = task.platform || 'dutchie';
|
|
|
|
console.log(`[StoreDiscovery] Starting discovery for platform: ${platform}`);
|
|
|
|
try {
|
|
// Get states to discover
|
|
const statesResult = await pool.query(`
|
|
SELECT code FROM states WHERE is_active = true ORDER BY code
|
|
`);
|
|
const stateCodes = statesResult.rows.map(r => r.code);
|
|
|
|
if (stateCodes.length === 0) {
|
|
return { success: true, storesDiscovered: 0, newStoreIds: [], message: 'No active states to discover' };
|
|
}
|
|
|
|
let totalDiscovered = 0;
|
|
let totalPromoted = 0;
|
|
// Per TASK_WORKFLOW_2024-12-10.md: Collect all new store IDs for task chaining
|
|
const allNewStoreIds: number[] = [];
|
|
|
|
// Run discovery for each state
|
|
for (const stateCode of stateCodes) {
|
|
// Heartbeat before each state
|
|
await ctx.heartbeat();
|
|
|
|
console.log(`[StoreDiscovery] Discovering stores in ${stateCode}...`);
|
|
|
|
try {
|
|
const result = await discoverState(pool, stateCode);
|
|
totalDiscovered += result.totalLocationsFound || 0;
|
|
totalPromoted += result.totalLocationsUpserted || 0;
|
|
|
|
// Per TASK_WORKFLOW_2024-12-10.md: Collect new IDs for chaining
|
|
if (result.newDispensaryIds && result.newDispensaryIds.length > 0) {
|
|
allNewStoreIds.push(...result.newDispensaryIds);
|
|
console.log(`[StoreDiscovery] ${stateCode}: ${result.newDispensaryIds.length} new stores`);
|
|
}
|
|
|
|
console.log(`[StoreDiscovery] ${stateCode}: found ${result.totalLocationsFound}, upserted ${result.totalLocationsUpserted}`);
|
|
} catch (error: unknown) {
|
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
console.error(`[StoreDiscovery] Error discovering ${stateCode}:`, errorMessage);
|
|
// Continue with other states
|
|
}
|
|
}
|
|
|
|
console.log(`[StoreDiscovery] Complete: ${totalDiscovered} discovered, ${totalPromoted} promoted, ${allNewStoreIds.length} new stores`);
|
|
|
|
return {
|
|
success: true,
|
|
storesDiscovered: totalDiscovered,
|
|
storesPromoted: totalPromoted,
|
|
statesProcessed: stateCodes.length,
|
|
// Per TASK_WORKFLOW_2024-12-10.md: Return new IDs for task chaining
|
|
newStoreIds: allNewStoreIds,
|
|
};
|
|
} catch (error: unknown) {
|
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
console.error(`[StoreDiscovery] Error:`, errorMessage);
|
|
return {
|
|
success: false,
|
|
error: errorMessage,
|
|
newStoreIds: [],
|
|
};
|
|
}
|
|
}
|