/** * 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 { 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: [], }; } }