The ability to support Maker-Checker style processes in Mifos X has been requested and discussed through email by various community members and also at the Mifos Summit 2012. This page is being used to share and communicate initial thoughts on how this will be approached from a design and implementation point of view.
Note: as of now (12th November 2012), all content here is a work in progress and any development that follows along these lines is likely to change in some ways as we flesh out the functionality fully and seek to make it as 'invisible' / 'generic' as possible to the platform developer and API developer.
Here's the current understanding of what will be in Mifos X Maker-Checker Solution.
The MAKER-CHECKER Functionality Overview
A MAKER performs a maintenance function that has been designated as following the MAKER-CHECKER workflow. Instead of being immediately applied, the proposed changes are held in a queue (also known as an inbox). A CHECKER can pull the proposed changes from the inbox and then either a) ACCEPT the changes (possibly after some edits) b) REJECT the changes (possibly with some notes and possibly the MAKER can resubmit changes later).
The Maker-Checker concept can be used for quality improvement (4 Eyes) or fraud prevention (superior signs-off) purposes.
The plan is to do a basic prototype which can be demo'd (between 19th - 23rd Nov). During the demo, the scope of the initial release can be discussed.
PROTOTYPE SCOPE (expected availability 19th Nov)
Assume that the "Create Client" task always uses the Maker-Checker Workflow but no other task uses it.
Any application user with the permission to create a client.
Any application user having their is_checker box ticked.
Maker "Proposed Changes" Validation
Apply validation to the request parameters but no database validation at this point.
A CHECKER can see a queue of any proposed changes that they didn't MAKE themselves. A CHECKER can select an item from their queue and see the proposed changes before accepting or rejecting them.
FULL SCOPE (for discussion during demo)
Ability to globally enable and disable Maker-Checker functionality. Ability to enable and disable Maker-Checker workflow for each non-read task. ... and then the possiblity of adding further optional rules to limit the CHECKER to a specific ROLE or other things including transaction amount limits.
Any application user with the permission to perform a maintenance task (create, update, delete, disburse, repay etc).
Possibly any application user having their is_checker box ticked or it might be better to have a CHECKER permission or it might be enough to match any optional CHECKER rules set against the task (e.g. if a loan can only be approved by a Credit Officer role then any user having that role can be a CHECKER for approving loans even if they aren't 'ticked' as one. Data scoping is applied. CHECKER can only CHECK data they are allowed to see i.e. within their office hierarchy. Some flows might require more than one CHECK.
Maker "Proposed Changes" Validation
Apply validation to the request parameters and also apply database validation (probably done by rolling back a valid transaction if it is a MAKER transaction). This ensures that only valid transactions are put on the Maker-Checker Queue (at time of creation)
A CHECKER can see any proposed changes that they didn't MAKE themselves that they are allowed to CHECK. A CHECKER can select an item from their queue and see the proposed changes before accepting or rejecting them. Notes may be attached to acceptance or rejection and the MAKER can see these.
When a user views some data that is awaiting a CHECKER response, the current data is shown but there is a notification that there is a proposed change. Possibly, the user can click on a link to see the proposed change.
The workflow is managed using a maker-checker inbox (separate table) rather than by having statuses on the 'master' table.
Mifos has some examples of the maker-check concept - creating Centres, Groups and Clients and also Loan Approval. These example would be covered by this more general Maker-Checker solution.
The Mifos X api will probably be extended so that any proposed changes can be returned e.g. for 'Create Client' the UI would need the template data (defaults and allowed values) as per normal AND the proposed changes in JSON in order to show the details as typed by the MAKER. e.g. /clients?template=true&MakerCheckerId=787877
It would be good to see other software that employs the maker-checker concept to help us understand more fully what those looking for this functionality expect from the approach. Haven't seen one yet.
An entry created in a maker-checker table to indicate task (client creation) has been 'made' and requires 'checking'
The new client does not show on system when retrieving clients.
At present the existing API returns only the system id of the entity that has been created or updated. Through Maker-Check flow, new entities are not created yet so need to pass back system id for maker-checker entry and no id for new entity which client applications will have to handle.
The following describe one possible example usage of Maker-Checker for one particular operation: CREATE_CLIENT
Data-entry user creates a new client through the user interface entering correct details and presses submit
Maker-Checker is enabled for this operation so instead of a new client being added to the database, an entry is made in maker-checker table - the Maker information is populated at this point
An application user who has checker rights for CREATE_CLIENT needs to verify this entry before it can be persisted in database, reject it if not wanted or modify it if needed
REJECT: if the checker rejects the entry, what then?
MODIFY: should there be a facility to allow the checker to modify the entry?
VERIFY: entry should attempt to be persisted in database (at this point there could still be problems with persisting it, data integrity rules etc)
Possible schema for maker-checker table
drop table `m_maker_checker`;
CREATE TABLE `m_maker_checker` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`task_name` varchar(100) NOT NULL,
`task_json` text NOT NULL,
`maker_id` bigint(20) NOT NULL,
`made_on_date` datetime NOT NULL,
`checker_id` bigint(20) DEFAULT NULL,
`checked_on_date` datetime DEFAULT NULL,
(John W: probably need to have fields for name and id of related entity e.g. 'Loan', 7666 so the master data and proposed changes can be joined)
PRIMARY KEY (`id`),
KEY `FK_m_maker_m_appuser` (`maker_id`),
KEY `FK_m_checker_m_appuser` (`checker_id`),
CONSTRAINT `FK_m_maker_m_appuser` FOREIGN KEY (`maker_id`) REFERENCES `m_appuser` (`id`),
CONSTRAINT `FK_m_checker_m_appuser` FOREIGN KEY (`checker_id`) REFERENCES `m_appuser` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;