EventideSystems / obsekio

GNU Affero General Public License v3.0
0 stars 0 forks source link

Move state representation to a separate model #25

Closed ferrisoxide closed 5 months ago

ferrisoxide commented 5 months ago

Background

Currently the state of a checklist (or more specifically the checklist instance model) is stored within the actual markdown contents. Every time a user clicks on / off a checklist item the code modifies the underlying text content.

While this makes rendering checklists trivial, it complicates data analysis. We have three basic requirements when it comes to data analysis:

  1. longitudinal data (reporting on history of clicks / comments over time)
  2. current state (for presentation purposes)
  3. historical state (point-in-time presentation of a checklist)

Ultimately there has to be a single source of truth in the system. Traditionally we might do this by having a canonical current state, with an audit log for reporting and reconstructing point-in-time state. However, it feels we might be better off using Event Sourcing - or at least having an event-driven architecture to manage state.

Proposed Solution

Sources of Truth

  1. The source of truth for the structure of a checklist exists as markdown content. User will author this directly, so it doesn't make sense to have the truth elsewhere. NB checklists will necessarily be versioned.
  2. The source of truth for the state of a checklist is the log of all events. We can derive both current state and historical state from the log, whereas having separate state and audit log models implies two sources of truth (which may not necessarily correspond).

Derived Facts

From the sources of truth we can synthesize or maintain separate representations of the truth. For now, we can call these "facts" and consider a couple of examples - though they are by no means exhaustive:

These can be cached for convenience, but they should also be able to be regenerated from sources of truth at any time.

Rough Data Model

NB this a very rough cut of the representation of checklists in the workspace domain. The library domain is similar but doesn't have the same level of data representation (e.g. doesn't need item states or instances).

There are other configuration-related entities that abut this domain, and some of the models here will need fleshing out, but this is a general idea of how the domain might look like.  


classDiagram
    class Checklist
    class ChecklistVersion
    class ChecklistInstance
    class ChecklistItem
    class ChecklistItemEvent
    class ChecklistState{
      <<enumeration>>
      draft
      published
    }
    class ChecklistItemState{
      <<enumeration>>
      checked
      unchecked
    }
    class ChecklistInstanceModel{
      <<enumeration>>
      single
      longitudinal
      concurent
    }
    ChecklistVersion --> Checklist
    ChecklistInstance --> ChecklistVersion
    ChecklistItem --> ChecklistInstance
    ChecklistVersion --> ChecklistState
    ChecklistItem --> ChecklistItemState
    ChecklistItemEvent --> ChecklistInstance
    ChecklistItemEvent --> ChecklistItemState
    ChecklistInstanceSnapshot --> ChecklistInstance
    ChecklistInstanceSnapshot --> ChecklistItem
    Checklist --> ChecklistInstanceModel
    ChecklistInstance --> ChecklistInstanceModel
    ChecklistInstanceSnapshot <|-- CurrentChecklistInstanceSnapshot 
ferrisoxide commented 5 months ago

@CobolKing this is in line with conversations we've been having outside of Github

ferrisoxide commented 5 months ago

DEV NOTE

This model might not be correct. Workspace checklists, as opposed to ones in the library, may not need versioning. Probably best to get back to writing actual use cases and see what emerges from that.

ferrisoxide commented 5 months ago

Done. Closing