/** * Trulieve Scottsdale - Per-Store Dutchie Crawler * * Store ID: 101 * Profile Key: trulieve-scottsdale * Platform Dispensary ID: 5eaf489fa8a61801212577cc * * Phase 1: Identity implementation - no overrides, just uses base Dutchie logic. * Future: Add store-specific selectors, timing, or custom logic as needed. */ import { BaseDutchieCrawler, StoreCrawlOptions, CrawlResult, DutchieSelectors, crawlProducts as baseCrawlProducts, } from '../../base/base-dutchie'; import { Dispensary } from '../../../dutchie-az/types'; // Re-export CrawlResult for the orchestrator export { CrawlResult }; // ============================================================ // STORE CONFIGURATION // ============================================================ /** * Store-specific configuration * These can be used to customize crawler behavior for this store */ export const STORE_CONFIG = { storeId: 101, profileKey: 'trulieve-scottsdale', name: 'Trulieve of Scottsdale Dispensary', platformDispensaryId: '5eaf489fa8a61801212577cc', // Store-specific overrides (none for Phase 1) customOptions: { // Example future overrides: // pricingType: 'rec', // useBothModes: true, // customHeaders: {}, // maxRetries: 3, }, }; // ============================================================ // STORE CRAWLER CLASS // ============================================================ /** * TrulieveScottsdaleCrawler - Per-store crawler for Trulieve Scottsdale * * Phase 1: Identity implementation - extends BaseDutchieCrawler with no overrides. * Future phases can override methods like: * - getCName() for custom slug handling * - crawlProducts() for completely custom logic * - Add hooks for pre/post processing */ export class TrulieveScottsdaleCrawler extends BaseDutchieCrawler { constructor(dispensary: Dispensary, options: StoreCrawlOptions = {}) { // Merge store-specific options with provided options const mergedOptions: StoreCrawlOptions = { ...STORE_CONFIG.customOptions, ...options, }; super(dispensary, mergedOptions); } // Phase 1: No overrides - use base implementation // Future phases can add overrides here: // // async crawlProducts(): Promise { // // Custom pre-processing // // ... // const result = await super.crawlProducts(); // // Custom post-processing // // ... // return result; // } } // ============================================================ // EXPORTED CRAWL FUNCTION // ============================================================ /** * Main entry point for the orchestrator * * The orchestrator calls: mod.crawlProducts(dispensary, options) * This function creates a TrulieveScottsdaleCrawler and runs it. */ export async function crawlProducts( dispensary: Dispensary, options: StoreCrawlOptions = {} ): Promise { console.log(`[TrulieveScottsdale] Using per-store crawler for ${dispensary.name}`); const crawler = new TrulieveScottsdaleCrawler(dispensary, options); return crawler.crawlProducts(); } // ============================================================ // FACTORY FUNCTION (alternative API) // ============================================================ /** * Create a crawler instance without running it * Useful for testing or when you need to configure before running */ export function createCrawler( dispensary: Dispensary, options: StoreCrawlOptions = {} ): TrulieveScottsdaleCrawler { return new TrulieveScottsdaleCrawler(dispensary, options); }