Git Product home page Git Product logo

bhima's People

Contributors

adamwatts avatar bors[bot] avatar buzunda avatar dedrickenc avatar dependabot-preview[bot] avatar dependabot[bot] avatar ebed-meleck avatar flurmbo avatar gibr avatar greenkeeper[bot] avatar greenkeeperio-bot avatar imawh avatar individual-it avatar jeremielodi avatar jmcameron avatar jniles avatar joshuahedlund avatar lomamech avatar mbayopanda avatar notriddle avatar rileythomp avatar scholldier avatar sfount avatar snyk-bot avatar trilemaestro92 avatar troyev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bhima's Issues

Automatically deploy to VM on successful test builds

Travis allows hooks to automatically deploy the application if the test suite successfully passes. My only experience is with OpenShift, though I would be interested in exploring other options (OpenShift uses out-of-date NodeJS versions).

After both #24 and #25 are satisfied, I propose we make it a project goal to have automatic deployment to a cloud provider. Not only will this require us to have a simplified build, it will force us to begin dealing with bandwidth constraints and allow external parties to review the application without any effort to configure it.

I'd be interested to hear if anyone else thinks this idea is worthwhile.

Use GreenKeeper to keep dependencies up to date

GreenKeeper is a useful tool for keeping dependencies up to date. As soon as #24 and #25 land, we'll be able to catch regressions easily in our code base. In order to keep up to date with security fixes, features, and optimizations in the underlying NPM modules, I propose we use GreenKeeper to test branches with new versions of our dependencies when they are updated. These, of course, would only be merged provided that they pass the tests.

Implement a filter for a telephone number

There are a few places we need to display telephone numbers in the application (receipts, reports, lists of users, etc). A handy component to have would be a telephone filter. Something that could be easily embedded in a view such as this:

<span>{{ patient.telephone | telephone }}</span>

... to yield a nicely formatted telephone number (e.g. +243 821 453 233).

Location API Endpoint

API should provide

  • Very detailed view of a specific village
  • Lists of villages/provinces/countries etc. given their dependencies (provinces in countries, villages in provinces etc.)
  • Well tested endpoint

This API will drive the management pages required for administering locations as well as provide data the for the location select directive and any modules that requires locations.

Replace dotjs with lodash templates

The application's email and report templating has previously been done by doT.js. However, since we are now depending on lodash for our library functions, we might as well use it for templating. As we begin to consider reports, we should seriously consider migrating our doT.js code to lodash.

Break up translation JSONs into multiple files.

Our translations files have become far to big to work with efficiently. This leads to repeating the same keys in different contexts, and collisions in our git repository on almost every commit.

The fundamental question is how to break the translation files up. For a start, we could try splitting on top-level domains, such as hospital.en.json, finance.fr.json, shared.fr.json, etc. What do @IMA-WorldHealth/local-contributors think?

Allow builds to be either HTTP or HTTPS

This proposal concerns the bhima build system.

I propose that we allow optional SSL. In production, you should always use HTTPS to protect your data; however, many virtualization and testing frameworks do not support SSL. It would certainly make our integration and end to end tests more clear.

To accomplish this, we will include the following flag in the .env environmental variables:

  • BHIMA_USE_TLS = { 0 || 1 }

We should also rename the previous TLS_CERT and TLS_KEY flags to use the BHIMA prefix.

An application built with TLS will continue to function as the current build. An app built without TLS enabled will import http instead of https and not require the certificate or keys to be imported.

Finally, if the application is not built with TLS, there should be prominent console warnings on boot up, telling the user that running data over an unencrypted network is dangerous.

Do not enforce daily exchange rates

This proposal concerns conceptually changing the exchange rate. We currently treat exchange rates as only valid the day they are defined. I propose change the exchange rate handling to be valid from the time of definition to the next time of change.

Proposed Database Changes:

  1. Drop the column enterprise_currency_id and replace with enterprise_id.
  2. The date column's data type will be DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP.
  3. Rename foreign_currency_id to simply currency_id.

