Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
91 changes: 52 additions & 39 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,45 +1,58 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
# System Files
.DS_Store
*.pem

# debug
Thumbs.db
*.swp

# Node.js / Frontend
node_modules/
dist/
build/
.next/
coverage/
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
# Python / Backend
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
.venv/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
.pytest_cache/
.coverage
htmlcov/
.env

# Editor / IDE
.vscode/
.idea/
*.sublime-workspace

# Antigravity/Gemini
.gemini/

# User requested ignores
*.md
!README.md
64 changes: 64 additions & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# Virtual environments
venv/
.env/
.venv/
env/
ENV/

# Environment & secrets
*.env
.env.*
!example.env

# FastAPI / Uvicorn logs
*.log

# Python packaging
build/
dist/
.eggs/
*.egg-info/
.installed.cfg

# Test / coverage
.coverage
htmlcov/
.tox/
.nox/
.pytest_cache/

# IDE / editor settings
.vscode/
.idea/
*.swp
*.swo
*.bak

# OS-specific
.DS_Store
Thumbs.db

# Migrations cache (if any generated)
alembic.ini~
alembic/**/__pycache__/

# Jupyter (if you use notebooks for experiments)
.ipynb_checkpoints/

# Kaggle / datasets cache (optional)
.kaggle/
data/
datasets/

# MyPy / type checking
.mypy_cache/

# PyInstaller
*.spec

node_modules
68 changes: 68 additions & 0 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Telemedicine Backend

Node.js Backend for the Telemedicine Platform, handling Authentication, Pharmacy, and Appointments.

## Prerequisites
- Node.js (v16+)
- MySQL Server

## Setup

1. **Install Dependencies**:
```bash
npm install
# or
yarn install
```

2. **Database Setup**:
- Create a MySQL database (default name: `telemed_db`).
- Configure `.env` file (copy from `.env.example`):
```ini
PORT=5000
DB_HOST=localhost
DB_USER=root
DB_PASS=yourpassword
DB_NAME=telemed_db
JWT_SECRET=supersecretkey123
```

3. **Run Server**:
```bash
npm start
# or for development
npm run dev
```
The server will start on port 5000 and automatically create the required database tables (`Users`, `Doctors`, `Appointments`, `Inventories`, `Orders`) on the first run.

## API Usage & Frontend Integration

### Authentication
- **Register**: `POST /api/register`
- Body: `{ "name": "John", "email": "john@test.com", "password": "123", "role": "patient" }`
- Roles: `patient`, `doctor`, `pharmacist`
- **Login**: `POST /api/login`
- Body: `{ "email": "john@test.com", "password": "123" }`
- Response: `{ "token": "jwt_token_here", "role": "patient", ... }`
- **frontend**: Store `token` in localStorage. Send in headers: `Authorization: Bearer <token>`.

### Appointments (Doctor Profile)
- **Get Queue (Doctor)**: `GET /api/appointments/doctor`
- Headers: `Authorization: Bearer <token>`
- **Book (Patient)**: `POST /api/appointments`
- Body: `{ "doctorId": 1, "date": "2024-01-01 10:00", "symptoms": "Fever" }`
- **Note**: The backend automatically sets `aiRiskScore` and `priorityFlag` for demo purposes.

### Pharma
- **Get Inventory**: `GET /api/pharma/inventory`
- **Order Medicine**: `POST /api/pharma/orders`
- Body: `{ "medicineId": 1, "quantity": 2 }`

## Testing Flow
1. Start Backend.
2. Use Postman or Frontend to **Register** a Doctor (`role: "doctor"`).
3. **Register** a Patient (`role: "patient"`).
4. **Login** as Patient.
5. **Book Appointment** with Doctor ID 1.
6. **Login** as Doctor.
7. **Get Queue** to see the patient's request.
Empty file added backend/app/__init__.py
Empty file.
Empty file added backend/app/api/__init__.py
Empty file.
Empty file.
Empty file added backend/app/core/__init__.py
Empty file.
Empty file added backend/app/db/__init__.py
Empty file.
9 changes: 9 additions & 0 deletions backend/app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from fastapi import FastAPI

app = FastAPI(title="Telemed Web")

@app.get("/")
async def read_root():
return {"message": "Hello World"}


Empty file added backend/app/models/__init__.py
Empty file.
Empty file added backend/app/schemas/__init__.py
Empty file.
Empty file.
Empty file added backend/app/utils/__init__.py
Empty file.
39 changes: 39 additions & 0 deletions backend/config/database.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require('dotenv').config();
const { Sequelize } = require('sequelize');

// Create database if it doesn't exist
const createDatabaseIfNotExists = async () => {
const tempSequelize = new Sequelize('', process.env.DB_USER, process.env.DB_PASS, {
host: process.env.DB_HOST,
dialect: 'mysql',
logging: false,
});

try {
await tempSequelize.query(`CREATE DATABASE IF NOT EXISTS \`${process.env.DB_NAME}\`;`);
console.log('Database created or already exists');
} catch (error) {
console.error('Error creating database:', error);
} finally {
await tempSequelize.close();
}
};

const sequelize = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASS,
{
host: process.env.DB_HOST,
dialect: 'mysql',
logging: false,
}
);

// Initialize database creation
// createDatabaseIfNotExists();

module.exports = {
sequelize,
createDatabaseIfNotExists
};
61 changes: 61 additions & 0 deletions backend/controllers/appointmentController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const { Appointment, Doctor, Patient } = require('../models');

// Get Doctor Appointments (Doctor view)
exports.getDoctorAppointments = async (req, res) => {
try {
// Since the user is logged in as a doctor, req.user.user_id IS the doctor's ID.
const doctorId = req.user.user_id;

const appointments = await Appointment.findAll({
where: { doctorId: doctorId },
include: [{ model: Patient, as: 'patient', attributes: ['name', 'email'] }]
});

res.status(200).json(appointments);
} catch (err) {
console.error(err);
res.status(500).send("Error fetching appointments");
}
};

// Book Appointment (Patient view)
exports.bookAppointment = async (req, res) => {
try {
const { doctorId, date, symptoms, type } = req.body;

// AI Score Mock logic (In real app, call python service or logic here)
const riskScores = ['Low', 'Medium', 'High'];
const aiRiskScore = riskScores[Math.floor(Math.random() * riskScores.length)];
const priorityFlag = aiRiskScore === 'High';

const appointment = await Appointment.create({
patientId: req.user.user_id,
doctorId,
date,
symptoms,
type: type || 'Video Consult',
aiRiskScore,
priorityFlag,
status: 'Pending',
summary: 'Automated AI Check: ' + aiRiskScore + ' Risk detected based on symptoms.'
});

res.status(201).json(appointment);
} catch (err) {
console.log(err);
res.status(500).send("Error booking appointment");
}
};

// Update Status (Doctor)
exports.updateStatus = async (req, res) => {
try {
const { id } = req.params;
const { status } = req.body;

await Appointment.update({ status }, { where: { id } });
res.status(200).json({ message: "Updated successfully" });
} catch (err) {
res.status(500).send("Error updating appointment");
}
}
Loading