Hospital Management System
A prescription saved with no allergy check looks completely normal — until it isn't, and nothing about the response tells you that.
- Java
- Spring Boot
- MySQL
About this project
A single hospital's patient, doctor, appointment, and prescription records. Three real staff roles — admin, doctor, receptionist — each genuinely scoped by Spring Security: a receptionist can manage appointments and contact details but is refused clinical data outright, and a doctor can only see the medical history of patients they actually have an appointment with.
The real subject of this project is what happens when a prescription is created with no safety check at all. A naive endpoint inserts the drug, dosage, and patient with no cross-check against that patient's recorded allergies — the record saves cleanly, returns 201, and looks completely normal, which is exactly the danger: nothing about a successful response tells anyone a conflict exists. The fixed endpoint checks the prescribed drug against the patient's allergy list, including a small drug-to-allergen-class mapping (Amoxicillin is a penicillin-class drug even though its name doesn't match "Penicillin" as a string), and refuses with a named conflict — unless the request carries a documented override reason, which is exactly the honest middle ground a hard, unbreakable block would get wrong: sometimes a doctor has a real clinical reason to proceed anyway, and the system's job is to make that decision visible and permanently recorded, not to make it impossible.
What you will learn
- Build a check-then-refuse-with-a-documented-override pattern for a naive action that could silently violate a known safety constraint
- Enforce real, role-based access control with Spring Security — not a hand-rolled if-statement checking a role string
- Scope a doctor's access to their own patients' clinical data, and correctly deny an unrelated doctor the same data
- Recognise that a hard, unbreakable block is sometimes the wrong fix too — and design the honest alternative
- Prove an authorization fix with a forged JWT, not just a normal request, and confirm the signature check actually runs
Before you start
- Java and some Spring Boot — controllers, services, Spring Data JPA basics
- A JDK 21+ — no global Maven install needed, the bundled wrapper downloads its own
- MySQL 8+ reachable somewhere, and some familiarity with Spring Security is useful but not required
New to Java? The free Java course covers everything this project assumes.
Academic integrity notice
These projects are provided for learning, experimentation and reference. Understand the code, modify it for your own requirements, and acknowledge external work according to your institution’s academic policies. Priodemy does not supply work to be submitted as your own.
Features
- A naive prescription endpoint and a fixed one, both real, proving a silent allergy conflict and its correct refusal
- A drug-to-allergen-class mapping — a name match alone would miss Amoxicillin conflicting with a recorded Penicillin allergy
- An override is allowed, but never silent: it requires a real reason, which is permanently stored on the prescription record
- Real Spring Security role enforcement — receptionist correctly refused clinical reads a hand-rolled check would be easy to get wrong
- A doctor's access is scoped to their own patients — a second, unrelated doctor is correctly refused the same data
- JWT signature verification confirmed against a real forged token, not just a normal unauthenticated request
Technology stack
Track: Java · Level: Major project
What is included
- A full Maven project — pom.xml, mvnw/mvnw.cmd, 64 source files across domain/repository/dto/security/service/web
- A README with the real allergy-conflict transcript, the RBAC transcript, and a real bug the project's own testing found and fixed
- A drug-allergen reference table seeded with enough real mappings to demonstrate the pattern
Delivered as a 92 KB ZIP. SHA-256 published under Changelog so you can verify it.
System requirements
- Operating system
- Any
- Runtime
- JDK 21+. MySQL 8+. No global Maven needed — the bundled wrapper downloads its own.
- Database
- MySQL
Licence
Learn from it, change it, and use it in your own coursework and personal projects. Do not resell it or pass it off as your own original work.
- Personal and educational use
- Modifying the code however you like
- Using it as the basis of your own coursework, with honest acknowledgement
- Putting your modified version in a portfolio or on your own GitHub
- Reselling or redistributing the project, modified or not
- Presenting it as your own original work
- Commercial deployment — see the Commercial licence
Support window: 6 months from download.
Frequently asked
Is the allergy conflict actually detected, or just asserted?
Detected for real. A patient is given a recorded Penicillin allergy through the actual API, then a real prescription request for Amoxicillin — a penicillin-class drug, not a literal name match — is sent to both endpoints. The naive one saves it silently; the fixed one refuses by name, and a fresh SELECT straight from MySQL (not the API's own response) confirms exactly what was stored.
Why allow an override at all — why not just block it?
Because a hard block would be wrong too. A doctor sometimes has a genuine clinical reason to prescribe despite a recorded allergy. The fix isn't "never allow it," it's "never allow it silently" — an override requires a real, non-blank reason, and that reason is permanently attached to the prescription record, not merely accepted and discarded.
How rigorously was the role-based access control tested?
Beyond the basic case: a second, unrelated doctor was refused a patient's data the same way a receptionist was; a receptionist was checked against multiple different clinical endpoints, not just one; and a real JWT was decoded, its role claim rewritten to ADMIN, and resubmitted with the now-mismatched signature — correctly rejected, confirming the check is real cryptographic verification, not just reading a claim out of the token.
Changelog
- First release
SHA-2567f8b394277d2d0af0daa81d5618d45220538b22dcad24384b5397360d3e5d090