- Add backend stale process monitoring API (/api/stale-processes) - Add users management route - Add frontend landing page and stale process monitor UI on /scraper-tools - Move old development scripts to backend/archive/ - Update frontend build with new features 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
83 lines
2.7 KiB
TypeScript
83 lines
2.7 KiB
TypeScript
import { pool } from './src/db/migrate';
|
|
|
|
async function addGeoFields() {
|
|
console.log('🗺️ Adding geo-location fields...\n');
|
|
|
|
try {
|
|
await pool.query(`
|
|
ALTER TABLE stores
|
|
ADD COLUMN IF NOT EXISTS latitude DECIMAL(10, 8),
|
|
ADD COLUMN IF NOT EXISTS longitude DECIMAL(11, 8),
|
|
ADD COLUMN IF NOT EXISTS region VARCHAR(100),
|
|
ADD COLUMN IF NOT EXISTS market_area VARCHAR(255),
|
|
ADD COLUMN IF NOT EXISTS timezone VARCHAR(50)
|
|
`);
|
|
|
|
console.log('✅ Added geo fields to stores table');
|
|
|
|
// Create indexes for geo queries
|
|
await pool.query(`
|
|
CREATE INDEX IF NOT EXISTS idx_stores_location ON stores(latitude, longitude) WHERE latitude IS NOT NULL;
|
|
CREATE INDEX IF NOT EXISTS idx_stores_city_state ON stores(city, state);
|
|
CREATE INDEX IF NOT EXISTS idx_stores_region ON stores(region);
|
|
CREATE INDEX IF NOT EXISTS idx_stores_market ON stores(market_area);
|
|
`);
|
|
|
|
console.log('✅ Created geo indexes');
|
|
|
|
// Create location-based views
|
|
await pool.query(`
|
|
CREATE OR REPLACE VIEW stores_by_region AS
|
|
SELECT
|
|
region,
|
|
state,
|
|
COUNT(*) as store_count,
|
|
COUNT(DISTINCT city) as cities,
|
|
array_agg(DISTINCT name ORDER BY name) as store_names
|
|
FROM stores
|
|
WHERE active = true
|
|
GROUP BY region, state
|
|
ORDER BY store_count DESC
|
|
`);
|
|
|
|
await pool.query(`
|
|
CREATE OR REPLACE VIEW market_coverage AS
|
|
SELECT
|
|
city,
|
|
state,
|
|
zip,
|
|
COUNT(*) as dispensaries,
|
|
array_agg(name ORDER BY name) as store_names,
|
|
COUNT(DISTINCT id) as unique_stores
|
|
FROM stores
|
|
WHERE active = true
|
|
GROUP BY city, state, zip
|
|
ORDER BY dispensaries DESC
|
|
`);
|
|
|
|
console.log('✅ Created location views');
|
|
|
|
console.log('\n✅ Geo-location setup complete!');
|
|
console.log('\n📊 Available location views:');
|
|
console.log(' - stores_by_region: Stores grouped by region/state');
|
|
console.log(' - market_coverage: Dispensary density by city');
|
|
|
|
console.log('\n💡 Your database now supports:');
|
|
console.log(' ✅ Lead Generation (contact info + locations)');
|
|
console.log(' ✅ Market Research (pricing + inventory data)');
|
|
console.log(' ✅ Investment Planning (market coverage + trends)');
|
|
console.log(' ✅ Retail Partner Discovery (store directory)');
|
|
console.log(' ✅ Geo-targeted Campaigns (lat/long + regions)');
|
|
console.log(' ✅ Trend Analysis (price history + timestamps)');
|
|
console.log(' ✅ Directory/App Creation (full store catalog)');
|
|
console.log(' ✅ Delivery Optimization (locations + addresses)');
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error:', error);
|
|
} finally {
|
|
await pool.end();
|
|
}
|
|
}
|
|
|
|
addGeoFields();
|