The knowledge layer is powered by ex_datalog.
It contains business facts, accounting facts, event facts, entity facts, account
facts, relationship facts, policy facts, template facts, mapping facts, and
constraint facts.
What the knowledge layer answers
- Should this event be processed?
- Is this event blocked?
- Does this event require approval?
- Which accounting policy applies?
- Which posting template applies?
- Which debit/credit account should be used?
- Which dimensions are required?
- Which account mapping applies?
- Which warnings should be attached?
The important rule
Datalog should not construct Elixir structs. Datalog decides facts and relationships. Elixir materializes journals, postings, and persisted records.
Program
Logistiki.Knowledge.Program is an ExDatalog.Schema that declares:
- Relations for per-event runtime facts (
event_type,event_amount_cents,event_account,event_cash_account,event_fee_income_account, ...). - Relations for derived business rules (
blocked,requires_approval). - Relations for accounting policy selection (
policy). - Relations for posting templates and account roles (
template,template_posting,requires_dimension,account_role_static,account_role). - Static facts for templates, template postings, required dimensions, and static account mappings.
- Rules that derive
blocked,requires_approval,policy, andaccount_rolefrom the per-event facts.
Runtime facts
Logistiki.Knowledge.Facts.generate/1 builds a list of {relation, values}
facts from a Logistiki.Event.Normalized event. The event is represented by the
fixed atom :evt inside the Datalog program. Logistiki.Knowledge.KnowledgeBase
loads Program.program/0 (which includes the compile-time static facts), adds
the runtime facts via ExDatalog.Program.add_fact/3, materializes the knowledge,
and interprets the result into a Logistiki.Knowledge.Result.
Result
Logistiki.Knowledge.Result captures:
blocked,requires_approvalpolicy— the selected accounting policy atomtemplate— the selected template (= the policy in v0.1.0)template_postings— ordered posting specsaccount_roles—role => account_coderequired_dimensionsexplanation
Public API
Logistiki.Knowledge.evaluate(normalized_event)
Logistiki.Knowledge.materialize(normalized_event)
Logistiki.Knowledge.load_program()
Logistiki.Knowledge.assert_fact(predicate, arguments)Logistiki.Knowledge.PolicySelector and
Logistiki.Knowledge.TemplateResolver are thin façades for callers that only
need the policy or template decision.