Proposed API changes:

  1. GET /exchange lists all the exchange rates in the database
  2. POST /exchange will create an exchange rate. If no date is provided, use the current timestamp.
  3. PUT /exchange/:id update an exchange rate in the database.
  4. DELETE /exchange/:id will delete an exchange rate from the database.

Proposed algorithm changes:

  1. The ExchangeService will get exchange rates based on the current time. The exchange rates will be kept in an ordered list. Given a date, the algorithm will walk down the list of exchange rates, setting the most recent rate prior to the given date as a valid rate. If no valid rate exists, the service should throw an error. This part of the proposal has already been implemented in ExchangeRateService.

Additionally, we should support both editing and deleting exchange records. This would allow the enterprise to correct previous records by editing a faulty exchange rate and recalculating the rates for the data in the posting journal.

Propose 2.X standard for catching client side errors

This proposal should be split into two parts:

  • Handling an error in the context of a specific form or form element - this should provide feedback as to why this particular operation failed (I.e cannot submit an integer for a string value)
  • Generic module wide error handling - this should be displayed in the context of the module, every module should handle these errors in a similar way (Server status 500 - contact system administrator etc.)

This proposal can then be implemented across 2.X modules.

Deprecate /lib/guid in favor of node-uuid

Since we are entering a sprint focused on testing, I propose we swap out our dependency on the library guid on the server in favor of a tested UUID library. It doesn't matter too much which one we use, but node-uuid is highly depended upon by other projects. The API is slightly different from our library, but that shouldn't be a big deal.

Separate our Business Logic Layer (BLL) with our Data Access Layer (DAL)

We are writting a new version of BHIMA (V2), some decision must be taken and now is the best moment to take them.
Our system is coupled we have angularjs and nodejs, angular is designed to force programmer using services, controllers and views but it is not the case for nodejs.
We should continue to amend our server side, for now our controllers at the server side contain some data operation which can be isolate to a low level (Data Access Layer).
We should find business rules only in our controller and data access operations in our kind of model or data object.
This proposal, if applied will reduce the number of code line in our route.js file and will make the server side code maintainable.
Exposing the controllers interfaces directly instead of exposing each http method one by one is advantageous.

Proposal: Restructure Posting Journal Schema

This proposal concerns the MySQL tables posting_journal and general_ledger.

Motivation

There is no clear way to reference an invoice in the Posting Journal or General Ledger. There should be an easy way to look up transactions in the database and following links between transactions to relate dependencies. For example, a cash transaction may reference a previous patient invoice, or a stock increase may reference the purchase order's cash transaction.

Column Redefinitions

I propose that we drop the columns doc_num and inv_po_id entirely. These will be replaced with more meaningfully named columns record_uuid and reference_uuid. The record_uuid should be the uuid of the table which posted the record to the posting journal. For example, if it were a cash payment, it would be the cash.uuid. For a patient invoice, the sale.uuid associated with that record. This is a required field, and it will be the same uuid for an entire transaction.

The reference_uuid will reference other record_uuids in the posting journal, forming the link between multiple transactions in a series. One line in a transaction will never have a reference_uuid, but all other lines may have one or none.

#### Why two columns?
You could model the same functionality with a single column. However, two columns also greater flexibility in application logic. Two columns distinguish between the idea of an ID and a reference. We can use this idea to build business logic that warns the user if they are deleting a transaction that is referenced in a subsequent transaction. With a single column, you cannot be sure if you are deleting the ID or the reference. With two columns, all you need to do is check the column name.

Interested in any feedback @IMA-WorldHealth/local-contributors.

Remove duplicate exchange rate services.

There are two exchange rate modules, ExchangeService and ExchangeRateService. ExchangeService continues to require a daily rate and has an impossible API. Earlier last year, it was rewritten as ExchangeRateService. As part of the bhima-2.X milestone, we should establish a goal to completely remove ExchangeService in favor of the ExchangeRateService.

Consider using ui-router for application state

The application has never handled state well. For simple cases (do we have a primary cashbox or not?), the controller has often just used an ng-if directly in the HTML to show/hide components. For more complex cases, the controller uses an ng-switch (create/update/success/failure). Admin modules are good examples of these. In the most complex cases, sometimes an ng-switch is coupled with an ng-include and even a new controller is templated in. Receipts is a good example of this condition.

