Skip to content


The aim of this gem is to standardise reporting. It also allow registration of reports and have them appear in the UI.

It will be used for reports which can not otherwise be produced with the data grid.

To register a report:

Reporting.register(name:   'BRU Recruitment Report', 
View configuration.rb
require 'dry/container'
require 'logger'
module Oxygen
class Configuration
extend Dry::Container::Mixin
# default configuration
register('reports', [])
View pull.rb
# DoSomething has dependency on Configuration and pulls default from Configuration
module MyThingy
class DoSomething
def call(input, suffix = nil)
input + (suffix || default_suffix)


Reagent binds components to data using an atom. An atom is a ClojureScript reference type. An atom references an immutable value, but the reference itself is mutable, it can be changed using reset! and swap! to reference a different imumtable value. Changes to atom's are atomic.

The value can be retrived by dereferencing the atom using deref or the @ prefix.

Functions can be attached to atoms to watch for changes, the function will get the atoms old and new state as arguments.

Reagent provides its own atom, reagent/atom, which has watches setup to rerender compontents which reference the atom.

require 'mongo'

class DynaModel
  include Virtus.model

  def save
View stack
Testing documas-cljs.routing-test
Ran 8 tests containing 9 assertions.
0 failures, 0 errors.
Tests succeeded.
Compiling "target/testable.js" failed.
java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom clojure.lang.RT.seq
core.clj:133 clojure.core/seq
View pres.rb
# given these models
class Study < AR::Base
class Site < AR::Base
class Visit < AR::Base

Data referenced in code

Sometimes data is referenced in code, for example a dynamically created "tab" has a key (it's unique id).

If we want to fetch that tab in our code, we do Tab.find_by_key('organisations'). This will break if a user deletes this tab.

Locking some fields of an entity should solve this.

EntityLock(entity_class, entity_uuid, attributes, reason)


Low level search

Updating the index

When a resource is CRUD'd it must update the Search index:

Search.put(:study, attributes) # create, update
Search.rm(:study, id) # delete

Task Orientated Authorization

Actor <-> Role <-> Task

  • Not a CRUD only solution
  • Tasks can describe anything
  • Roles and/or Policies
  • Actors are typically users, but can be any object
  • Actors are not polluted with authentication concerns
  • Tasks can be added at runtime
Something went wrong with that request. Please try again.