Spaces:
Sleeping
Sleeping
File size: 6,294 Bytes
b802ed5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | from __future__ import annotations
import json
import os
import sqlite3
import uuid
from contextlib import contextmanager
from datetime import datetime, timezone
from pathlib import Path
from typing import Iterator
from .security import hash_password
def utc_now() -> str:
return datetime.now(timezone.utc).isoformat()
def new_id(prefix: str) -> str:
return f"{prefix}_{uuid.uuid4().hex[:16]}"
def database_path() -> Path:
return Path(os.getenv("SQLITE_PATH", "data/medbill.sqlite3")).expanduser()
def connect() -> sqlite3.Connection:
path = database_path()
path.parent.mkdir(parents=True, exist_ok=True)
connection = sqlite3.connect(path, check_same_thread=False)
connection.row_factory = sqlite3.Row
connection.execute("PRAGMA foreign_keys = ON")
return connection
@contextmanager
def get_connection() -> Iterator[sqlite3.Connection]:
connection = connect()
try:
yield connection
connection.commit()
finally:
connection.close()
SCHEMA = """
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'customer',
created_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS medicines (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
brand TEXT,
category TEXT NOT NULL,
composition TEXT NOT NULL,
price REAL NOT NULL,
mrp REAL,
rating REAL NOT NULL DEFAULT 4.5,
stock INTEGER NOT NULL DEFAULT 100,
prescription_required INTEGER NOT NULL DEFAULT 0,
uses TEXT NOT NULL DEFAULT '[]',
side_effects TEXT NOT NULL DEFAULT '[]',
safety_advice TEXT NOT NULL DEFAULT '',
manufacturer TEXT NOT NULL DEFAULT ''
);
CREATE TABLE IF NOT EXISTS orders (
id TEXT PRIMARY KEY,
user_id TEXT,
total REAL NOT NULL,
address TEXT,
status TEXT NOT NULL DEFAULT 'placed',
items TEXT NOT NULL DEFAULT '[]',
created_at TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS health_records (
id TEXT PRIMARY KEY,
user_id TEXT,
title TEXT NOT NULL,
record_type TEXT NOT NULL,
notes TEXT,
created_at TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS appointments (
id TEXT PRIMARY KEY,
user_id TEXT,
doctor_name TEXT NOT NULL,
specialty TEXT NOT NULL,
fee REAL NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
created_at TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
);
"""
MEDICINES = [
("prod-001", "Paracetamol 500mg", "MedBill", "Fever & Pain", "Pack of 10 tablets", 25, 30, 0),
("prod-002", "Azithromycin 500mg", "MedBill", "Antibiotics", "Pack of 5 tablets", 90, 110, 1),
("prod-003", "Cetirizine 10mg", "MedBill", "Allergy", "Pack of 10 tablets", 35, 42, 0),
("prod-004", "Vitamin D3 60K", "MedBill", "Vitamins", "Pack of 4 sachets", 120, 150, 0),
("prod-005", "Pantoprazole 40mg", "MedBill", "Acidity", "Pack of 15 tablets", 75, 95, 0),
("prod-006", "Insulin Glargine", "MedBill", "Diabetes", "3ml cartridge", 850, 950, 1),
("prod-007", "Amlodipine 5mg", "MedBill", "Heart Care", "Pack of 10 tablets", 45, 55, 1),
("prod-008", "Multivitamin", "MedBill", "Vitamins", "Pack of 30 tablets", 220, 280, 0),
("prod-009", "Cough Syrup", "MedBill", "Cold & Cough", "100ml bottle", 95, 120, 0),
("prod-010", "ORS Sachet", "MedBill", "Hydration", "Pack of 5 sachets", 50, 60, 0),
]
def init_db() -> None:
with get_connection() as connection:
connection.executescript(SCHEMA)
seed_data(connection)
def seed_data(connection: sqlite3.Connection) -> None:
now = utc_now()
connection.execute(
"""
INSERT OR IGNORE INTO users (id, name, email, password_hash, role, created_at)
VALUES (?, ?, ?, ?, ?, ?)
""",
(
"user-demo-aarav",
"Aarav Mehta",
"aarav@medbill.com",
hash_password("Secure@123"),
"customer",
now,
),
)
connection.execute(
"""
INSERT OR IGNORE INTO users (id, name, email, password_hash, role, created_at)
VALUES (?, ?, ?, ?, ?, ?)
""",
(
"user-demo-admin",
"System Admin",
"admin@medbill.com",
hash_password("Secure@123"),
"admin",
now,
),
)
for item in MEDICINES:
connection.execute(
"""
INSERT OR IGNORE INTO medicines (
id, name, brand, category, composition, price, mrp,
prescription_required, uses, side_effects, safety_advice, manufacturer
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""",
(
*item,
json.dumps(["Fever", "Pain relief"]),
json.dumps(["Nausea", "Stomach discomfort"]),
"Use as directed by a physician.",
"MedBill Pharmacy",
),
)
connection.execute(
"""
INSERT OR IGNORE INTO health_records (id, user_id, title, record_type, notes, created_at)
VALUES (?, ?, ?, ?, ?, ?)
""",
(
"record-demo-001",
"user-demo-aarav",
"Prescription",
"Prescription",
"AI extracted 3 medicines",
now,
),
)
def row_to_user(row: sqlite3.Row) -> dict:
return {
"_id": row["id"],
"id": row["id"],
"name": row["name"],
"email": row["email"],
"role": row["role"],
}
def row_to_medicine(row: sqlite3.Row) -> dict:
return {
"_id": row["id"],
"id": row["id"],
"name": row["name"],
"brand": row["brand"],
"category": row["category"],
"composition": row["composition"],
"price": row["price"],
"mrp": row["mrp"],
"rating": row["rating"],
"stock": row["stock"],
"prescriptionRequired": bool(row["prescription_required"]),
"uses": json.loads(row["uses"]),
"sideEffects": json.loads(row["side_effects"]),
"safetyAdvice": row["safety_advice"],
"manufacturer": row["manufacturer"],
}
|