- 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>
62 lines
2.4 KiB
TypeScript
62 lines
2.4 KiB
TypeScript
import { pool } from './src/db/migrate';
|
|
|
|
async function createBrandsTables() {
|
|
console.log('📦 Creating brands tracking tables...\n');
|
|
|
|
try {
|
|
// Brands table - stores unique brands across all stores
|
|
await pool.query(`
|
|
CREATE TABLE IF NOT EXISTS brands (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) UNIQUE NOT NULL,
|
|
logo_url TEXT,
|
|
first_seen_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
last_seen_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`);
|
|
console.log('✅ Created brands table');
|
|
|
|
// Store-Brand relationship - tracks which brands are at which stores
|
|
await pool.query(`
|
|
CREATE TABLE IF NOT EXISTS store_brands (
|
|
id SERIAL PRIMARY KEY,
|
|
store_id INTEGER REFERENCES stores(id) ON DELETE CASCADE,
|
|
brand_id INTEGER REFERENCES brands(id) ON DELETE CASCADE,
|
|
first_seen_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
last_seen_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
active BOOLEAN DEFAULT true,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE(store_id, brand_id)
|
|
)
|
|
`);
|
|
console.log('✅ Created store_brands table');
|
|
|
|
// Add indexes for performance
|
|
await pool.query(`
|
|
CREATE INDEX IF NOT EXISTS idx_store_brands_store_id ON store_brands(store_id);
|
|
CREATE INDEX IF NOT EXISTS idx_store_brands_brand_id ON store_brands(brand_id);
|
|
CREATE INDEX IF NOT EXISTS idx_store_brands_active ON store_brands(active);
|
|
CREATE INDEX IF NOT EXISTS idx_brands_name ON brands(name);
|
|
`);
|
|
console.log('✅ Created indexes');
|
|
|
|
console.log('\n✅ Brands tables created successfully!');
|
|
console.log('\nTable structure:');
|
|
console.log(' brands: Stores unique brand names and logos');
|
|
console.log(' store_brands: Tracks which brands are at which stores with timestamps');
|
|
console.log('\nReports you can run:');
|
|
console.log(' - Brand exposure: How many stores carry each brand');
|
|
console.log(' - Brand timeline: When brands were added/removed from stores');
|
|
console.log(' - Store changes: Which brands were added/dropped at a store');
|
|
} catch (error) {
|
|
console.error('❌ Error:', error);
|
|
} finally {
|
|
await pool.end();
|
|
}
|
|
}
|
|
|
|
createBrandsTables();
|