Hospital Information System with Meteor


#1

Hey, it’s the first time I post to meteor forum. Despite I’ve been using it for about 2 years already :smiley:
I’ve done some projects with Meteor starts from hello world to the most complex one our team are building now. I’m Indonesian and so glad to join on this forum, and I’m sorry for my poor english. But let’s just get to the point of this post here …

I’ve been building a Hospital Information System (a rather small one) entirely on Meteor, with the help of coffeescript, jade, stylus, and iron router. I succeed to make them in about 1800 lines of codes in several .coffee and .jade files. And the client can’t be happier to see how much the codes are simplified, readable, and extensible as much as they want it to be, compared to previous one they’ve built on top of Laravel. Also the DB itself reduced from about hundreds of MySQL tables to only about 5 collection in MongoDB. And just to say, It’s quite hard for us at the first time to convice the client to replace their established (yet buggy) Laravel app to Meteor, but at last we did moved them to production in about 7 months.

Without furtherado, let me show you what our source codes contains of. You can go to this link to see the repo itself http://github.com/rikyperdana/rspb. You may as well give some comments on it, fork it, modify it to your need, or something else. But I’m sorry in advance that some of var and function names are in Indonesian, but I’m sure you can gTranslate it :smiley:

  • both.coffee
    This file contains iron router configuration, routing, schemas, and collections (patients, goods, doctors, fees and so on)

  • server.coffee
    this file contains publications and methods

  • client.coffee
    this file contains all template.helpers and template.events, as well as the globalHelpers and body.events

  • view.jade
    this file contains entire blaze templates from login page, to administration page. And relies it’s data context provided by template.helpers, and their behaviors determined by template.events as I mentioned above

  • style.styl
    just some lines of codes that alter the padding size of container class

  • folder
    hooks.coffee (this file contains AutoForm.hooks that alter the doc that being modified by user)
    selects.coffee (contains arrays of strings that maped to objects that contains values and labels for AutoForm options)
    pdf.coffee (pdfMake methods that generate pdf based on values passed to their respective params)
    rights.coffee (an array that will be used to test current user access rights with the help of allaning:roles)
    modules.coffee (an array that contains route names, as well as their respective title page names)

  • public (only contains 1 .jpeg file for login page)

Yep, that’s all our source codes contains of. And the next thing, let me explain how the app works as how the hospital wanted it to be.

  1. Scenario if the patient coming are unregistered
    Patient comes in -> Reg Staff ask his name -> Search the name on system -> If not exist, create a new one, else open outpatient menu
  2. Scenario if the patient are paying the med by themselves
    Reg staff entry the appointment to the desired medication facility/specialits -> Pay the reg fee -> Patient wait in line -> Nurse call the name and the doctor check the patient
  3. Scenario if the patient are paid by insurance company
    Reg staff entry the appointment just as like above -> Patient wait in line -> Nurse call, doctor check -> Finance guy claim the fees to insurance company

Menus included in this app are :
Registration, Outpatient, Cashier, Laboratory, Radiology, Pharmacy, Logistic Warehouse, and Management
Registration is where the staffs register new patients and read existing datas
Outpatient is where the patient handled by the nurses and get checked by doctors
Cashier is where the patient pay for reg, medication, and pharmacy fees
Laboratory is where the patient take laboratory tests which the doctor has prescribed for him
Radiology is where the patient take radiology tests which the doctor has prescribed for him
Pharmacy is where the patient receive drugs which the doctor has prescribed for him
Logistic Warehouse is where the staffs input their goods stocks which later can be accessed by Pharmacy
Management is where the admin manages user accounts, update fees list, on export some datas to csv

There are 2 level of user rights on this app which is staffs and admins. For each staffs can only input data and read it. While the admin level can do everything staffs can and also remove data related to menu they have access to. So it means, Registration Admin can only have right to CRUD datas related to registration things, and so does admin for other menus.

Further Dev ::
We’re going to extend this app to include features like inpatient, rooms, etc. And I’m sure will update this post as I have more valuable information to share

Known Issues ::
Each methods that exists on server.coffee are exposed on client’s side, thus anyone who knows our method names are able to hack them (like removing patient, make the hacker bill’s free)

I guess that’s all I can share for now, so it’d be nice if anyone are willing to help me with it by giving comments, suggestion, or something. And if my explanation is poor please don’t judge me like people did on SO. I’m just glad that I can share with people who use Meteor like me.

Working demos are available from this link http://128.199.232.220:4300
You can use my account here for testing purpose username: riky password: asdfkj

Peace from Indonesia


#2

You need to protect your methods by checking the userId and if that user is authorized to call that method.


#3

Thanks, I’ll give it a try. But can you give me an example of how to do it?


#4

Can I ask you why ? Is this done on purpose ?


#5

I have resolved it by moving it to server folder as suggested by meteor guide


#6

Use the alanning:roles package and then check in your method if the current user has the proper authorization, for example

Meteor.methods({
 updateRecord(data){
   if(Roles.userIsInRole(this.userId, ['admin','adminPatient']) ) {
     ....
   } else {
      throw new Meteor.Error(403, 'Permission denied', 'you have to have the proper role');
   }
 }
})

#7

You meant alanning:roles :wink:


#8

Of course you are right, damn autocorrect :wink: