Files
AI_Pharmacy_Api/src/db/init.ts
T
2026-07-29 11:38:27 +05:30

168 lines
5.1 KiB
TypeScript

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();