Hi Dimitri,
Thanks for the thoughtful response. That makes a lot of sense. I especially appreciate the note about CSV being useful for working with non-techs, that seems very salient.
I guess the tension between Iniz and my proposal illuminates a deeper tension in OpenMRS: that between DB-stored config (“metadata”) and in-memory config (“Settings”). Iniz is really good at the former, for things that have good reason to be DB-stored config, e.g. drugs. (I’m hoping OCL-for-OpenMRS takes over the Concepts space, and does so justly; I don’t think anyone has figured out Concepts yet). (Does AddressHierarchy use Iniz to pull in config from the App Data Dir? Seems like it should…)
But there are a lot of things that we presently store in-DB that really ought to be stored in-memory. So I guess at the heart of my proposal is a new in-memory store, a Config tree. Things that fit the bill for this include…
- idgen
- locations
- personAttributeTypes
- programs
- encounters
- forms/fields
- logic rules
- programs
- providermanagement
- relationships
- roles
(Do you know how dashboards & patientSummaryWidgets are stored? I think these should also be in-memory, probably YAML-configurable…)
How have you been handling those things above that don’t have Readers in Iniz?
The idea of hierarchy and overriding is very interesting. I haven’t thought about it at all, really. I’ve been imagining that having inconsistent configurations should cause a fast failure. How will a client of Iniz define what is supposed to override what?
I imagine a declarative config-defining API that is, in theory, not format specific. It would define specifically the shape of the config tree. So, e.g., the code
import org.openmrs.config
// define a relationship config object
ConfigObject relationshipConf = new ConfigObject();
relationshipConf.addKey(required=True, auto=False)
relationshipConf.addStringField('aToB', runtimeMutable=True, required=True);
relationshipConf.addStringField('bToA', runtimeMutable=True, required=True);
relationshipConf.addStringField('description', runtimeMutable=True);
relationshipConf.addBooleanField('allowSelf', runtimeMutable=True, default=True);
ConfigEnum personTypes = new ConfigEnum<String>('patient', 'provider', 'nonProviderUser');
ConfigArray allowedPersonATypes = relationshipConf.addArray('allowedPersonATypes', personTypes);
ConfigArray allowedPersonBTypes = relationshipConf.addArray('allowedPersonBTypes', personTypes);
// tell config module to expect a top-level array of relationshipConfs
config.addArray('relationships', relationshipConf);
This might be satisfied by some YAML that looks like
relationships:
- key: DOC_PT
aToB: doctor
bToA: patient
allowedPersonATypes:
- provider
allowedPersonBTypes:
- patient
- nonProvideruser
- key: SIBLINGS
aToB: sibling
bToA: sibling
It could also be satisfied with a CSV that looks like
key, aToB, bToA, allowedPersonATypes, allowedPersonBTypes
DOC_TO_PT, doctor, patient, provider, "patient; nonProviderUser"
SIBLINGS, sibling, sibling,,
Let me know what you think of all that. I won’t be in Boston at that time; I’m based in Mexico. Looking forward to talking more about this though.