Initial commit
This commit is contained in:
+167
@@ -0,0 +1,167 @@
|
||||
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();
|
||||
Reference in New Issue
Block a user