import { pool } from './pool'; async function initDB() { const client = await pool.connect(); try { await client.query('BEGIN'); console.log('Creating tables...'); // 1. Catalogue Module await client.query(` CREATE TABLE IF NOT EXISTS drugs ( id VARCHAR(50) PRIMARY KEY, generic_name VARCHAR(255) NOT NULL, atc_code VARCHAR(50), schedule VARCHAR(20), is_nti BOOLEAN DEFAULT false, pregnancy_category VARCHAR(10) ); `); await client.query(` CREATE TABLE IF NOT EXISTS products ( id VARCHAR(50) PRIMARY KEY, drug_id VARCHAR(50) REFERENCES drugs(id), brand_name VARCHAR(255) NOT NULL, manufacturer VARCHAR(255), strength VARCHAR(50), form VARCHAR(50), mrp DECIMAL(10, 2), dpco_ceiling DECIMAL(10, 2) ); `); // 2. Inventory Module await client.query(` CREATE TABLE IF NOT EXISTS batches ( batch_no VARCHAR(100) PRIMARY KEY, product_id VARCHAR(50) REFERENCES products(id), expiry DATE NOT NULL, qty_on_hand INTEGER NOT NULL CHECK (qty_on_hand >= 0), purchase_price DECIMAL(10, 2), status VARCHAR(50) DEFAULT 'available' ); `); await client.query(` CREATE TABLE IF NOT EXISTS stock_movements ( id SERIAL PRIMARY KEY, batch_no VARCHAR(100) REFERENCES batches(batch_no), movement_type VARCHAR(50) NOT NULL, -- 'receipt', 'dispense', 'adjustment' qty_delta INTEGER NOT NULL, reference_id VARCHAR(100), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); `); // 3. Dispensing & Audit await client.query(` CREATE TABLE IF NOT EXISTS dispensing_records ( id VARCHAR(50) PRIMARY KEY, subject_ref VARCHAR(100) NOT NULL, tenant_id VARCHAR(50) NOT NULL, dispensed_by VARCHAR(100) NOT NULL, prescription_id VARCHAR(50), total_amount DECIMAL(10, 2) DEFAULT 0, payment_method VARCHAR(50) DEFAULT 'cash', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); `); await client.query(` CREATE TABLE IF NOT EXISTS overrides_log ( id SERIAL PRIMARY KEY, dispensing_id VARCHAR(50) REFERENCES dispensing_records(id), code VARCHAR(50) NOT NULL, reason TEXT NOT NULL, actor_user_id VARCHAR(100) NOT NULL, occurred_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); `); await client.query(` CREATE TABLE IF NOT EXISTS h1_registers ( id VARCHAR(50) PRIMARY KEY, dispensing_id VARCHAR(50) REFERENCES dispensing_records(id), patient_name VARCHAR(255) NOT NULL, prescriber_name VARCHAR(255), drug_name VARCHAR(255) NOT NULL, batch_no VARCHAR(100), qty INTEGER NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); `); await client.query(` CREATE TABLE IF NOT EXISTS order_drafts ( id VARCHAR(50) PRIMARY KEY, subject_ref VARCHAR(100), prescription_ref VARCHAR(50), items JSONB, status VARCHAR(20) DEFAULT 'draft', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); `); await client.query(` CREATE TABLE IF NOT EXISTS audit_logs ( id SERIAL PRIMARY KEY, call_id VARCHAR(100), actor_user_id VARCHAR(100), task_type VARCHAR(50), details JSONB, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); `); // 4. Phase 2: Prescriptions await client.query(` CREATE TABLE IF NOT EXISTS prescriptions ( id VARCHAR(50) PRIMARY KEY, image_path TEXT NOT NULL, image_hash VARCHAR(64) NOT NULL, status VARCHAR(20) DEFAULT 'processing', extracted_data JSONB, confirmed_data JSONB, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); `); console.log('Seeding initial data...'); // Seed Dummy Data for UI await client.query(` INSERT INTO drugs (id, generic_name, schedule) VALUES ('drg_001', 'Losartan Potassium', 'H'), ('drg_002', 'Sertraline', 'H') ON CONFLICT (id) DO NOTHING; `); await client.query(` INSERT INTO products (id, drug_id, brand_name, form, mrp) VALUES ('prd_4410', 'drg_001', 'Losar 50', 'tablet', 78.50), ('prd_5510', 'drg_002', 'Sertra 50', 'tablet', 110.00) ON CONFLICT (id) DO NOTHING; `); // Add batches. Let's add a near-expiry batch so the UI alert triggers await client.query(` INSERT INTO batches (batch_no, product_id, expiry, qty_on_hand, purchase_price) VALUES ('B4421', 'prd_4410', CURRENT_DATE + INTERVAL '15 days', 240, 50.00), ('B4630', 'prd_5510', CURRENT_DATE + INTERVAL '200 days', 500, 80.00) ON CONFLICT (batch_no) DO NOTHING; `); await client.query('COMMIT'); console.log('Database initialization and seeding completed successfully!'); } catch (error) { await client.query('ROLLBACK'); console.error('Error initializing database:', error); } finally { client.release(); pool.end(); } } initDB();