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
1 2 3 4 5 6 7 8 9 10
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
1 2 3 4 5 6 7 8 9 10
# 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


Be pragmatic, this is a guide.


Engage with Customer / Domain experts

Encourage them to describe their process and root problem.


DataGrid: build cells, rows and columns

Cells referenced by x,y (like spreadsheet)


  • Cells with conditional formatting, e.g. cell is red is value over threshold
  • Cells with formula, e.g. SUM(A5-A6)

Table has default cell attributes, e.g. height/width

View gist:8949744ef2cc11d50cd0
1 2 3 4 5 6 7 8 9
-event4+5-> [Process1] -event1-> [Process2] -event2-> [process4] -event4->
-event1-> [Process3] -event3-> [process5] -event5->
Each process could be a pool of processes. Each process can use the Actor model.
Events need to include a uuid so inputs and results (event4 + event5) can be matched up.
Event1 is consumed by two different processes break up different processing of input.
Something went wrong with that request. Please try again.