One solution is to use the router to manage state. Our current router (ngRouter) is limited to only directly mapping URLs to individual templates and controllers, 1-1-1. A different project, ui-router allows you to nest controllers and views, so that child states can inherit properties of the parent states, and you can have multiple views on a single page (we currently only have on ng-view).

Advantages of ui-router:

  1. Can create easily compose separate states for create/update/views for common CRUD modules (e.g. users, projects, enterprises, locations, etc, ...).
  2. Easily nest states (/patients <- /patients/:id <- /patients/:id/groups) to reduce the need for services and extra $http requests.
  3. Multiple views!
  4. No longer have to depend on the URL to change to switch controllers -- allows us to better encapsulate complex pages.

Dis-advantages of ui-router:

  1. No idea how it will compose with Angular 2. They are working on it though.

link.

Currency Input Component

This proposal is for a currency input directive. The cash module currently uses a <input type="number"> that is very simplistic and does not give appropriate user feedback. Here is an image of it:
currencyinputdirective
I imagine the directive's signature to look like this:

  <div class="form-group">
    <label>The Currency Directive</label>
     <bh-currency-directive currency="Ctrl.currencyId" relaxed required></bh-currency-directive>
  </div>

The currency input directive must fit the following criteria:

  1. Support the following attributes:
    a. currency={ currencyId } (one way binding to controller currency id)
    b. required Boolean attribute to apply to the underlying <input> element
    c. relaxed Boolean attribute to determine if rule 3 of this list is followed. If true, do let any positive value be inputed. If false, follow the constraint describe in rule 3.
  2. Display the currency symbol in an input group to the left of the input.
  3. Enforce the min_monentary_unit of the currency as the minimum value acceptable in the currency input.
  4. Show the following validation messages to the user as appropriate:
    a. "The value you entered is smaller than the smallest unit of this currency. The smallest supported value for %s is %s.".format(currencyName, minMonentaryUnit)
    b. "The value must be positive."

A directive such as this would greatly improve the speed we develop the Primary Cash modules.

Upgrade to Angular 1.5

Angular 1.5 was just released. The most significant advantage is first-class support for angular.component() which we should seriously consider implementing anywhere we would use a directive (and potentially re-writing some of our old directives as components).

Both the changelog and migration guide seem to suggest that we will not have any breaking changes - only security and potentially performance improvements.

Convention Module need a loading indicator

The convention module need a loading indicator for notify the user about the debitor receipts are being loaded when we select a debitor.

The process take too long time for loading debitor receipts and also when we click on "submit" for a payment.

Recommendation: use bluebird instead of q for promises.

So far, we've been using q as our Promise implementation on the server. An alternative is to use bluebird, a fast promise implementation that is built with NodeJS specifically in mind. I'd like to change library for three reasons:

  1. A better API - we no longer need to use the ugly .done() syntax, built-in support for .map(), etc.
  2. Faster than both q and native promises.
  3. Potentially to use bluebird.promisify() to replace db.exec().

A third alternative is to simply use NodeJS promises, but it seems that bluebird is faster than Native promises and gives us more flexibility in the API than a strictly A+/Promise implementation.

Since we are currently rewriting APIs, it makes sense for this change to land now. Curious to know what other developers think though.

Use SauceLabs to run end-to-end tests

Once #24 lands, bhima-2.X will have automatic testing of integration tests to prevent regressions. This will greatly speed up PR reviews and ensure that we are always moving forward without breaking things in the past.

The next logical step is to move our e2e tests onto an external service. Travis integrates well with SauceLabs which gives unlimited testing instances to open source projects. It's my personal goal to have automatic e2e and integration testing for each PR by the end of the month.

Need a way to clear localForage

We use localForage for our local storage wrapper. There currently isn't a good way to selectively delete items from a localForage instance, during e2e tests. It would be nice to have a generic function to allow clearing a localforage namespace, usable from our e2e tests. Something like:

it('clears the provided namespace', function () {
  var namespace = 'example';
  clearLocalStorage(namespace);

  // .. other tests ..
});

