A comprehensive, enterprise-grade clinic management system built with ASP.NET Core 10.0, featuring advanced authentication, real-time appointment scheduling, medical records management, and automated payment processing.
✨ Features • 🏗️ Architecture • 💻 Installation • 🌐 API Docs • 🗄️ Database
- 🎯 Overview
- ✨ Key Features
- 🏗️ Architecture
- 🛠️ Technologies Used
- 🗄️ Database Schema
- 🔐 Authentication & Authorization
- 🌐 API Endpoints
- 💻 Installation
- ⚙️ Configuration
- 🔮 Future Enhancements
- 🤝 Contributing
- 👨💻 Author
Elite Clinic Management System is a modern, full-featured healthcare management platform designed to streamline clinic operations. Built with Clean Architecture principles and implementing CQRS pattern with MediatR, this system provides a robust solution for managing patients, doctors, appointments, medical records, prescriptions, and payments.
- ✅ Production-Ready: Enterprise-level code quality with proper error handling and logging
- ✅ Scalable Architecture: Clean Architecture ensures maintainability and testability
- ✅ Security First: JWT authentication, role-based authorization, and email confirmation
- ✅ Real-Time Operations: Background job processing with Hangfire
- ✅ Comprehensive API: RESTful API with Swagger documentation
- ✅ Email Automation: Professional HTML email templates for all notifications
Advanced Security Features:
- 🔑 JWT-based authentication with Access & Refresh Tokens
- 🔒 Secure password hashing using ASP.NET Core Identity
- ✉️ Email confirmation for new account activation
- 🔄 Password reset functionality with secure token encoding
- 👥 Role-based authorization (Admin, Doctor, Patient)
- 🔁 Refresh token rotation with automatic revocation
- ⏰ Token expiration handling with configurable timeouts
- 🔐 Account lockout after failed login attempts (5 attempts)
Key Components:
- Access Token: Short-lived (configurable, default: 60 minutes)
- Refresh Token: Long-lived (default: 30 days) with database storage
- Email confirmation required before account activation
- Encrypted tokens for password reset with URL-safe encoding
The system integrates Google OAuth 2.0 to provide frictionless patient access while strictly maintaining database integrity for medical records:
- Two-Step Onboarding (Data Integrity): Solves the "missing provider data" problem. If a new Google user logs in, the system halts creation and returns a
RequiresCompletionflag, ensuring mandatory clinic fields (Phone, DateOfBirth, ...) are captured via a dedicated command before generating the JWT. - Smart Account Linking: Automatically detects if a Google email matches an existing traditionally-registered account and authenticates the user instantly without duplicating records.
- Passwordless Provisioning: Dynamically provisions verified ASP.NET Identity users (
EmailConfirmed = true) purely for the"Patient"role, without requiring dummy passwords or breaking existing validation rules.
In this project, Redis is used for two main reasons: to make the API run much faster and to protect it from hackers.
- Faster Responses (Caching): Frequently requested data (like available doctor appointments) is saved in Redis. This means the API doesn't have to query the SQL database every time, reducing response times to just a few milliseconds.
- Smart Cache Updates: When new data is added (like booking a new appointment), the system only deletes the specific cached data related to it using key prefixes, instead of clearing the whole cache.
- Blocking Attackers (Rate Limiting): Redis is used to track user requests. If an IP address or a specific user sends too many requests quickly (like trying to guess a password), the system blocks them. Their IP is added to a "Blacklist" in Redis for 24 hours to stop brute-force attacks.
- Safe Reconnection: If the Redis server temporarily disconnects, the application automatically tries to reconnect safely without crashing the whole system.
To protect the API from abuse and brute‑force attempts, the system uses ASP.NET Core Rate Limiting combined with Redis for threat tracking:
- Global limiter is enabled for all requests in the pipeline via
app.UseRateLimiter(). - Requests are partitioned to enforce fair limits:
- Authenticated users are rate-limited by User ID (e.g., 100 requests/min).
- Anonymous users are rate-limited by IP address (e.g., 60 requests/min).
- A dedicated
AuthLimiterpolicy (Sliding Window) is applied to sensitive endpoints (e.g., login / account actions):- 5 requests per minute per IP.
QueueLimit = 0(reject immediately once limit is exceeded).
- Unified Rejection & Threat Tracking (OnRejected):
- Returns HTTP 429 (Too Many Requests) with a standard JSON response.
- Security Auditing: Blocked requests are dynamically intercepted. Attacker metadata (IP address, UserID, Target Endpoint, and Timestamp) is immediately logged via Serilog.
- Blacklist Tracking: The attacker's record is temporarily stored in Redis with a 24-hour TTL, laying the groundwork for real-time admin monitoring dashboards.
This project includes a docker-compose.yml to quickly run the required infrastructure services:
- SQL Server 2022 container (persistent data via a named volume)
- Redis container (used for caching)
Make sure you have
SQL_PORT,SQL_PASSWORD, andREDIS_PORTset (e.g., in your shell environment).
docker compose up -ddocker compose down- SQL Server runs on:
${SQL_PORT}:1433 - Redis runs on:
${REDIS_PORT}:6379 - SQL Server data is stored in the
sql_data_newvolume.
To ensure high performance, reliability, and loose coupling, the system implements an Event-Driven Architecture utilizing RabbitMQ as the message broker, orchestrated by MassTransit. This transitions the application from a traditional synchronous request-response monolith to a highly scalable, distributed system.
- Asynchronous Processing: Time-consuming infrastructure tasks, such as sending emails (e.g., User Registration, Password Reset, Appointment Confirmations, and Medical Reports), are entirely offloaded to background consumers. This drastically reduced API response times from several seconds to a few milliseconds.
- Fault Tolerance & Resilience (Retry Policy): Implemented a robust Incremental Retry Policy. If a third-party service (like an SMTP server) experiences a transient network drop, the system automatically retries processing the message with exponential backoff, ensuring zero data loss.
- Smart Error Handling: Permanent logical errors (e.g.,
ArgumentNullException) explicitly bypass the retry mechanism and are routed directly to a Dead Letter Queue (Error Queue), conserving CPU resources and keeping logs clean. - Architectural Decoupling: Adhering strictly to Clean Architecture, the Application layer only publishes "Fat Events" containing plain data state. It is completely unaware of how emails are constructed or sent, leaving template rendering and SMTP communication exclusively to the Infrastructure's consumer layer.
Below is a snapshot of our RabbitMQ Management Dashboard, actively monitoring message queues, throughput rates, and consumer acknowledgments:
The project utilizes GitHub Actions to automate the development lifecycle, ensuring strict code quality and preparing for rapid delivery:
- Automated Guardrails (CI): Every push or Pull Request automatically triggers an isolated cloud runner to build and test the
.slnxsolution, preventing broken code or syntax errors from merging into themainbranch. - Future-Ready Delivery (CD): The workflow architecture is structured to support Continuous Deployment. Once a production server is provisioned, verified builds will be automatically deployed to the live environment, eliminating manual deployment bottlenecks and human errors.
The system uses SignalR (WebSockets) to provide instant updates and automate clinic workflows without client-side polling:
- A dedicated
INotificationsServiceabstraction is used in the Application Layer. - Targeted Delivery: Uses
Clients.User(IdentityUserId)to securely send private alerts (e.g., new/canceled bookings) ONLY to the specific doctor. - Role-Based Broadcasting: Uses
Clients.Group("Admins")to instantly notify reception staff when a doctor completes an appointment and the prescription is ready. - Stateless Live Queue: Introduced a
CallPatientCommandthat broadcasts a payload directly to"WaitingRoomScreens"for audiovisual alerts without database overhead. - Unified Payload: All events share a standard
NotificationDTOcontract (Title,Message,NotificationType,RelatedEntityId) to seamlessly drive frontend UI state.
Complete Patient Lifecycle:
- 📝 Patient registration with automatic email confirmation
- 👤 Comprehensive patient profiles (demographics, contact info, medical history)
- 📊 Medical history tracking across all appointments
- 📅 Complete appointment history with status tracking
- 🔍 Advanced search by name, phone, or patient ID
- 🗑️ Soft delete support for data retention and compliance
- 📄 Pagination support for handling large patient databases
- 📧 Automated welcome emails with account details
Doctor Administration:
- ✏️ Create, update, and manage doctor profiles
- 🏥 Specialization-based categorization and filtering
- 📅 Doctor availability and schedule management
- 📊 Track doctor appointments and patient load
- 📈 Doctor revenue tracking and statistics
- 🔍 Search by specialization, name, or ID
- 👑 Promote doctors to Admin role
- 🗑️ Soft and hard delete options
Smart Scheduling Features:
- 🗓️ Real-time availability checking for doctor slots
- ⏰ Configurable time slots (default: 15-minute intervals)
- 📋 Multiple appointment statuses:
- Pending (initial booking)
- Confirmed (after payment)
- Completed (visit done)
- Cancelled (by patient or admin)
- Rescheduled (new time assigned)
- NoShow (patient didn't arrive)
- 🔄 Appointment rescheduling with automatic notifications
- ❌ Cancellation system with email alerts
- 📊 Statistics dashboard for admins
- 📧 Automated email notifications for all status changes
- 🕒 Auto-cancellation of unpaid appointments after 30 minutes (Hangfire job)
- 📈 Past appointment tracking for doctors and patients
Email Notifications:
Comprehensive Payment System:
- 💰 Multiple payment methods (Cash, Credit Card, Insurance)
- 📊 Payment status tracking (Pending, Completed, Failed, Refunded)
- 💵 Automatic amount calculation based on appointment
- 📧 Payment confirmation emails with transaction details
- 📈 Daily revenue reports for administrators
- 💼 Doctor revenue tracking and analytics
- 🔍 Payment history for patients and appointments
- 🧾 Transaction ID generation and tracking
Clinical Documentation:
- 📝 Create detailed medical records for each appointment
- 🩺 Record diagnosis, visit descriptions, and clinical notes
- 💊 Multi-prescription support per medical record
- 📋 Prescription details:
- Medication name and dosage
- Frequency and administration instructions
- Start and end dates
- Special instructions
- 🔒 Secure access control (only doctors and admins can create)
- 📖 Patient access to their own medical history
- 📊 Complete medical record tracking
Professional Email Templates:
Automated Emails:
- ✅ Account confirmation with branded templates
- 🔑 Password reset with secure token links
- 📅 Appointment booking confirmation
- 💳 Payment confirmation with receipt details
- ❌ Appointment cancellation notifications
- 🔄 Appointment rescheduling alerts
- 🚫 No-show notifications for missed appointments
- 📋 Medical record/prescription delivery
Email Infrastructure:
- 🎨 Professional HTML templates with responsive design
- ⚡ Background job processing using Hangfire
- 📧 SMTP configuration (Gmail integration ready)
- 🔁 Retry mechanism for failed email delivery
- 📊 Email tracking and logging
Pagination & Filtering:
- 📄 Server-side pagination for all list endpoints
- 🔍 Advanced filtering by status, date, doctor, patient
- 📈 Sorting capabilities for all data tables
- ⚡ Performance optimized queries with EF Core
Background Jobs (Hangfire):
- ⏰ Scheduled tasks for appointment management
- 🔄 Recurring jobs for data cleanup
- 📧 Email queue processing with retry logic
- 🗑️ Auto-cancellation of unpaid appointments
- 📊 Dashboard monitoring for job execution
Logging & Monitoring:
- 📝 Serilog integration with file and console logging
- 🔍 Request/Response logging for debugging
⚠️ Error tracking with detailed stack traces- 📊 Performance monitoring of database queries
Validation & Error Handling:
- ✅ FluentValidation for request validation
- 🛡️ Global exception handling middleware
- 📋 Consistent API responses with status codes
- 🔒 Business rule enforcement at application layer
The system follows Clean Architecture with clear separation of concerns and CQRS pattern implementation:
Elite-Clinic-System/
│
├── Clinic System.API/ # 🌐 Presentation Layer
│ ├── Controllers/ # API Controllers (Doctors, Patients, Appointments, etc.)
│ ├── Middlewares/ # Global Error Handler, Logging
│ ├── Bases/ # Base Controller with MediatR
│ └── Program.cs # App Configuration & Dependency Injection
│
├── Clinic System.Application/ # 📋 Application Layer (Business Logic)
│ ├── Features/ # ⚡ CQRS Implementation
│ │ ├── Patients/ # Patient Commands & Queries
│ │ │ ├── Commands/ # Create, Update, Delete Patient
│ │ │ └── Queries/ # Get Patient, List Patients, Search
│ │ ├── Doctors/ # Doctor Commands & Queries
│ │ ├── Appointments/ # Appointment Management
│ │ ├── Authentication/ # Login, Register, Password Reset
│ │ ├── Authorization/ # Role Management
│ │ ├── Payments/ # Payment Processing
│ │ ├── MedicalRecords/ # Medical Records Management
│ │ └── Prescriptions/ # Prescription Management
│ ├── DTOs/ # 📦 Data Transfer Objects
│ ├── Mappings/ # 🔄 AutoMapper Profiles
│ ├── Validators/ # ✅ FluentValidation Rules
│ ├── Behaviors/ # 🔧 MediatR Pipeline Behaviors
│ └── Services/ # 🛠️ Application Services & Interfaces
│
├── Clinic System.Core/ # 🎯 Domain Layer (Entities & Business Rules)
│ ├── Entities/ # Domain Models
│ │ ├── Doctor.cs
│ │ ├── Patient.cs
│ │ ├── Appointment.cs
│ │ ├── MedicalRecord.cs
│ │ ├── Prescription.cs
│ │ └── Payment.cs
│ ├── Enums/ # Domain Enums
│ │ ├── AppointmentStatus.cs
│ │ ├── PaymentStatus.cs
│ │ ├── PaymentMethod.cs
│ │ └── Gender.cs
│ ├── Interfaces/ # Repository & Service Contracts
│ │ ├── IRepository.cs
│ │ └── IUnitOfWork.cs
│ └── Exceptions/ # Custom Exception Classes
│
├── Clinic System.Data/ # 💾 Data Access Layer (Persistence)
│ ├── Context/ # DbContext Configuration
│ ├── Configurations/ # EF Core Entity Configurations
│ ├── Migrations/ # Database Migrations
│ ├── Repository/ # Repository Pattern Implementation
│ │ ├── GenericRepository.cs
│ │ ├── RepositoriesForEntities/
│ │ └── UnitOfWork/
│ └── Seeders/ # Initial Data Seeding
│
└── Clinic System.Infrastructure/ # 🔧 Infrastructure Layer (External Services)
├── Authentication/ # JWT Token Generation & Validation
├── Authorization/ # Role & Permission Management
├── Identity/ # ASP.NET Core Identity Setup
├── Services/ # External Service Implementations
│ ├── Email/ # Email Service (SMTP)
│ │ ├── EmailService.cs
│ │ ├── AppointmentEmailNotificationService.cs
│ │ └── EmailTemplates.cs
│ ├── AppointmentService.cs
│ ├── DoctorService.cs
│ ├── PatientService.cs
│ └── CurrentUserService.cs
└── Helpers/ # Helper Classes & Extensions
- Clean Architecture: Separation of concerns with independent layers
- CQRS Pattern: Command Query Responsibility Segregation with MediatR
- Repository Pattern: Data access abstraction
- Unit of Work Pattern: Transaction management
- Dependency Injection: Loose coupling and testability
- Strategy Pattern: Payment method handling
- Factory Pattern: Entity creation and initialization
- Mediator Pattern: Decoupled request/response handling
- ASP.NET Core 10.0 - Modern web framework
- C# 12 - Latest C# features
- Microsoft SQL Server - Enterprise database
- Entity Framework Core 10.0 - ORM with Code-First approach
- LINQ - Type-safe queries
- ASP.NET Core Identity - User management
- JWT (JSON Web Tokens) - Stateless authentication
- BCrypt - Password hashing
- MediatR - CQRS implementation
- AutoMapper - Object-to-object mapping
- FluentValidation - Request validation
- Serilog - Structured logging
- Hangfire - Background job processing
- Swashbuckle (Swagger) - API documentation
- Clean Architecture - Maintainable code structure
- CQRS Pattern - Scalable operations
- Repository Pattern - Data access abstraction
- Unit of Work - Transaction management
- Id (PK) - string
- UserName - string (unique, required)
- Email - string (unique, required)
- PasswordHash - string
- EmailConfirmed - bool
- PhoneNumber - string (optional)
- TwoFactorEnabled - bool
- LockoutEnabled - bool
- AccessFailedCount - int
- RefreshTokens - Collection<RefreshToken> (1:Many)
- Doctor - Doctor (1:1, optional)
- Patient - Patient (1:1, optional)
- Id (PK) - int (Auto-increment)
- ApplicationUserId (FK) - string (Unique)
- FullName - string (100 chars, required, indexed)
- Gender - enum (Male/Female)
- DateOfBirth - DateTime
- Phone - string (20 chars, required, unique)
- Address - string (250 chars)
- Specialization - string (100 chars, required, indexed)
- CreatedAt - DateTime (Auto-generated)
- IsDeleted - bool (Soft delete)
- Appointments - Collection<Appointment> (1:Many)
- Id (PK) - int (Auto-increment)
- ApplicationUserId (FK) - string (Unique)
- FullName - string (100 chars, required, indexed)
- Gender - enum (Male/Female)
- DateOfBirth - DateTime
- Phone - string (20 chars, required, unique)
- Address - string (250 chars)
- CreatedAt - DateTime (Auto-generated)
- IsDeleted - bool (Soft delete)
- Appointments - Collection<Appointment> (1:Many)
- Id (PK) - int (Auto-increment)
- PatientId (FK) - int (Required, Indexed)
- DoctorId (FK) - int (Required, Indexed)
- AppointmentDate - DateTime (Required, Indexed)
- Status - enum (Pending/Confirmed/Completed/Cancelled/Rescheduled/NoShow)
- CreatedAt - DateTime (Auto-generated)
- UpdatedAt - DateTime (Auto-updated)
- IsDeleted - bool (Soft delete)
- Patient - Patient (Many:1)
- Doctor - Doctor (Many:1)
- MedicalRecord - MedicalRecord (1:1, optional)
- Payment - Payment (1:1, optional)
- Id (PK) - int (Auto-increment)
- AppointmentId (FK) - int (Unique, Required)
- Diagnosis - string (500 chars, required)
- DescriptionOfTheVisit - string (1000 chars)
- AdditionalNotes - string (500 chars)
- CreatedAt - DateTime (Auto-generated)
- IsDeleted - bool (Soft delete)
- Appointment - Appointment (1:1)
- Prescriptions - Collection<Prescription> (1:Many)
- Id (PK) - int (Auto-increment)
- MedicalRecordId (FK) - int (Required, Indexed)
- MedicationName - string (100 chars, required)
- Dosage - string (50 chars, required)
- Frequency - string (100 chars, required)
- SpecialInstructions - string (300 chars)
- StartDate - DateTime (Required)
- EndDate - DateTime (Required)
- CreatedAt - DateTime (Auto-generated)
- IsDeleted - bool (Soft delete)
- MedicalRecord - MedicalRecord (Many:1)
- Id (PK) - int (Auto-increment)
- AppointmentId (FK) - int (Unique, Required)
- AmountPaid - decimal(18,2) (Required)
- PaymentMethod - enum (Cash/CreditCard/Insurance)
- PaymentStatus - enum (Pending/Completed/Failed/Refunded)
- PaymentDate - DateTime (Auto-generated)
- IsDeleted - bool (Soft delete)
- Appointment - Appointment (1:1)
- Id (PK) - int (Auto-increment)
- Token - string (500 chars, unique, indexed)
- ExpiresOn - DateTime (Required)
- CreatedOn - DateTime (Auto-generated)
- RevokedOn - DateTime (Nullable)
- IsActive - bool (Computed: !RevokedOn && ExpiresOn > Now)
- ApplicationUserId (FK) - string (Indexed)
- ApplicationUser - ApplicationUser (Many:1)
ApplicationUser 1:1 Doctor
ApplicationUser 1:1 Patient
ApplicationUser 1:N RefreshToken
Doctor 1:N Appointment
Patient 1:N Appointment
Appointment 1:1 MedicalRecord
Appointment 1:1 Payment
MedicalRecord 1:N Prescription
- ✅ Soft Delete Pattern: All entities support soft delete (IsDeleted flag)
- 📊 Indexes: Strategic indexes on frequently queried columns
- 🔒 Foreign Keys: Referential integrity with appropriate cascade rules
- 📅 Timestamps: Automatic CreatedAt/UpdatedAt tracking
- 🔍 Global Query Filters: Automatic filtering of soft-deleted records
- 💾 Lazy Loading: Virtual navigation properties with proxies
- 🗂️ Fluent Configuration: Separate entity configurations for clean code
Step-by-Step Process:
- 👤 User sends credentials (email/username + password) to
/api/authentication/login - 🔍 System validates credentials against database using ASP.NET Identity
- ✅ If valid and email confirmed, generates JWT Access Token + Refresh Token
- 💾 Refresh Token saved to database with expiration date
- 📤 Returns tokens, user info, and roles in response
- 🔐 Client stores tokens (localStorage/sessionStorage)
- 🎫 Client includes Access Token in Authorization header for subsequent API requests
Example Login Request:
POST /api/authentication/login
Content-Type: application/json
{
"emailOrUserName": "patient1@gmail.com",
"password": "Patient@123"
}Example Success Response:
{
"statusCode": 200,
"succeeded": true,
"message": "Login Successful",
"data": {
"id": 1,
"userName": "patient1",
"email": "patient1@gmail.com",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLXBhdDEiLCJ1bmlxdWVfbmFtZSI6InBhdGllbnQxIiwiZW1haWwiOiJwYXRpZW50MUBnbWFpbC5jb20iLCJqdGkiOiI4YzRhM2YxZS02ZjdhLTRkOGItYjJlYy03ZjVhOWIyYzRkMWEiLCJyb2xlIjoiUGF0aWVudCIsImV4cCI6MTczODQ0MDA3MH0.R3v9x1qQ9kXN7sT8yZ2wL4pF5mN6hJ1bG8tD3yC4xK0",
"refreshToken": "hG8Lj2RpQm3Tk9Wn6Yz4Cv1Xf7Sb5Da0Ke8Jm4Pq2Vr6",
"expiresAt": "2026-02-01 22:32:54",
"roles": ["Patient"]
}
}When Access Token expires:
- 🔄 Client sends expired Access Token + Refresh Token to
/api/authentication/refresh-token - 🔍 System validates Refresh Token from database
- ✅ If valid and not revoked, generates new Access Token + new Refresh Token
- 🗑️ Old Refresh Token is revoked in database
- 💾 New Refresh Token saved to database
- 📤 Returns new tokens to client
Token Security Features:
- ⏰ Short-lived Access Tokens (60 minutes)
- 🔁 Automatic token refresh before expiration
- 🔒 Refresh Token rotation (single-use tokens)
- 💾 Database storage for Refresh Tokens with revocation support
- 🚫 Immediate revocation on logout
- 🕐 Configurable expiration times
The system uses Role-Based Access Control (RBAC) with three distinct roles:
| Role | Permissions | Access Level |
|---|---|---|
| Admin | • Full system access • Manage all doctors and patients • View all appointments and payments • Access system statistics • Promote doctors to admin • Delete records (soft/hard) |
🔴 Highest |
| Doctor | • Manage own appointments • Create medical records and prescriptions • View patient information • Access past appointments • Track revenue • Update own profile |
🟡 Medium |
| Patient | • Book and manage own appointments • View own medical records • Access prescription history • Make payments • Update own profile • Cancel appointments |
🟢 Limited |
Example Protected Endpoints:
// Admin Only
[Authorize(Roles = "Admin")]
[HttpGet("stats")]
public async Task<IActionResult> GetAppointmentsStats()
// Admin and Doctor
[Authorize(Roles = "Admin,Doctor")]
[HttpGet("pastfordoctor")]
public async Task<IActionResult> GetPastAppointmentsForDoctor()
// Admin and Patient
[Authorize(Roles = "Admin,Patient")]
[HttpPost("book")]
public async Task<IActionResult> BookAppointment()
// All Authenticated Users
[Authorize]
[HttpGet("{id:int}")]
public async Task<IActionResult> GetPatientById(int id)Authorization Features:
- 🎯 Fine-grained role-based access control
- 🔒 Attribute-based authorization on controllers and actions
- 👤 Current user context injection in handlers
- 🚫 Automatic 401/403 responses for unauthorized access
- 📊 Role claims embedded in JWT tokens
POST /api/authentication/login
Content-Type: application/json
{
"emailOrUserName": "patient1@gmail.com",
"password": "Patient@123"
}POST /api/authentication/refresh-token
Content-Type: application/json
{
"accessToken": "expired_token_here",
"refreshToken": "refresh_token_here"
}GET /api/authentication/confirm-email?userId={userId}&code={encodedCode}POST /api/authentication/resend-confirmation-email
Content-Type: application/json
{
"email": "user@example.com",
"baseUrl": "https://yourdomain.com"
}POST /api/authentication/send-reset-password
Content-Type: application/json
{
"email": "user@example.com",
"baseUrl": "https://yourdomain.com"
}POST /api/authentication/reset-password
Content-Type: application/json
{
"email": "user@example.com",
"code": "encoded_reset_token",
"newPassword": "NewPassword@123"
}POST /api/patients
Authorization: Bearer {token}
Content-Type: application/json
{
"fullName": "Ahmed Hassan",
"userName": "ahmed123",
"email": "ahmed@example.com",
"password": "Ahmed@123",
"phone": "01234567890",
"address": "Cairo, Egypt",
"gender": "Male",
"dateOfBirth": "1990-05-15",
"baseUrl": "https://yourdomain.com"
}GET /api/patients
Authorization: Bearer {admin_token}GET /api/patients/paging?pageNumber=1&pageSize=10
Authorization: Bearer {admin_token}GET /api/patients/{id}
Authorization: Bearer {token}GET /api/patients/phone/{phone}
Authorization: Bearer {admin_or_doctor_token}GET /api/patients/name/{name}
Authorization: Bearer {admin_token}PUT /api/patients/{id}
Authorization: Bearer {admin_or_patient_token}
Content-Type: application/json
{
"fullName": "Ahmed Hassan Updated",
"phone": "01234567890",
"address": "Giza, Egypt",
"dateOfBirth": "1990-05-15"
}DELETE /api/patients/{id}
Authorization: Bearer {admin_token}DELETE /api/patients/{id}/hard
Authorization: Bearer {admin_token}POST /api/doctors
Authorization: Bearer {admin_token}
Content-Type: application/json
{
"fullName": "Dr. Mohamed Ali",
"userName": "dr_mohamed",
"email": "dr.mohamed@clinic.com",
"password": "Doctor@123",
"phone": "01098765432",
"address": "Alexandria, Egypt",
"gender": "Male",
"dateOfBirth": "1980-03-20",
"specialization": "Cardiology",
"baseUrl": "https://yourdomain.com"
}GET /api/doctors
Authorization: Bearer {admin_token}GET /api/doctors/paging?pageNumber=1&pageSize=10
Authorization: Bearer {admin_token}GET /api/doctors/{id}
Authorization: Bearer {token}GET /api/doctors/{id}/appointments
Authorization: Bearer {admin_or_doctor_token}GET /api/doctors/specializations/{specialization}
Authorization: Bearer {token}GET /api/doctors/name/{name}
Authorization: Bearer {token}PUT /api/doctors/{id}
Authorization: Bearer {admin_or_doctor_token}
Content-Type: application/json
{
"fullName": "Dr. Mohamed Ali Updated",
"phone": "01098765432",
"address": "Cairo, Egypt",
"specialization": "Cardiology",
"dateOfBirth": "1980-03-20"
}DELETE /api/doctors/{id}
Authorization: Bearer {admin_token}DELETE /api/doctors/{id}/hard
Authorization: Bearer {admin_token}GET /api/appointments/AvailableSlots?DoctorId=1&Date=2026-02-05
Authorization: Bearer {token}POST /api/appointments/book
Authorization: Bearer {patient_token}
Content-Type: application/json
{
"doctorId": 1,
"patientId": 1,
"appointmentDate": "2026-02-05T14:30:00"
}GET /api/appointments/doctor?pageNumber=1&pageSize=10
Authorization: Bearer {doctor_token}GET /api/appointments/patient?pageNumber=1&pageSize=10
Authorization: Bearer {patient_token}GET /api/appointments/pastfordoctor?pageNumber=1&pageSize=10
Authorization: Bearer {doctor_token}GET /api/appointments/pastforpatient?pageNumber=1&pageSize=10
Authorization: Bearer {patient_token}GET /api/appointments/statusforadmin?status=Pending&pageNumber=1&pageSize=10
Authorization: Bearer {admin_token}GET /api/appointments/statusfordoctor?status=Confirmed&pageNumber=1&pageSize=10
Authorization: Bearer {doctor_token}GET /api/appointments/stats?StartDate=2026-02-01&EndDate=2026-02-28
Authorization: Bearer {admin_token}PUT /api/appointments/confirm
Authorization: Bearer {admin_or_doctor_token}
Content-Type: application/json
{
"appointmentId": 5
}PUT /api/appointments/reschedule
Authorization: Bearer {admin_or_patient_token}
Content-Type: application/json
{
"appointmentId": 5,
"newAppointmentDate": "2026-02-06T15:00:00"
}PUT /api/appointments/complete
Authorization: Bearer {doctor_token}
Content-Type: application/json
{
"appointmentId": 5
}PUT /api/appointments/noshow
Authorization: Bearer {admin_or_doctor_token}
Content-Type: application/json
{
"appointmentId": 5
}PUT /api/appointments/cancel
Authorization: Bearer {admin_or_patient_token}
Content-Type: application/json
{
"appointmentId": 5,
"cancellationReason": "Patient unavailable"
}POST /api/medicalrecords
Authorization: Bearer {doctor_token}
Content-Type: application/json
{
"appointmentId": 5,
"diagnosis": "Hypertension",
"descriptionOfTheVisit": "Patient complained of high blood pressure...",
"additionalNotes": "Follow up in 2 weeks"
}GET /api/medicalrecords/{id}
Authorization: Bearer {token}GET /api/medicalrecords/appointment/{appointmentId}
Authorization: Bearer {token}POST /api/prescriptions
Authorization: Bearer {doctor_token}
Content-Type: application/json
{
"medicalRecordId": 3,
"medicationName": "Lisinopril",
"dosage": "10mg",
"frequency": "Once daily",
"specialInstructions": "Take in the morning with food",
"startDate": "2026-02-05",
"endDate": "2026-03-05"
}GET /api/payment/list?pageNumber=1&pageSize=20
Authorization: Bearer {admin_token}GET /api/payment/{id}
Authorization: Bearer {token}GET /api/payment/daily-revenue?Date=2026-02-01
Authorization: Bearer {admin_token}GET /api/payment/doctor-revenue?DoctorId=1&StartDate=2026-02-01&EndDate=2026-02-28
Authorization: Bearer {admin_or_doctor_token}POST /api/payment
Authorization: Bearer {patient_token}
Content-Type: application/json
{
"appointmentId": 5,
"amountPaid": 500.00,
"paymentMethod": "CreditCard"
}POST /api/role/promote-doctor
Authorization: Bearer {admin_token}
Content-Type: application/json
{
"doctorId": 2
}- .NET SDK 10.0 or higher (Download)
- SQL Server 2019 or higher (Download)
- Visual Studio 2022 or VS Code (Download)
- SQL Server Management Studio (SSMS) (optional, for database management)
git clone https://github.com/adhamdr1/Clinic-System.git
cd Clinic-Systemdotnet restoreOpen appsettings.json in the Clinic System.API project and update the connection string:
{
"constr": "Server=YOUR_SERVER_NAME;Database=ClinicSystem;Integrated Security=SSPI;TrustServerCertificate=True;MultipleActiveResultSets=True"
}Replace YOUR_SERVER_NAME with your SQL Server instance name (e.g., localhost or DESKTOP-XYZ123).
Update email settings in appsettings.json:
{
"EmailSettings": {
"Host": "smtp.gmail.com",
"Port": 587,
"FromEmail": "your-email@gmail.com",
"Password": "your-app-password",
"SenderName": "Elite Clinic"
}
}Note: For Gmail, you need to use an App Password instead of your regular password. See Google's guide.
cd "Clinic System.API"
dotnet ef database updateThis will create the database and seed initial data (admin, doctors, patients).
dotnet runThe API will start at:
- HTTPS:
https://localhost:7179 - HTTP:
http://localhost:5129
Open your browser and navigate to:
https://localhost:7179/swagger
Configure JWT authentication in appsettings.json:
{
"JWT": {
"SecritKey": "your-super-secret-key-minimum-32-characters-long",
"AudienceIP": "https://localhost:4200",
"IssuerIP": "https://localhost:7179",
"TokenExpirationInMinutes": 60,
"RefreshTokenExpirationInDays": 30
}
}Important Security Notes:
- 🔑 SecretKey: Must be at least 32 characters long. Use a random, strong key in production.
- 🌐 AudienceIP: Your frontend application URL
- 🏢 IssuerIP: Your backend API URL
- ⏰ TokenExpiration: Adjust based on your security requirements
{
"EmailSettings": {
"Host": "smtp.gmail.com",
"Port": 587,
"FromEmail": "your-email@gmail.com",
"Password": "your-app-password",
"SenderName": "Elite Clinic"
}
}Supported Email Providers:
- Gmail (smtp.gmail.com:587)
- Outlook (smtp-mail.outlook.com:587)
- Office365 (smtp.office365.com:587)
- Custom SMTP servers
Configure clinic working hours and appointment slots:
{
"ClinicSettings": {
"DayStartTime": "09:00:00",
"DayEndTime": "21:00:00",
"SlotDurationInMinutes": 15
}
}Serilog logging settings:
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.EntityFrameworkCore.Database.Command": "Information",
"System": "Warning"
}
},
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": "Logs/log-.txt",
"rollingInterval": "Day",
"retainedFileCountLimit": 7
}
}
]
}
}The following features are planned for future releases:
- Unit Tests - Comprehensive unit test coverage for business logic
- Integration Tests - API endpoint testing with test database
- Test Coverage Reports - Automated coverage analysis
- SMS Notifications - Appointment reminders via SMS (Twilio integration)
- WhatsApp Integration - Automated messages via WhatsApp Business API
- ✅ Docker Support - Containerization with Docker Compose
- SQL Server container
- Redis container
- ✅ CI/CD Pipeline - Automated builds and deployments (GitHub Actions)
- Admin Dashboard - React/Angular admin panel
- Patient Portal - Self-service patient website
- ✅ Caching - Redis integration for performance
- ✅ Rate Limiting - API throttling and abuse prevention
- ✅ SignalR - Real-time updates for appointments
- ✅ Google OAuth 2.0 - register for google-email
Contributions are welcome! Here's how you can help:
- Fork the Repository
- Create a Feature Branch
git checkout -b feature/AmazingFeature
- Commit Your Changes
git commit -m 'Add some AmazingFeature' - Push to the Branch
git push origin feature/AmazingFeature
- Open a Pull Request
Adham Mohamed
- 💼 Backend Developer specializing in ASP.NET Core
- 🎓 Computer Science Student
- 📧 Email: adhamdr32@gmail.com
- 🌐 GitHub: @adhamdr1
- 💼 LinkedIn: Adham Mohamed
Special thanks to:
- Microsoft - For the excellent ASP.NET Core framework
- MediatR - For simplifying CQRS implementation
- Hangfire - For robust background job processing
- The Clean Architecture Community - For architectural guidance
- Open Source Contributors - For the amazing libraries used in this project










