All Projects

Hospital Management System

Yibera

Yibera is a web-based hospital management system — a public marketing site plus three role-based portals (patients, staff, admins) behind a security-first authentication layer. It unifies patient intake, appointments, prescriptions, lab results, pharmacy inventory, and billing into one operational system.

Yibera — Hospital Management System
Problem

Hospitals juggle disconnected workflows — patient intake, appointment requests, staff records, pharmacy stock, lab results, and billing — often spread across paper, spreadsheets, and siloed tools. Patients have no single place to register, book, and follow their care, and staff and admins have no unified operational view.

Solution

A full HMS with three role-based portals behind a security-first auth layer. Patients self-register, book and manage appointments, and view prescriptions, lab results, and invoices. Staff (created by admins) sign in to a clinical/operational view, while admins manage patients, staff, and pharmacy inventory and see analytics. Booking is currently request-and-confirm — an admin confirms each appointment — not real-time slot selection.

System Design

Frontend

Server-rendered PHP views + Tailwind (compiled, purged, minified); progressive enhancement with vanilla JS, Chart.js, AOS, Swiper. No SPA.

Backend

PHP 8 custom MVC — no framework or Composer. Front-controller + router with thin models over mysqli using prepared statements.

Database

MySQL / MariaDB. Schema self-provisions on first request — idempotent CREATE TABLE IF NOT EXISTS plus additive column migrations.

Notifications

Dependency-free SMTP client (raw sockets, SSL/STARTTLS, AUTH LOGIN) for OTP/verification, with mail() + file-log fallback.

Infra

Apache on shared hosting; .htaccess for forced HTTPS, asset caching, gzip, and security headers; gitignored env-style config for secrets.

User Journey
  1. 01

    Register / Activate

    Self-signup, or email-OTP activate/reset for patients booked by an admin.

  2. 02

    Onboarding

    Optional, skippable profile completion.

  3. 03

    Sign In

    Password (bcrypt cost 12) + optional email-OTP 2FA, protected by brute-force lockout.

  4. 04

    Book

    Choose department + preferred date/time — appointment is created as pending.

  5. 05

    Confirm

    Admin/staff move it to confirmed or completed; the patient sees the status.

  6. 06

    Follow Care

    View prescriptions, lab results, and invoices; pay invoices (simulated).

Database Structure
  • patient — demographics, insurance, portal auth
  • staff — provider profile, department, portal auth
  • admin_users — admin / super-admin accounts
  • appointment — patient, department, date/time, status
  • prescription — EMR records per patient
  • lab_report — EMR lab results per patient
  • invoice — billing: amount, status, due/paid
  • medication — pharmacy inventory
  • login_attempts — brute-force throttle ledger
Screenshot Gallery

Tap any frame to open the lightbox — use arrow keys or swipe to navigate.

Technical Challenges

Multi-actor auth with isolated guards

Three identity types (admin / patient / staff) live in separate tables and session namespaces via three guard classes, so a valid patient session can't traverse into staff or admin areas. More code than one users table with RBAC — but strong blast-radius isolation.

Security as defense-in-depth

CSRF tokens on every state-changing form, brute-force lockout (5 tries → 15 min, scoped per identifier + IP), password policy with rehash-on-login, opt-in email-OTP 2FA, session-ID regeneration, idle/absolute timeouts, and HTTPS/HSTS edge hardening.

Schema migrate-on-boot

No shell/CLI on shared hosting, so Database::migrate() runs idempotently on the first request of a session to self-heal the schema on deploy. It isn't versioned — at scale I'd move to a real migration runner in CI/CD.

Dependency-free transactional email

A from-scratch SMTP client (raw sockets, SSL/STARTTLS, AUTH LOGIN) sends OTP/verification anywhere, falling back to mail() then a file log. Gaps: no retries/queue, no bounce handling, and OTP send is synchronous on the request path.

Honest data-model tension

Public booking still writes to patient.Status while the portal added an appointment table for multiple bookings — a real dual-source-of-truth smell (admin stats still read patient.Status). The fix is to move all scheduling onto appointment and keep patient as pure identity.

Where it breaks at scale

Single Apache box, file-based sessions, same-host MySQL, synchronous email. Scaling out means Redis/DB sessions, managed MySQL with read replicas for reporting, a queue for email, a CDN/object store for images, and versioned CI/CD migrations.

Impact

Yibera is a working full hospital management system — a public site plus patient, staff, and admin portals over a 9-table MySQL schema, with multi-actor authentication, defense-in-depth security, and self-provisioning migrations — built on zero-dependency PHP 8 so it deploys on plain shared hosting.

3
Role-Based Portals
9
Database Tables
12
bcrypt Cost Factor
OTP
Email 2FA + Lockout
Roadmap
  1. 01

    Real availability & slot engine

  2. 02

    Provider discovery & search

  3. 03

    Payment gateway (real billing)

  4. 04

    Unified identity service with RBAC

  5. 05

    Versioned CI/CD migrations

  6. 06

    Email job queue + provider

  7. 07

    Redis sessions & caching

  8. 08

    Managed MySQL read replicas

  9. 09

    CDN / object store + WebP images

  10. 10

    Structured logging, metrics & alerts

Want to see more?