There may be a need to use browser.wait() or browser.executeAsyncScript() to accomplish this. As we begin testing functionality, we'll need this tool.

... alternatively, we could drop support for localForage and use the window storage directly (through some Angular wrapper). I see no reason to support such a flexible storage solution if our only browser support is for Chrome. We could also simply write our own wrapper.

Ship JavaScript app and dependencies in a single file.

The current bhima production builds ship individual files to the client in a large number of script tags (see index.html). This is bad practice. The correct way to distribute our JavaScript app is to minify and package the entire application in a single file and ship that once to the client.

For this issue to be satisfied, our index.html must contain this script tag as the only script tag:

<script src="js/app.min.js"></script>

Loading indicators on selects waiting on service HTTP requests. (Proposal)

This could be proposed as a requirement for bhima-2.X pages (like form validation etc.)

Anywhere a module elements waits on an asynchronous request it can cause the user interface to 'hang' or wait for the data to be populated - if this is indicated clearly it is very clear what the page is doing.

This is especially noticeable when loading modals that require additional data to be downloads, for a demonstration of the problem:

  1. navigate to Update Patients/Test Patient
  2. Throttle Chrome connection to GPRS
  3. Select 'Update Group Assignments'

As the modal downloads the available patient groups, nothing is displayed and the application is allowed to enter a broken or unhandled state.

Transfer module

During our daily meeting we decided to add a new module in finance to let the cashier veer money between the cash and the transfer account, so that the primary cash responsibility and auxiliary cash responsibility will be clearly separated.

Since the auxiliary cash is formatted for income only, the transfer module will write directly in the posting_journal table.

What do you think?
@IMA-WorldHealth/local-contributors

Decorate $q with $q.spread()

This is a request for a polyfill/decorator that will allow me to write much cleaner client-side code. Angular's $q service provides a tiny API. I've found myself writing the following code several times:

Service.detail(id)
.then(function (entitiy) {
  return [
   ServiceA.detail(entity.idA),
   ServiceB.detail(entity.idB),
   ServiceC.list(),
   ServiceD.methodX()
}).then(function (promises) {
  var entityA = promises[0];
  var entityB = promises[1];
  var entityC = promises[2];
  var entityD = promises[3];

  // logic!
})
.catch(handler);

This code is obtuse and hard to read. If we decorated $q with $q.spread() I could write:

Service.detail(id)
.then(function (entitiy) {
  return [
   ServiceA.detail(entity.idA),
   ServiceB.detail(entity.idB),
   ServiceC.list(),
   ServiceD.methodX()
}).spread(function (entityA, entityB, entityC, entityD) {

  // logic!
})
.catch(handler);

which is certainly much prettier. Adding methods to AngularJS services is easy with Angular.decorator.

Model the entire Primary Cash module as Journal Vouchers

After some analysis of the bhima-1.X primary cash module, I think we could model the entire functionality of the primary cash, with the exception of payroll, as journal vouchers.

Raison d'Etre

Benefits:

  1. Fewer interfaces for users to learn and master. More time can be spent on the user manual to explain the Journal Voucher module, rather than spending time maintaining multiple other modules.
  2. No more confusing decisions - is this transaction a generic income, or is there a proper way to do this in the application? Everything is a journal voucher!
  3. Fewer modules for developers to maintain - less code means we can spend more time on testing and refinement of the module. This cannot be overemphasized.
  4. Opportunity to build reusable components/models for other pages to benefit from. For example, the we may need a modal to look up accounts belonging to employees, conventions, suppliers, etc, we can develop it once, test it once, and use it to create employee payment journal vouchers, convention payment journal vouchers, and on any reports that we need may desire.

Costs:

  1. Requires completely scrapping the Primary Cash module's code and potentially API.
  2. Requires retraining the users at our test sight.

Design Proposal

In order to use Journal Vouchers for Primary Cash operations, we will need to have a Journal Voucher table in the database. This is different from the current method, where Journal Vouchers simply send data directly to the posting_journal. We need the voucher table so that we have an immutable record (like sale or cash) of the journal voucher created and can re-print the receipt at any time.

The table should be called voucher with fields uuid, date, project_id, reference, currency_id, amount, description, document_uuid, and user_id. There will be a joiner table voucher_items with columns uuid, account_id, debit, credit, voucher_uuid.

Additional Commentary

I strongly feel that our Primary Cash module is confusing and over-extended. It also fits our test site well, but probably will not make any sense when scaling to other hospitals. What happens if employees are not paid out of the primary cash, but instead the bank? One whole part of the module is useless.

As we are focusing on Primary Cash next, I would be interested in having a discussion with @IMA-WorldHealth/local-contributors to get feedback on this proposal.

Prefer DATETIME to DATE in the MySQL Database

As part of the bhima 2.X release cycle, I propose we migrate as many tables as possible to using DATETIME column types instead of DATE for storing date datapoints. Under this direction, we will design our table columns following these guidelines:

  • DATE should never be used. It does not store any time information, and might result in incorrect dates conversions between JS and SQL.
  • DATETIME should be used for every column that needs to store a JS Date() object. The SQL datatype does not convert records from their original timezone to UTC (like a TIMESTAMP does), preferring to store them in the time zone of the server.
  • TIMESTAMP should be used for every column that needs to know the create/update time of the record. This should be seen as information about the MySQL row, not the entity the row represents. TIMESTAMPs may help with data migrations and analytical tools later on.

It is worth reading the page on MySQL dates [1]. Also useful is this [2] Stack Overflow discussion (see top two answers).

[1] http://dev.mysql.com/doc/refman/5.7/en/datetime.html.
[2] http://stackoverflow.com/questions/409286/should-i-use-field-datetime-or-timestamp.

Proposal: Implement uib-datepicker for certain date inputs.

Angular UI's datepicker has come a long way in recent releases. The advantages of using uib-datepicker for (certain, if not all) date inputs are the following:

  1. Consistent cross-browser and cross-browser-versions behavior.
  2. Custom styling can be applied to the uib-datepicker implementation, whereas styling for the <input type="date"> is limited and browser specific.
  3. Custom date formats are possible.
  4. We can translate all the text on the uib-datepicker dynamically using $translate, which removes a dependency on the users' browser settings.
  5. Large area leads to less user input errors.

May be related to #58.

Design a state-driven form submit button

One major difficulty that bhima has faced is users double-clicking the submit button. This results in multiple form submissions. This proposal is for a submit button that has state so that it is disabled and shows a loading indication when submitting when submitting, and behaves like a regular button at all other times. The idea would be something like this:
Ready State
buttonreadystate
Loading State
buttonloadingstate

When loading, the button shows a loading indicator and disables itself. When not loading it is a regular button. This button in the HTML might look like this:

<button submit-button="Ctrl.loadingState" class="btn btn-primary" ng-click="Ctrl.submit()" type="submit"></button>

Edit date component

Directive to display a read only date that can enter a discrete manual update state to allow the date to be changed only if required.

This pattern has been used in a number of places and it would be good to standardise/ test it.

  • Aux Cash
  • Patient Registration
  • Patient Invoices

The component would have to states

  • Set - Date is read-only; pressing the 'Edit' button will allow the date to be changed
  • Update - It should be possible for the date to accept minimum and maximum values and report errors accordingly - A submit button should be pressed to return to the 'Set' state (required for submitting forms)

Patient Edit Component

Along with this issue #57 there are a number of components we used in many places in BHIMA that should be well researched, proposed and implemented.

Use a better session management store

The application currently depends on session-file-store, which seems to work, but doesn't inspire much confidence. This is my terminal:
session-file-store
I think we can do better.

We have had a number of issues with session timeouts and session persistence in the past. @sfount has previously proposed using redis to manage sessions (via connect-redis or an alternative), which may be investigated. Another interesting solution might be to use sqlite3 wrapped with connect-sqlite3.

For reference, the list of supported session stores is here.

Print Journal/Ledger Transaction Receipts (w/ Signature Fields)

This proposal is for a generic receipt (modal) for any given transaction in the General Ledger or Posting Journal.

Use Case
1 . Many of our Primary Cash transactions are really just account-to-account transactions with a nicer UI in front of them. Most, if not all, of these modules could use the same "Transaction Receipt" interface to print out the details of a transaction, instead of creating a custom receipt for each one.

  1. Before posting a transaction, it may need to be authorized by an additional signature - for example, the administrator or chief accountant (or both!) We should not expect them to do the posting. One way to facilitate this need is to print out a transaction for signing approval, get the signatures, and archive the paper for auditors. The user can then post the transaction, and look up the signature if any questions are raised later on.
  2. If an accountant edits an important transaction in the Posting Journal, they may need to get it re-approved. Instead of printing out the original receipt (which will load for sale/cash/vouchers/etc with the OLD outdated information), the user should print out the new version of the transaction to re-approval via signature.
  3. There may be a need for signatures on generic transactions made with the Journal Vouchers module. Instead of implementing its own receipt, it could also leverage the generic transaction receipt.

Technical Details
The transaction receipt must be a modal, showing all the important details of the transaction. This includes:

  1. transaction date
  2. debit
  3. credit
  4. label/text
  5. voucher id
  6. transaction id

As headers, the receipt should include:

  1. currency (not currency id)
  2. Enterprise (at the top, not part of the transaction).
  3. Date of printing receipt
  4. User printing the receipt
  5. A large UNPOSTED message if it is a posting journal record, rather than a general ledger record

As footers, the receipt should include:

  1. one or more signature fields (potentially #78).

Create an "Add a Location" modal

Any form which requires a location (using the location select component #35), will probably need to add a new location at some point. Instead of forcing navigation away from the page to a "location management page" as we did in bhima-1.X, we should instead drop in a modal to let the user specify a new location immediately.

The modal should allow a user to create a new location - a combination of country, province, sector, and village. The modal should accept an object of uuids (countryUuid, provinceUuid sectorUuid) to be injected into the controller via resolve(), and preselect that contry, province, and/or sector from the dropdown menus.

This component will directly link to #35.

Location Directive Refactor

Re: The comment at the top of the location directive.

* Note : Directive should have a separate template and link method;                                                             
*  - Angular doesn't allow you to template ng-model                                                                              
*  - I'm too stubborn to let that win, and (simplify everything) just hard-code in location selects                               
*  - This doesn't need to be this generic, and should be re-factored if required                                                  
*/

This directive should be updated to the latest 2.X standards. Specifically:

  • Separate all data into services
  • Latest angular form validation on selects
  • Separate template files
  • Tested end points + E2E

Make bhima's Tree Navigation awesome

A huge refactor of the CSS + logic powering bhima's Tree Navigation component just landed (#42). The tree is functional and re-skinned for 2.X standards. This issue is to track new features we might want to add to the navigation either for bhima 2.X or beyond. If a PR lands with any of these features, feel free to link them and tick the checkbox.

  • Page refresh should preserve the current highlighted tree module.
  • The navigation should match the base URL in the cases when $routeParams are present. (e.g. '/patients/:uuid?' should be matched in all the following cases: '/patients', 'patients/', 'patients/1324').
  • [:small_red_triangle_down: Low Priority] Colour coded routes showing category (this will happen one day) - for example:
  • Hospital - Blue
  • Finance - Orange
  • Inventory - Yellow
  • Stock - Green
  • Reports - Purple
  • End to End tests for all tree functionality
  • demonstrate that pages are remembered in the browsers cache.
  • demonstrate that the sort order is alphabetical on free nodes
  • demonstrate successful logout

Feature: drop-in signatures for reports/receipts

This is a request for a generic "signature" component that would allow users to insert custom signatures into reports. At minimum, the developer should be able to specify a signature with a signer key to display. The code would like like this...

<bh-signature signer="SIGNATURES.ACCOUNTANT"></bh-signature>

.. rendering a signature field for the accountant. The signer field would accept a key to be passed to $translate and templated into the HTML template. Adding signatures to a receipt would become incredibly easy.

Use dotenv to manage configurations

The npm dotenv module would help us manage production/development/testing environments much more clearly and efficiently than our current JSON setup. It would also give us a clear way to add new environmental variables (such as database configuration parameters, timers, etc) in the future.

For bhima, the basic idea would be to define an .env file (and .env.example for reference) that would not be synced to Github. It would have keys such as PORT, DB_PASS, DB_USER, DB_HOST, EMAIL_FREQUENCY, LOG_LEVEL etc, that are currently stored in /server/environment/config. The dotenv module would allow the server to load these configuration properties once to be shared with all child modules, rather than passing around a JSON object from module to module.

Replace localForage with native localstorage

This recommendation replaces the #91 issue by recommending we move to an alternative storage provider, removing the dependency on both localForage and angular-localforage. My formal recommendation is to move to ngStorage, which looks like a nice lightweight alternative. It only supports key-value storage, but all browsers have good support for key-value stores.

I'd be interested in seeing a prototype PR built with ngStorage. It does not use promises, so our code could potentially be much cleaner! Removing localForage would slim the application by a few kb.

Unify posting journal interface

The current journal code uses string matching and a function that takes in six parameters - some of them objects, numbers, or functions. We should re-write this interface to provide direct posting without the need for anything but a UUID. For example:

// inside controllers/finance/sales.js
// create a sale with some uuid
journal.postPatientInvoice(uuid);

// inside controllers/finance/cash.js
// create a cash payment with some uuid
journal.postCashPayment(uuid);

All information needed to post any record should already exist in the database.

Proposal: usage of services and code layout

In order to facilitate easily reading and reviewing the code (as well as nice JSDoc layouts), I propose we adopt the following guidelines for creating services within the application.

  1. Always use services over factories, unless a specific use case is desired.
  2. Always use the suffix 'Service' at the end of the service name.
  3. Always alias var service = this at the top of the service function.
  4. Always bind service methods at the top of the service function declaration. The method definitions should be declared later.
  5. Always write JSDoc documentation comments at the function definition.
  6. Always return service at the bottom of the service function declaration.

Here is an example:

angular.module('bhima.services')           // note: we are creating a 'service' instead of a 'factory'
.service('SomeService', SomeService);  // note: this name contains the suffix Service

SomeService.$inject = [ '$http', 'util' /*, other injects ... */];

function SomeService($http, util) {
  var service = this;  // note: we are aliasing the `this` reference.

  /** @method detail */
  service.detail = detail;

  /** @method someOtherMethod */
  service.someOtherMethod = someOtherMethod;

  // .... 

  /**
  * @desc The detail methods returns detailed records from the database
  * @param {Number} id A numerical id found in the database
  * @example
  * SomeService.detail(id)
  * .then(function (record) {
  *   vm.record = record;
  * });
  * @returns {Object} promise A promise object with the response.body inside.
  */
  function detail(id) {
    return $http.get('/some/endpoint' + id)
       .then(util.unwrapHttpResponse);
  }

  /**
  * @desc blah, blah, blah
  *  .... more JSDoc documentation
  */
  function someOtherMethod() {
    // ... code ... 
  }

  return service;  // Note: returning service at the bottom of the service.
}

Use Winston to configure logging

We currently use morgan middleware for logging HTTP requests and connections. Unfortunately, it does not support generic logging (for example, events or thrown errors) and only listens to HTTP connections (not available in libraries).

Winston provides a highly configurable logger that gives us the remaining functionality we lack. It supports the idea of log levels (for example, verbose, production, silent, ...) and outputs seamlessly to files. I propose we use it to compliment morgan, which seems to do a good job at logging HTTP requests.

Use lodash on the server to write cleaner code

A quite popular functional programming library is lodash. We've run into a couple use cases where it would be very useful to have on the server. Considering we are valuing testing, lodash is well-tested and would do well to replace out current util library functions.

Here are a few applications:

  1. Preprocessing arrays to insert into the database (filtering and filling).
  2. Potentially replacing dotjs with lodash templates (templating).
  3. Replace all of our current util with lodash/lang.

Interestingly, lodash is the most depended upon npm package [src]. You can bet it is well tested!

Rename hollydays to holidays

Our database tables and associated routes are all named "hollydays" or "holydays", in some cases, which should be corrected as we revisit these routes. The correct spelling is "holiday" (singular) or "holidays" (plural).

Feature: Link scanned medical documents with patient entity

Feature Proposal: Patient Attachments

This feature proposal expands the medical history records of the application.

One way to preserve patient documents is to scan them into the computer, upload them, and directly link them to a patient entity. In order to successfully accomplish this, we'll need to develop an appropriate method of linking, storing, backing up, and syncing patient documents.

In brief, a new database table, patient_attachment, will need to be created with the following columns: patient_uuid, document_uuid, label, timestamp. Any uploaded document will have the file name rewritten to a new uuid(). The patient_attachment table stores the original document name in the label field (editable in the future). The documents are stored on disk in a folder specified by the environmental variable UPLOAD_DIR.

We will need to design a way to sync documents across radio networks as well. Something like rsync might come in handy there.

The server side API should support the following routes:

  • POST /patients should allow an additional array of "attachments" (five maximum).
  • POST /patients/:uuid/attachments should add attachments to the patient
  • DELETE /patients/:uuid/attachments/:uuid should delete an attachment from the patient's attachments matching the provided ID.
  • DELETE /patients/:uuid/attachments should delete all attachments from the patient entity.
  • GET /patients/:uuid should return an attachments array on the patient object with ids for all of the entity's attachments
  • GET /patients/:uuid/attachments/ should return a list of patient attachments
  • GET /patients/:uuid/attachments/:uuid should serve the attachment to the browser as a download.

On the client side, the /patients/:uuid/edit route should allow a user to upload, remove, and show attachments much like patient groups or debtor groups.

Interested in feedback on this @IMA-WorldHealth/local-contributors.

Refine find-patient directive

The find-patient directive has been updated to BHIMA 2.X standards and is now a very solid base.

There are a few additional features that could be added to improve user experience and simplify use - as this directive is used in so many different modules it can be tackled by any developer that would like to address an issue.

Proposed Features

  • Use standard form components for success and failure states (maintain similar message but deprecate alert element)
  • Support binding the required hook for form validation
  • [Improvement] The "Patient Name" button should have tabindex = -1 in the HTML
  • Searching by patient name should be done in two steps to make the experience the same
    • A name is entered and results displayed
    • A result is clicked to select a patient
    • 'Submit' is pressed to confirm this patients selection
  • OR
    • The 'Submit' button is removed allowing the typeahead to confirm the search
  • Improvement: Add the following HTML tags to the underlying to prevent confusing browser rendering:
    • autocomplete="off"
    • autocorrect="off"
    • autocapitalize="off"

I will add any comments that are made below into this list of proposed features for the find-patient directive

Components To Build

These are components that we will need to build to make the application modular and testable. This list is subject to change, and each component should be described in its own issue.

Components

  • Loading Button (Issue: #57, PR #194)
  • Edit Date Component (Issue: #58, PR: #102)
  • Loading Indicator (Issue: #68)
  • Find Patient Component (Issue: #69, PRs: #116, #132)
  • Find Debtor Group Component (PR #134)
  • Find Account Component
  • Location Selection Component (Issue: #35, PR #108)
  • Signature Component (Issue: #78)
  • Headercrumb Component (PR #107)
  • UI Grid Status Indicator
  • Cashbox Select Component (PR #119)
  • Location Modal (Issue: #100, PR #136)
  • Currency Select Component (PR #178)

Store UUIDs as Binary(16)

For a while we have known that storing UUIDs as a 36 character (VARCHAR(36)) string is non optimal, both for the storage space it requires and for how long it takes to read/join tables on long strings.

Proposal:

  • Generate UUID as 36 length string
8598abec-c985-11e5-975b-6c29955775b0
  • Remove dashes to bring string length to 32
8598abecc98511e5975b6c29955775b0
  • Pass this value to the UNHEX() MySQL method to store it in the database as a Binary(16)
UNHEX(8598abecc98511e5975b6c29955775b0)
  • In order to read string value from the database pass the value through the HEX() method
HEX(Table.Uuid)

There are a number of research articles that seem to show storing UUIDs in this format reduces both space required and most importantly access/ join speed.

The change would mostly affect how UUIDs are written and read from the database and should not change very much application logic.
@IMA-WorldHealth/local-contributors This can be discussed and prioritised accordingly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.