Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Convention Workflow

Example of a farmOS Convention workflow, using farmOS.js & SurveyStack

Start by creating a farmOS.js instance configured to connect to your farmOS server, authorize it, yada yada...

const remote = { /** host url, config, etc */};
const farm = farmOS({ remote })
farm.remote.authorize(username, password);

Fetch and load the Activity log schema from the server:

farm.schema.fetch('log', 'activity')
  .then(s => { farm.schema.set('log', 'activity', s) });

You can also cache the schema somewhere, pass it around, do what you will with it. Importantly, though, your farmOS.js instance now has it, so it knows how to create activity logs and send them back to the server. Later, when the user wants to create a convention based on the Activity log, SurveyStack asks for that schema again:

const activitySchema = farm.schema.get('log', 'activity');

At this point, I just have to imagine what SurveyStack will do, because I don't know its internals, but let's say it looks something like this:

const options = { base: activitySchema };
  .then(convention => SurveyStack.convention.cache(convention));

A lot of hand-waving with that .create() method, but let's say it creates a whole GUI form, gets user input on what fields in the Activity log to modify or constrain somehow, then passes the results back as a convention object after the form is submitted so SurveyStack can store in its database somehow.

That convention object might look something like this, as JSON:

  "id": "",
  "name": "log--activity--forage",
  "version": "1.0.0",
  "entity": "log",
  "bundle": "log--activity", // the parent schema, in essence
  "constraints": [
      "field": "status",
      "constraint": {
        "$schema": "",
        "$id": "",
        "enum": ["done", "pending"] // whereas a plain activities can also be "in-progress"
      "field": "name",
      "constraint": {
        "$schema": "",
        "$id": "",
        "maxLength": 32
      "field": "category",
      "constraint": {
        "$schema": "",
        "$id": "",
        "const": "Forage" // it always has the forage category, basically
  "schema": {
    /** full JSON Schema for a log that complies with both the log--activity
    schema AND the log--activty--forage */

Then, at some point, you could retrieve the cached convention and publish it:

  .then(convention => SurveyStack.convention.publish(convention));

Now anyone who goes to, which we're also using as the convention's id, can get the entire JSON of that convention document.

Later, SurveyStack can get the forage activity from another user and send it off to farmOS:

  .then(convention => {
    return SurveyStack.farmerSurvey.create({ convention });
  .then(results => {
    const { data: forageLog } = results;
    return farm.log.send(forageLog);

And farmOS will accept it just as it would any other Activity log, w/o any knowledge of the convention per se, but it will still be compliant with the constraints of the forage convention.

As a rule:

A log that is valid for a farmOS convention (eg, log--activity--forage) will always be valid for the convention's parent bundle (eg, log--activity), but a log that is valid for the parent bundle will only sometimes, and not always, be valid for the convention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment