Author: Oh Hyun Wo (ohyunwoods663@gmail.com) | https://github.
com/punixcorn
Hospital Backend System Documentation
This document outlines the complete backend architecture of our hospital system, covering the
data models, API endpoints, dynamic scheduling logic, and deployment considerations.
Note:
· Our backend is built with Node.js and Express, written in TypeScript, and uses
MongoDB (via Mongoose) for data storage.
· Authentication is handled via JWT tokens (often stored as HTTP-only cookies) with role-
based access controls.
· The system is modularized into separate domains for Auth, Doctor, Patient, and Notes
functionality.
· This website is not production ready.
· Most of the Api’s listed here may or may not be present or and functionality may have
not been fully confirmed, due to lack of time this was rushed.
Author: Oh Hyun Wo (ohyunwoods663@gmail.com) | https://github.com/punixcorn
Hospital Backend System Documentation
The Expose endpoints:
Patient doctor selection.
Doctor retrieval of their patient list.
Submitting doctor notes and processing actionable steps.
Retrieving actionable steps and reminders.
1. Models
User Model
Assignment Model
Note Model
Session Model
Verification Model
2. API Endpoints
Authentication Endpoints
POST /api/auth/signup
POST /api/auth/login
Doctor Endpoints
GET /api/doctor/get-patients
POST /api/doctor/select-patient
Patient Endpoints
GET /api/patient/available-doctors
POST /api/patient/select-doctor
Notes Endpoints
POST /api/notes/add_note_task
GET /api/notes/get_my_tasks
3. Dynamic Scheduling & Task Lifecycle
Dynamic Scheduling
4. Documentation & Justification
Authentication
Encryption
Scheduling
Data Storage
Containerization
REQUIREMENTS :
As per requirements the following endpoints
The Expose endpoints:
User signup and authentication.
· /api/auth/signup
· /api/auth/login
· /api/auth/logout (out of scope)
Patient doctor selection.
· /api/patient/available-doctors
· /api/patient/select-doctor
Doctor retrieval of their patient list.
· /api/doctor/get_patients
Submitting doctor notes and processing actionable steps.
· /api/notes/add_note_task
Retrieving actionable steps and reminders.
· /api/notes/get_my_tasks
1. Models
User Model
File: src/models/user.model.ts
Purpose:
Stores all user data, including both patients and doctors. The boolean field role distinguishes
between them:
· role: true → Doctor
· role: false → Patient
Schema Fields:
· email: String (unique, required) – User’s email address.
· password: String (required) – Password (hashed via a pre-save bcrypt hook).
· verified: Boolean (default: false) – Indicates if the email is verified.
· role: Boolean (required) – Indicates user type.
· Timestamps: Automatically maintained createdAt and updatedAt.
Instance Methods:
· comparePassword(password: string): Promise<boolean> – Compares a candidate
password with the stored hash.
· omitPassword(): object – Returns a user object with sensitive data (password) omitted.
Assignment Model
File: src/models/assignment.model.ts
Purpose:
Maps doctors to their patients. When a patient selects a doctor, their ID is added to the doctor’s
Assignment document.
Schema Fields:
· doctor: ObjectId (ref: "User", required) – ID of the doctor.
· patients: Array of ObjectId (ref: "User", required) – IDs of patients who selected this
doctor.
· Timestamps: createdAt and updatedAt are maintained automatically.
Note Model
File: src/models/notes.model.ts
Purpose:
Holds a doctor’s note for a patient along with the LLM-processed actionable steps.
Schema Fields:
· doctor_id: ObjectId (ref: "User", required) – Doctor who created the note.
· patient_id: ObjectId (ref: "User", required) – Patient who will see the note.
· original_note: String (required) – The original note text.
· extracted_actions: Object – Contains LLM-processed data following the interface:
· typescript
· CopyEdit
· export interface LLMdata { actionable_steps: { checklist: string; plan: string;
number_of_days: number; interval_between_days: number; }; }
· number_of_days_left: Number (required) – Initialized to number_of_days from
LLMdata; decrements daily.
· date_of_creation: Date (default: Date.now) – The creation date.
· is_done: Boolean (default: false) – Set to true when number_of_days_left reaches 0.
· remind_patient_today: Boolean (default: false) – Flag indicating if the patient has been
reminded on the current day.
· Timestamps: createdAt and updatedAt are automatically maintained.
Session Model
File: src/models/session.models.ts
Purpose:
Tracks active user sessions. Even if JWTs are used for stateless authentication, session data may
be stored server-side to allow for immediate revocation or additional security checks.
Typical Schema Fields:
· user: ObjectId (ref: "User", required) – The authenticated user’s ID.
· token: String (required) – The session token.
· createdAt: Date (default: Date.now) – Session creation timestamp.
· (Optional: Set an expiry on sessions via Mongoose’s expires option.)
Verification Model
File: src/models/verification.model.ts
Purpose:
Manages user verification (e.g., email confirmation). When a user registers, a verification record
is created, which is later marked as verified upon successful confirmation.
Schema Fields:
· user: ObjectId (ref: "User", required) – Associated user.
· code: String (required) – Verification code.
· expiresAt: Date (required) – When the code expires.
· verified: Boolean (default: false) – Whether verification has completed.
· Timestamps: Automatically includes createdAt and updatedAt.
2. API Endpoints
The API is organized by module. All endpoints assume the presence of authentication
middleware that validates a JWT (and populates req.user).
Authentication Endpoints
(Located in src/api/auth)
POST /api/auth/signup
· Purpose: Registers a new user.
· Request Body Example:
· json
· CopyEdit
· { "email": "user@example.com", "password": "yourPassword", "role": false }
· Response:
· 201 Created: Returns user details (without the password).
· Errors: 400 for missing fields; 500 on error.
POST /api/auth/login
· Purpose: Authenticates a user.
· Request Body Example:
· json
· CopyEdit
· { "email": "user@example.com", "password": "yourPassword" }
· Response:
· 200 OK: JWT is returned and stored as an HTTP-only cookie.
· Errors: 401 for invalid credentials; 500 on error.
Doctor Endpoints
(Located in src/api/doctor)
GET /api/doctor/get-patients
· Purpose: Retrieves a list of patients who have chosen the doctor.
· Authentication: Requires a valid JWT for a doctor (role: true).
· Response Example:
· json
· CopyEdit
· { "patients": [ { "_id": "patientId1", "email": "patient1@example.com", ... },
{ "_id": "patientId2", "email": "patient2@example.com", ... } ] }
POST /api/doctor/select-patient
· Purpose: Allows a doctor to send a note to a specific patient. The note is processed (via
Gemini) to extract actionable steps (checklist & plan).
· Authentication: Requires a valid doctor token.
· Request Body Example:
· json
· CopyEdit
· { "patientId": "60f8a8e2c3a1b34d2c8d9f1a", "note": "Patient needs to buy drug X and
take it daily for 7 days." }
· Response Example:
· json
· CopyEdit
· { "actionableSteps": { "checklist": ["Buy required medication"], "plan": ["Schedule
daily reminder for 7 days"] } }
Patient Endpoints
(Located in src/api/patient)
GET /api/patient/available-doctors
· Purpose: Lists all doctors available for selection.
· Authentication: Requires a valid JWT (applies to all authenticated users).
· Response Example:
· json
· CopyEdit
· { "doctors": [ { "_id": "doctorId1", "name": "Dr. Smith", "email":
"drsmith@example.com" }, { "_id": "doctorId2", "name": "Dr. Jones", "email":
"drjones@example.com" } ] }
POST /api/patient/select-doctor
· Purpose: Lets a patient choose a doctor, updating the Assignment model.
· Authentication: Must be an authenticated patient (role: false).
· Request Body Example:
· json
· CopyEdit
· { "doctorId": "60f8a8e2c3a1b34d2c8d9f1a" }
· Response Example:
· json
· CopyEdit
· { "message": "Doctor selected successfully", "assignment": { "doctor":
"60f8a8e2c3a1b34d2c8d9f1a", "patients": ["patientId"], ... } }
Notes Endpoints
(Located in src/api/notes)
POST /api/notes/add_note_task
· Purpose: Allows a doctor to create a note for a patient. The note is processed via an LLM
to extract actionable steps.
· Fields:
· doctor_id, patient_id, original_note
· extracted_actions (includes checklist, plan, number_of_days, interval_between_days)
· number_of_days_left is initialized from the LLM data.
· is_done is false initially; it becomes true when number_of_days_left reaches 0.
· remind_patient_today tracks if the patient has been reminded for the day.
· Authentication: Accessible only to doctors.
· Request Body Example:
· json
· CopyEdit
· { "patientId": "patientId123", "originalNote": "Patient must take drug X daily for 7
days." }
· Response Example:
· json
· CopyEdit
· { "note": { "_id": "noteId", "doctor_id": "doctorId", "patient_id": "patientId123",
"original_note": "Patient must take drug X daily for 7 days.", "extracted_actions": {
"actionable_steps": { "checklist": "Buy drug X", "plan": "Take drug X daily",
"number_of_days": 7, "interval_between_days": 1 } },
"number_of_days_left": 7, "is_done": false, "remind_patient_today": false,
"date_of_creation": "2025-02-14T05:01:17.000Z", "createdAt": "...", "updatedAt":
"..." } }
GET /api/notes/get_my_tasks
· Purpose: Lets a patient retrieve all active (i.e. is_done: false) note tasks.
· Authentication: Accessible only to patients.
· Response Example:
· json
· CopyEdit
· { "tasks": [ { "_id": "noteId", "doctor_id": "doctorId", "patient_id":
"patientId", "original_note": "Patient must take drug X daily for 7 days.",
"extracted_actions": { ... }, "number_of_days_left": 5, "is_done": false,
"remind_patient_today": false, "createdAt": "...", "updatedAt": "..." } ] }
3. Dynamic Scheduling & Task Lifecycle
Dynamic Scheduling
· Overview:
The system supports dynamic scheduling of patient reminders based on the actionable
plan extracted from a doctor’s note.
· Process:
1. Note Creation:
When a doctor creates a note (via add_note_task), the LLM processing returns a plan
(e.g., “Take medication daily for 7 days”) and a corresponding number of days.
2. Initialization:
The number_of_days_left field is set to the LLM’s number_of_days.
3. Daily Decrement:
A background job (using a scheduler like Bull or node-cron) runs daily, decrementing
number_of_days_left by 1 for each active note.
4. Completion:
Once number_of_days_left reaches 0, the note’s is_done flag is set to true, preventing it
from being retrieved by the patient.
5. Reminder Flag:
The remind_patient_today flag tracks whether the patient has been reminded on a
particular day. It is reset each day by the scheduling system.
· Cancellation:
If a new note is added for the patient, any previously scheduled actionable tasks for that
patient are canceled to ensure that only the most recent note is active.
4. Documentation & Justification
Authentication
· JWT:
· Stateless, fast, and scalable.
· Stored in HTTP-only cookies to mitigate XSS.
· Role-Based Access:
· User model's role field restricts endpoints (doctors vs. patients).
Encryption
· bcrypt:
· Securely hashes passwords.
· HTTPS:
· All data transmitted securely.
Scheduling
· Dynamic Reminders:
· Use background jobs (e.g., Bull/node-cron) to decrement number_of_days_left daily.
· Missed check-ins extend the schedule.
· Task Cancellation:
· New notes cancel old reminders to avoid conflicts.
Data Storage
· MongoDB/Mongoose:
· Flexible, scalable schema design.
· Separate collections for Users, Assignments, Notes, Sessions, and Verifications.
Containerization
· Docker Multi-Stage Build:
· Build with node:22 and run with node:22-alpine for a lightweight, secure production
image.