|
| 1 | +# 🏥 Medical Store Management System (MSMS) |
| 2 | + |
| 3 | +> **Student:** Muawiya Amir | **ID:** 2k24_BSAI_72 |
| 4 | +> **Course:** Database Lab — 4th Semester BS Artificial Intelligence |
| 5 | +> **Instructor:** Sir Ahsan Ahmed |
| 6 | +
|
| 7 | +--- |
| 8 | + |
| 9 | +## 🚦 How to Run (Quick Start) |
| 10 | + |
| 11 | +1. **Install dependencies** |
| 12 | + Open two terminals and run: |
| 13 | + - In `backend` folder: |
| 14 | + `npm install` |
| 15 | + - In `frontend` folder: |
| 16 | + `npm install` |
| 17 | + |
| 18 | +2. **Set up environment** |
| 19 | + - Copy `backend/.env.example` to `backend/.env` and fill in your MySQL info. |
| 20 | + |
| 21 | +3. **Set up the database** |
| 22 | + - Import all SQL files in `database/` into your MySQL server (see detailed steps below). |
| 23 | + |
| 24 | +4. **Start the servers** |
| 25 | + - In `backend`: |
| 26 | + `npm start` |
| 27 | + - In `frontend`: |
| 28 | + `npm run dev` |
| 29 | + |
| 30 | +5. **Open the app** |
| 31 | + - Frontend: [http://localhost:5173](http://localhost:5173) |
| 32 | + - Backend API: [http://localhost:5000](http://localhost:5000) |
| 33 | + |
| 34 | +--- |
| 35 | + |
| 36 | +## ✨ Features |
| 37 | + |
| 38 | +### Core Modules |
| 39 | + |
| 40 | +- **Inventory Management** — Add, edit, search medicines with dosage form, strength, price, and prescription flag |
| 41 | +- **Point of Sale (POS)** — Real-time cart, customer lookup, prescription validation, live total calculation |
| 42 | +- **Prescription Tracking** — Link doctor prescriptions to customers; enforce Rx-only sales |
| 43 | +- **Supplier Management** — Track suppliers with ratings and contact details |
| 44 | +- **Customer Management** — Profiles with purchase history and total spending |
| 45 | +- **Employee Management** — Role-based accounts (Admin / Manager / Pharmacist / Cashier) |
| 46 | +- **Payment Processing** — Cash, Card, Online, Insurance; full transaction log |
| 47 | +- **Reports & Analytics** — Low stock, expiry alerts, sales summary with charts, top-selling medicines |
| 48 | + |
| 49 | +### Database Features |
| 50 | + |
| 51 | +- 12 normalized tables (3NF) |
| 52 | +- 4 Triggers (stock deduction, low-stock alert, order total recalc, expiry check) |
| 53 | +- 4 Stored Procedures (GenerateBill, RestockMedicine, PlaceOrder, CompletePayment) |
| 54 | +- 7 Views (LowStockAlert, ExpiringSoon, SalesSummary, TopSellingMedicines, EmployeePerformance, SupplierRatings, FullInventory) |
| 55 | +- Indexes on high-frequency query columns |
| 56 | + |
| 57 | +### UI/UX Extras |
| 58 | + |
| 59 | +- 🌙 Dark mode (persisted in localStorage) |
| 60 | +- 🖨️ Printable invoices (`window.print()` hides sidebar/navbar) |
| 61 | +- 📥 PDF bill download (A5 size via jsPDF + html2canvas) |
| 62 | +- 📊 Sales bar chart (Recharts) |
| 63 | +- 📤 Export to CSV on every report tab |
| 64 | +- 🔔 Toast notifications for all actions |
| 65 | +- 🔴 Red dot badge on sidebar when medicines expire within 7 days |
| 66 | +- ⚠️ Low-stock banner on dashboard |
| 67 | +- JWT authentication with role-based route protection |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +## 🛠 Tech Stack |
| 72 | + |
| 73 | +| Layer | Technology | |
| 74 | +| -------- | ------------------------------------- | |
| 75 | +| Frontend | React 18, Vite, TailwindCSS, Recharts | |
| 76 | +| Backend | Node.js, Express 4, mysql2 | |
| 77 | +| Database | MySQL 8.0 | |
| 78 | +| Auth | JWT (jsonwebtoken) + bcryptjs | |
| 79 | +| Forms | react-hook-form + Zod validation | |
| 80 | +| PDF | jsPDF + html2canvas | |
| 81 | + |
| 82 | +--- |
| 83 | + |
| 84 | +## 📋 Prerequisites |
| 85 | + |
| 86 | +- **Node.js** v18 or higher |
| 87 | +- **npm** v9 or higher |
| 88 | +- **MySQL 8.0** running locally |
| 89 | + |
| 90 | +--- |
| 91 | + |
| 92 | +## 🚀 Installation & Setup |
| 93 | + |
| 94 | +### 1. Clone the repository |
| 95 | + |
| 96 | +```bash |
| 97 | +git clone "https://github.com/Coding-Moves/BSAI-Projects.git" |
| 98 | +cd msms |
| 99 | +``` |
| 100 | + |
| 101 | +### 2. Install all dependencies |
| 102 | + |
| 103 | +```bash |
| 104 | +npm run install:all |
| 105 | +``` |
| 106 | + |
| 107 | +This installs root, backend, and frontend packages in one command. |
| 108 | + |
| 109 | +### 3. Configure backend environment |
| 110 | + |
| 111 | +```bash |
| 112 | +cd backend |
| 113 | +cp .env.example .env |
| 114 | +``` |
| 115 | + |
| 116 | +Open `.env` and fill in your MySQL credentials: |
| 117 | + |
| 118 | +``` |
| 119 | +DB_HOST=localhost |
| 120 | +DB_PORT=3306 |
| 121 | +DB_USER=root |
| 122 | +DB_PASSWORD=your_mysql_password |
| 123 | +DB_NAME=msms_db |
| 124 | +JWT_SECRET=change_this_to_a_random_secret |
| 125 | +PORT=5000 |
| 126 | +``` |
| 127 | + |
| 128 | +### 4. Set up the MySQL database |
| 129 | + |
| 130 | +Open **MySQL Workbench** (or any MySQL client) and run the SQL files **in this exact order**: |
| 131 | + |
| 132 | +```sql |
| 133 | +-- Step 1: Create tables |
| 134 | +SOURCE /path/to/msms/database/schema.sql; |
| 135 | + |
| 136 | +-- Step 2: Insert sample data |
| 137 | +SOURCE /path/to/msms/database/sample_data.sql; |
| 138 | + |
| 139 | +-- Step 3: Create triggers |
| 140 | +SOURCE /path/to/msms/database/triggers.sql; |
| 141 | + |
| 142 | +-- Step 4: Create stored procedures |
| 143 | +SOURCE /path/to/msms/database/stored_procedures.sql; |
| 144 | + |
| 145 | +-- Step 5: Create views |
| 146 | +SOURCE /path/to/msms/database/views.sql; |
| 147 | + |
| 148 | +-- Step 6: Create indexes |
| 149 | +SOURCE /path/to/msms/database/indexes.sql; |
| 150 | +``` |
| 151 | + |
| 152 | +Or run them from the command line: |
| 153 | + |
| 154 | +```bash |
| 155 | +mysql -u root -p < database/schema.sql |
| 156 | +mysql -u root -p msms_db < database/sample_data.sql |
| 157 | +mysql -u root -p msms_db < database/triggers.sql |
| 158 | +mysql -u root -p msms_db < database/stored_procedures.sql |
| 159 | +mysql -u root -p msms_db < database/views.sql |
| 160 | +mysql -u root -p msms_db < database/indexes.sql |
| 161 | +``` |
| 162 | + |
| 163 | +### 5. Start the application |
| 164 | + |
| 165 | +```bash |
| 166 | +cd .. |
| 167 | +npm run dev |
| 168 | +``` |
| 169 | + |
| 170 | +This runs both frontend and backend concurrently: |
| 171 | + |
| 172 | +- **Backend API:** http://localhost:5000 |
| 173 | +- **Frontend:** http://localhost:5173 |
| 174 | + |
| 175 | +--- |
| 176 | + |
| 177 | +## 🔐 Default Login |
| 178 | + |
| 179 | +| Username | Password | Role | |
| 180 | +| -------- | ---------- | ----- | |
| 181 | +| `admin` | `admin123` | Admin | |
| 182 | + |
| 183 | +> ⚠️ Change the default password immediately after first login in production. |
| 184 | +
|
| 185 | +--- |
| 186 | + |
| 187 | +## 🗂 Project Structure |
| 188 | + |
| 189 | +``` |
| 190 | +msms/ |
| 191 | +├── README.md |
| 192 | +├── package.json ← root (concurrently) |
| 193 | +├── .gitignore |
| 194 | +│ |
| 195 | +├── docs/ |
| 196 | +| ├── report.pdf |
| 197 | +| ├── proposal.pdf |
| 198 | +| ├── manual.pdf |
| 199 | +| ├── ER_diagram.pdf |
| 200 | +| |
| 201 | +├── backend/ |
| 202 | +│ ├── server.js ← Express entry point |
| 203 | +│ ├── db.js ← MySQL connection pool |
| 204 | +│ ├── .env.example |
| 205 | +│ ├── routes/ |
| 206 | +│ │ ├── auth.js ← POST /auth/login, GET /auth/me |
| 207 | +│ │ ├── medicines.js |
| 208 | +│ │ ├── categories.js |
| 209 | +│ │ ├── manufacturers.js |
| 210 | +│ │ ├── suppliers.js |
| 211 | +│ │ ├── stock.js ← includes POST /restock |
| 212 | +│ │ ├── customers.js |
| 213 | +│ │ ├── doctors.js |
| 214 | +│ │ ├── employees.js |
| 215 | +│ │ ├── prescriptions.js |
| 216 | +│ │ ├── orders.js ← includes bill + complete endpoints |
| 217 | +│ │ ├── payments.js |
| 218 | +│ │ └── reports.js ← calls all 4 views + dashboard stats |
| 219 | +│ └── middleware/ |
| 220 | +│ ├── auth.js ← JWT verify + role authorize |
| 221 | +│ └── validate.js ← express-validator error handler |
| 222 | +│ |
| 223 | +├── frontend/ |
| 224 | +│ └── src/ |
| 225 | +│ ├── App.jsx ← all routes defined here |
| 226 | +│ ├── api/index.js ← axios instance + all API helpers |
| 227 | +│ ├── context/ |
| 228 | +│ │ ├── AuthContext.jsx |
| 229 | +│ │ └── CartContext.jsx |
| 230 | +│ ├── components/ |
| 231 | +│ │ ├── Layout/ ← Sidebar, Navbar, ProtectedRoute |
| 232 | +│ │ ├── UI/ ← Modal, Badge, StatCard, SearchBar, ConfirmDialog, Pagination, CrudPage |
| 233 | +│ │ └── Bill/ ← BillPreview, BillActions |
| 234 | +│ └── pages/ |
| 235 | +│ ├── Login.jsx |
| 236 | +│ ├── Dashboard.jsx |
| 237 | +│ ├── Inventory/ ← MedicineList, StockList |
| 238 | +│ ├── Sales/ ← NewOrder (POS), OrderList, OrderDetail |
| 239 | +│ ├── Customers/ |
| 240 | +│ ├── Suppliers/ |
| 241 | +│ ├── Doctors/ |
| 242 | +│ ├── Employees/ |
| 243 | +│ ├── Prescriptions/ |
| 244 | +│ ├── Payments/ |
| 245 | +│ └── Reports/ ← 4-tab report page with chart + CSV export |
| 246 | +│ |
| 247 | +└── database/ |
| 248 | + ├── schema.sql ← 12 tables + 2 auxiliary tables |
| 249 | + ├── sample_data.sql ← Pakistani context sample data |
| 250 | + ├── triggers.sql ← 4 triggers |
| 251 | + ├── stored_procedures.sql ← 4 procedures |
| 252 | + ├── views.sql ← 7 views |
| 253 | + └── indexes.sql ← performance indexes |
| 254 | +``` |
| 255 | + |
| 256 | +--- |
| 257 | + |
| 258 | +## 🌐 API Endpoints |
| 259 | + |
| 260 | +### Auth |
| 261 | + |
| 262 | +| Method | Endpoint | Description | |
| 263 | +| ------ | -------------------- | -------------- | |
| 264 | +| POST | `/api/v1/auth/login` | Login, get JWT | |
| 265 | +| GET | `/api/v1/auth/me` | Current user | |
| 266 | + |
| 267 | +### Resources (all support GET / GET /:id / POST / PUT /:id / DELETE /:id) |
| 268 | + |
| 269 | +`/api/v1/categories`, `/api/v1/manufacturers`, `/api/v1/suppliers`, |
| 270 | +`/api/v1/medicines`, `/api/v1/doctors`, `/api/v1/customers`, |
| 271 | +`/api/v1/employees`, `/api/v1/prescriptions`, `/api/v1/payments` |
| 272 | + |
| 273 | +### Stock |
| 274 | + |
| 275 | +| Method | Endpoint | Description | |
| 276 | +| ------ | ----------------------- | ------------------ | |
| 277 | +| GET | `/api/v1/stock` | All stock records | |
| 278 | +| POST | `/api/v1/stock/restock` | Restock a medicine | |
| 279 | + |
| 280 | +### Orders |
| 281 | + |
| 282 | +| Method | Endpoint | Description | |
| 283 | +| ------ | ----------------------------- | --------------------------------- | |
| 284 | +| GET | `/api/v1/orders` | List orders (paginated) | |
| 285 | +| POST | `/api/v1/orders` | Place order + optional payment | |
| 286 | +| GET | `/api/v1/orders/:id` | Order detail with items | |
| 287 | +| GET | `/api/v1/orders/:id/bill` | Full bill (calls GenerateBill SP) | |
| 288 | +| POST | `/api/v1/orders/:id/complete` | Complete payment | |
| 289 | +| PUT | `/api/v1/orders/:id/cancel` | Cancel pending order | |
| 290 | + |
| 291 | +### Reports |
| 292 | + |
| 293 | +| Method | Endpoint | Description | |
| 294 | +| ------ | -------------------------------------- | ---------------------- | |
| 295 | +| GET | `/api/v1/reports/dashboard-stats` | 6 dashboard KPIs | |
| 296 | +| GET | `/api/v1/reports/low-stock` | vw_LowStockAlert | |
| 297 | +| GET | `/api/v1/reports/expiring-soon` | vw_ExpiringSoon | |
| 298 | +| GET | `/api/v1/reports/sales-summary` | vw_SalesSummary | |
| 299 | +| GET | `/api/v1/reports/top-medicines` | vw_TopSellingMedicines | |
| 300 | +| GET | `/api/v1/reports/employee-performance` | vw_EmployeePerformance | |
| 301 | + |
| 302 | +--- |
| 303 | + |
| 304 | +## 🗄 Database Schema (12 Tables) |
| 305 | + |
| 306 | +| Table | Primary Key | Purpose | |
| 307 | +| --------------- | ----------------- | ----------------------------------------- | |
| 308 | +| `categories` | `category_id` | Medicine classifications | |
| 309 | +| `manufacturers` | `manufacturer_id` | Pharma companies | |
| 310 | +| `suppliers` | `supplier_id` | Stock suppliers with ratings | |
| 311 | +| `medicines` | `medicine_id` | Core medicine catalog | |
| 312 | +| `stock` | `stock_id` | Quantity, batch, expiry per medicine | |
| 313 | +| `doctors` | `doctor_id` | Licensed doctors for prescriptions | |
| 314 | +| `customers` | `customer_id` | Customer profiles | |
| 315 | +| `employees` | `employee_id` | Staff with roles and credentials | |
| 316 | +| `prescriptions` | `prescription_id` | Doctor → Customer prescriptions | |
| 317 | +| `orders` | `order_id` | Master order with discount/tax | |
| 318 | +| `order_items` | `item_id` | Line items (subtotal is GENERATED column) | |
| 319 | +| `payments` | `payment_id` | Payment method and status per order | |
| 320 | + |
| 321 | +--- |
| 322 | + |
| 323 | +## 📸 Screenshots |
| 324 | + |
| 325 | +> _(Add screenshots here after first run)_ |
| 326 | +
|
| 327 | +- `screenshots/login.png` |
| 328 | +- `screenshots/dashboard.png` |
| 329 | +- `screenshots/pos.png` |
| 330 | +- `screenshots/bill-preview.png` |
| 331 | +- `screenshots/reports.png` |
| 332 | + |
| 333 | +--- |
| 334 | + |
| 335 | +## 👤 Author |
| 336 | + |
| 337 | +**Moavia Amir** |
| 338 | +Student ID: 2k24_BSAI_72 |
| 339 | +BS Artificial Intelligence — 4th Semester |
| 340 | +Database Lab | Instructor: Sir Ahsan Ahmed |
0 commit comments