Skip to content

Latest commit

 

History

History
1135 lines (997 loc) · 31.2 KB

File metadata and controls

1135 lines (997 loc) · 31.2 KB

API

  • (JSON-in) All methods pass their argument in a json hash in the HTTP request body.
  • (JSON-out) All methods return a json hash in the HTTP response body.
  • GET is used for queries.
  • POST is used for modifiers.
  • Paths are not REST-ful.

Cluster

A cluster is the umbrella over a multi Language-Test-Framework (LTF) practice: it offers 2..5 LTFs, holding one ordinary Group per LTF (its children). A cluster is never joined directly; a joiner joins one of its child groups.

POST cluster_create

  • description

    • Creates a cluster from the given manifest and returns its id. The manifest holds the group-wide exercise and an ltfs array (2..5 per-LTF group manifests). For each ltf a child group is created, carrying a cluster_id back-pointer, and the cluster references the children.
  • parameters

    Name Type Description
    manifest Hash with exercise:String and ltfs:Array[Hash], the 2..5 per LTF group manifests (as built by creator).
  • returns

    • the id of the created cluster.
    • status 400 if ltfs does not hold 2..5 entries.
  • example

    $ curl \
      --data '{"manifest":{"exercise":"Tennis","ltfs":[...]}}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request POST \
        https://${DOMAIN}:${PORT}/cluster_create | jq .
    {
      "cluster_create": "dFg8Us"
    }

GET cluster_manifest

  • description

    • Gets the manifest of the cluster with the given id: its exercise and its children (one per LTF, each {ltf_display_name, group_id}).
  • parameters

    Name Type Description
    id String The cluster id.
  • returns

    • the manifest of the cluster with the given id.
  • example

    $ curl \
      --data '{"id":"dFg8Us"}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/cluster_manifest | jq .
    {
      "cluster_manifest": {
        "id": "dFg8Us",
        "exercise": "Tennis",
        "children": [
          { "ltf_display_name": "Python, unittest", "group_id": "g1AbCd" },
          { "ltf_display_name": "Ruby, MiniTest",   "group_id": "g2EfGh" }
        ]
      }
    }

GET cluster_exists?

  • description

    • Determines if a cluster with the given id exists.
  • parameters

    Name Type Description
    id String The cluster id.
  • returns

    • true if a cluster with the given id exists, otherwise false.
  • example

    $ curl \
      --data '{"id":"dFg8Us"}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/cluster_exists? | jq .
    {
      "cluster_exists?": true
    }

Group

A group is a shared practice for a single Language-Test-Framework: joiners join it, each allocated a distinct avatar (Lion, Salmon, Bee, etc) and their own Kata of the group's exercise. A group holds up to 64 katas, one per avatar. In a Cluster a group is one of the children (one per LTF).

POST group_create

  • description

    • Creates a new group from the given manifest and returns its id.
      See group_manifest below for a manifest overview.
      See here for more detailed manifest information.
  • parameters

    Name Type Description
    manifest Hash created by creator from languages-start-points and exercises-start-points or custom-start-points.
  • returns

    • the id of the created group.
  • example

    $ curl \
      --data '{"manifest":...}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request POST \
        https://${DOMAIN}:${PORT}/group_create | jq .
    {
      "group_create":  "dFg8Us"
    }

GET group_manifest

  • description

    • Gets the manifest used to create the group with the given id.
  • parameters

    Name Type Description
    id String The group id.
  • returns

    • the manifest of the group with the given id.
  • example

    $ curl \
      --data '{"id":"dFg8Us"}' \
      --fail \    
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/group_manifest | jq .
    {
      "group_manifest": {
        "display_name": "Bash, bats",
        "image_name": "cyberdojofoundation/bash_bats:53d0c9c",
        "filename_extension": [
          ".sh"
        ],
        "tab_size": 4,
        "visible_files": {
          "test_hiker.sh": { "content": "..." },
          "bats_help.txt": { "content": "..." },
          "hiker.sh": { "content": "..." },
          "cyber-dojo.sh": { "content": "..." },
          "readme.txt": { "content": "..." }
        },
        "exercise": "LCD Digits",
        "version": 1,
        "created": [2020,10,19,12,51,32,991192],
        "id": "REf1t8",
        "highlight_filenames": [],
        "max_seconds": 10,
        "progress_regexs": []
      }
    }  

GET group_exists?

  • description

    • Determines if a group with the given id exists.
  • parameters

    Name Type Description
    id String The group id.
  • returns

    • true if a group with the given id exists, otherwise false.
  • example

    $ curl \
      --data '{"id":"dFg8Us"}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/group_exists? | jq .
    {
      "group_exists?": true
    }

POST group_join

  • description

    • Creates a new kata in the group with the given id and returns the kata's id.
  • parameters

    Name Type Description
    id String The group id.
    indexes Array[int] (optional). The candidate avatar indexes (from 0..63) in preference order. The first index not already taken in the group is allocated. Defaults to a shuffled 0..63. Pass a custom order to influence which avatar a joiner gets. For example, in a cluster, list the avatars not yet used elsewhere in the cluster first, so avatars stay distinct across the cluster's groups.
  • returns

    • the id of the created kata, or null if the group is already full.
  • example

    $ curl \
      --data '{"id":"dFg8Us"}' \
      --fail \    
      --header 'Content-type: application/json' \
      --silent \
      --request POST \
        https://${DOMAIN}:${PORT}/group_join | jq .
    {
      "group_join": "a8gVRN"
    }

GET group_joined

  • description

    • Returns the kata-id and kata-events-summary keyed against the kata's avatar-index (0-63) for the katas that have joined a group.
  • parameters

    Name Type Description
    id String The group's id or the id of any kata in the group.
  • returns

    • a Hash.
  • example

    $ curl \
      --data '{"id":"dFg8Us"}' \
      --fail \    
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/group_joined | jq .
    {
      "group_joined": {
        "7": {
          "id": "a8gVRN",
          "events": [...]
        },
        "29": {
          "id": "gUNjUV",
          "events": [...]
        },
        ...
       }
    }

POST group_fork

  • description

    • Creates a new group whose starting files are a copy of the files in the kata with the given id at the given index. The new group is not a fork in the git sense; that is, it is not a 'deep' copy, the history of commits (one per test event) that exist in the kata being forked are not copied.
  • parameters

    Name Type Description
    id String The id of the kata being forked.
    index int The event index to fork from.
  • returns

    • the id of the created group.
  • example

    $ curl \
      --data '{"id":"dFg8Us", "index":23}' \
      --fail \    
      --header 'Content-type: application/json' \
      --silent \
      --request POST \
        https://${DOMAIN}:${PORT}/group_fork | jq .
    {
      "group_fork": "a8gVRN"
    }

Kata

A kata is one participant's practice: created from a manifest (an exercise for a single Language-Test-Framework), it records every event as its own git commit - the create, each file create/delete/rename/edit, and each test run with its traffic-light colour (red, amber, green). Each avatar in a Group is a kata.

POST kata_create

  • description

    • Creates a new kata from the given manifest and returns its id.
      See kata_manifest below for a manifest overview.
      See here for more detailed manifest information.
  • parameters

    Name Type Description
    manifest Hash created by creator from languages-start-points and exercises-start-points (or custom-start-points).
  • returns

    • the id of the created kata.
  • example

    $ curl \
      --data '{"manifest":...}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request POST \
        https://${DOMAIN}:${PORT}/kata_create | jq .
    {
      "kata_create":  "dFg8Us"
    }

GET kata_manifest

  • description

    • Gets the manifest used to create the kata exercise with the given id.
  • parameters

    Name Type Description
    id String The kata id.
  • returns

    • the manifest of the kata with the given id.
  • example

    $ curl \
      --data '{"id":"4ScKVJ"}' \
      --fail \    
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/kata_manifest | jq .
    {
      "kata_manifest": {
        "display_name": "Bash, bats",
        "image_name": "cyberdojofoundation/bash_bats:53d0c9c",
        "filename_extension": [ ".sh" ],
        "tab_size": 4,
        "visible_files": {
          "test_hiker.sh": { "content": "..." },
          "bats_help.txt": { "content": "..." },
          "hiker.sh": { "content": "..." },
          "cyber-dojo.sh": { "content": "..." },
          "readme.txt": { "content": "..." }
        },
        "exercise": "LCD Digits",
        "version": 1,
        "created": [2020,10,19,12,52,46,396907],
        "group_id": "REf1t8",
        "group_index": 44,
        "id": "4ScKVJ",
        "highlight_filenames": [],
        "max_seconds": 10,
        "progress_regexs": []
      }
    }  

GET kata_exists?

  • description

    • Determines if a kata exercise with the given id exists.
  • parameters

    Name Type Description
    id String The kata id.
  • returns

    • true if a kata with the given id exists, otherwise false.
  • example

    $ curl \
      --data '{"id":"4ScKVJ"}' \
      --fail \    
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/kata_exists? | jq .
    {
      "kata_exists?": false
    }

GET kata_events

  • description

    • Gets the summary of all current events for the kata with the given id.
  • parameters

    Name Type Description
    id String The kata id.
  • returns

    • an Array holding the events summary of the kata with the given id. Each event carries three positional indexes, computed on read (the event-write POSTs do not return them):
      • index - the event's absolute position, so events[index].index == index.
      • major_index - the number of red/amber/green traffic-lights up to and including this event (the created event is 0); a traffic-light is always at major_index with minor_index 0.
      • minor_index - 0 on a traffic-light; incremented by each inter-test file event (create/delete/rename/edit) since the previous traffic-light.
  • example

    $ curl \
      --data '{"id":"4ScKVJ"}' \
      --fail \    
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/kata_events | jq .
    {
      "kata_events": [
        { "index": 0,
          "major_index": 0,
          "minor_index": 0,
          "time": [2020,10,19,12,52,46,396907],
          "colour": "create",
          "event": "created",
          "diff_added_count": 0,
          "diff_deleted_count": 0
        },
        { "index": 1,
          "major_index": 1,
          "minor_index": 0,
          "time": [2020,10,19,12,52,54,772809],
          "colour": "red",
          "duration": 0.491393,
          "predicted": "none",
          "diff_added_count": 4,
          "diff_deleted_count": 1,
          "laptop_id": "02cfdffb5c0c31221b837a153d1108e6cd19fd6cef11db27c8457a1e63caf46f",
          "tab_seq": 1
        },
        { "index": 2,
          "major_index": 2,
          "minor_index": 0,
          "time": [2020,10,19,12,52,58,547002],
          "colour": "amber",
          "duration": 0.426736,
          "predicted": "none",
          "diff_added_count": 2,
          "diff_deleted_count": 0,
          "laptop_id": "02cfdffb5c0c31221b837a153d1108e6cd19fd6cef11db27c8457a1e63caf46f",
          "tab_seq": 2
        },
        { "index": 3,
          "major_index": 3,
          "minor_index": 0,
          "time": [2020,10,19,12,53,3,256202],
          "colour": "green",
          "duration": 0.438522,
          "predicted": "none",
          "diff_added_count": 3,
          "diff_deleted_count": 2,
          "laptop_id": "02cfdffb5c0c31221b837a153d1108e6cd19fd6cef11db27c8457a1e63caf46f",
          "tab_seq": 3
        }
      ]
    }

GET kata_event

  • description

    • Gets the full details for the kata event whose kata has the given id whose event has the given index.
  • parameters

    Name Type Description
    id String The kata id.
    index int Negative values count backwards, -1 is the last index.
  • returns

    • the event with the given id and index.
  • example

    $ curl \
      --data '{"id":"4ScKVJ","index":2}' \
      --fail \    
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/kata_event | jq .
    {
       "kata_event": {
         "files": {
           "test_hiker.sh": { "content": "..." },
           "bats_help.txt": { "content": "..." },
           "hiker.sh": { "content": "..." },
           "cyber-dojo.sh": { "content": "..." },
           "readme.txt": { "content": "..." }
         },
         "stdout": {
           "content": "...",
           "truncated": false
         },
         "stderr": {
           "content": "...",
           "truncated": false
         },
         "status": "1",
         "index": 2,
         "major_index": 2,
         "minor_index": 0,
         "time": [2020,10,19,12,52,58,547002],
         "colour": "amber",
         "duration": 0.426736,
         "predicted": "none",
         "diff_added_count": 2,
         "diff_deleted_count": 0,
         "laptop_id": "02cfdffb5c0c31221b837a153d1108e6cd19fd6cef11db27c8457a1e63caf46f",
         "tab_seq": 2
       }
     }

GET katas_events

  • description

    • Gets the full details for the kata events with the given ids and indexes. A Batch-Method for kata_event(id,index).
  • parameters

    Name Type Description
    ids Array[String] The kata ids.
    index Array[int] The corresponding event indexes.
  • returns

    • the events with the given ids and indexes.
  • example

    $ curl \
      --data '{"ids":["4ScKVJ","De87Aa"],"indexes":[23,45]}' \
      --fail \    
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/katas_events | jq .
    {
       "katas_events": {
         "4ScKVJ": {
           "23": {
             "files": { ... },
             "stdout": { ... }  
             ...
           }
         },
         "De87Aa": {
           "45": {
             "files": { ... },
             "stdout": { ... }  
             ...
           }
         }
       }
     }

GET kata_download

  • description

    • Returns a gzipped tar archive of the kata's git repository, base64-encoded.
  • parameters

    Name Type Description
    id String The kata id.
  • returns

    • an Array of two elements: the suggested filename (String) and the base64-encoded tgz content (String).
  • example

    $ curl \
      --data '{"id":"4ScKVJ"}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/kata_download | jq .
    {
      "kata_download": [
        "cyber-dojo-2026-4-6-4ScKVJ.tgz",
        "H4sIAAAAAAAAA+..."
      ]
    }

POST kata_file_create

  • description

    • Records a new empty file being created in the browser. If any existing file has been edited since the last save, that edit is recorded first as a file_edit event.
  • parameters

    Name Type Description
    id String The kata id.
    files Hash The current files (the new filename is not yet present).
    filename String The name of the file being created.
    laptop_id String See laptop_id.
    tab_seq int See tab_seq.
  • returns

    • nothing meaningful (a 200 ack); the event is recorded - read it back via kata_events.
  • example

    $ curl \
      --data '{"id":"4ScKVJ","files":{...},"filename":"utils.sh","laptop_id":"02cfdffb5c0c31221b837a153d1108e6cd19fd6cef11db27c8457a1e63caf46f","tab_seq":1}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request POST \
        https://${DOMAIN}:${PORT}/kata_file_create

POST kata_file_delete

  • description

    • Records a file being deleted in the browser. If any existing file has been edited since the last save, that edit is recorded first as a file_edit event.
  • parameters

    Name Type Description
    id String The kata id.
    files Hash The current files (the filename to delete is still present).
    filename String The name of the file being deleted.
    laptop_id String See laptop_id.
    tab_seq int See tab_seq.
  • returns

    • nothing meaningful (a 200 ack); the event is recorded - read it back via kata_events.
  • example

    $ curl \
      --data '{"id":"4ScKVJ","files":{...},"filename":"utils.sh","laptop_id":"02cfdffb5c0c31221b837a153d1108e6cd19fd6cef11db27c8457a1e63caf46f","tab_seq":2}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request POST \
        https://${DOMAIN}:${PORT}/kata_file_delete

POST kata_file_rename

  • description

    • Records a file being renamed in the browser. If any existing file has been edited since the last save, that edit is recorded first as a file_edit event.
  • parameters

    Name Type Description
    id String The kata id.
    files Hash The current files (old_filename is present; new_filename is not yet present).
    old_filename String The current name of the file.
    new_filename String The new name of the file.
    laptop_id String See laptop_id.
    tab_seq int See tab_seq.
  • returns

    • nothing meaningful (a 200 ack); the event is recorded - read it back via kata_events.
  • example

    $ curl \
      --data '{"id":"4ScKVJ","files":{...},"old_filename":"utils.sh","new_filename":"helpers.sh","laptop_id":"02cfdffb5c0c31221b837a153d1108e6cd19fd6cef11db27c8457a1e63caf46f","tab_seq":3}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request POST \
        https://${DOMAIN}:${PORT}/kata_file_rename

POST kata_file_edit

  • description

    • Records a file edit event if any file content has changed since the last save. If no file has changed, no event is recorded.
  • parameters

    Name Type Description
    id String The kata id.
    files Hash The current files.
    laptop_id String See laptop_id.
    tab_seq int See tab_seq.
  • returns

    • nothing meaningful (a 200 ack); the file_edit event, if any, is recorded - read it back via kata_events.
  • example

    $ curl \
      --data '{"id":"4ScKVJ","files":{...},"laptop_id":"02cfdffb5c0c31221b837a153d1108e6cd19fd6cef11db27c8457a1e63caf46f","tab_seq":4}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request POST \
        https://${DOMAIN}:${PORT}/kata_file_edit

POST kata_ran_tests

  • description

    • Record a test event with no prediction.
  • parameters

    Name Type Description
    id String The kata id.
    files Hash The files which created stdout,stderr,status in the same format as kata_event
    stdout Hash The stdout produced from files, in the same format as kata_event
    stderr Hash The stderr produced from files, in the same format as kata_event
    status String The status produced from files, in the same format as kata_event
    summary Hash Extra event data to store, eg duration,time,colour
    laptop_id String See laptop_id.
    tab_seq int See tab_seq.

POST kata_predicted_right

  • description
    • Record a test event with a correct prediction.

POST kata_predicted_wrong

  • description
    • Record a test event with an incorrect prediction.

POST kata_reverted

  • description
    • Revert back to a previous traffic-light.

POST kata_checked_out

  • description
    • Checkout a traffic-light from a different avatar.

GET kata_option_get

  • description
    • Get a theme (dark/light) or colour (on/off) or prediction (on/off) option.

POST kata_option_set

  • description
    • Set a theme (dark/light) or colour (on/off) or prediction (on/off) option.

POST kata_fork

  • description

    • Creates a new kata whose starting files are a copy of the files in the kata with the given id at the given index. The new kata is not a fork in the git sense; that is, it is not a 'deep' copy, the history of commits (one per test event) that exist in the kata being forked are not copied.
  • parameters

    Name Type Description
    id String
    index int
  • returns

    • the id of the created kata.
  • example

    $ curl \
      --data '{"id":"dFg8Us", "index":23}' \
      --fail \    
      --header 'Content-type: application/json' \
      --silent \
      --request POST \
        https://${DOMAIN}:${PORT}/kata_fork | jq .
    {
      "kata_fork": "a8gVRN"
    }

ID

Find the full Cluster/Group/Kata information of any id.


GET id_chain

  • description

    • Returns the chain of ids from the given id up to its topmost containing entity, ordered bottom-to-top as [{type,id}, ...] where type is kata, group or cluster. The first entry is the given id; the last entry's id is the topmost. Lets a caller resolve any id up to the practice it belongs to (eg a kata up to its cluster).
  • parameters

    Name Type Description
    id String A kata, group or cluster id.
  • returns

    • the id chain. A solo kata returns just itself; a kata in a cluster returns its kata, then group, then cluster.
  • example

    $ curl \
      --data '{"id":"5rTJv5"}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/id_chain | jq .
    {
      "id_chain": [
        { "type": "kata",    "id": "5rTJv5" },
        { "type": "group",   "id": "g1AbCd" },
        { "type": "cluster", "id": "dFg8Us" }
      ]
    }

Diff

Compare a Kata's files between two event indexes.

GET diff_lines

  • description

    • A diff of two sets of files (designated with was_index and now_index) from the kata with the given id. Every line of every file is returned - not just the changed lines with a few unchanged lines either side as a normal git diff would give. Unchanged files and files renamed with identical content are also included.
  • parameters

    Name Type Description
    id String The kata id.
    was_index Integer The event index of the first set of files.
    now_index Integer The event index of the second set of files.
  • returns

    • an Array of Hashes, one per file. Each Hash has the following keys:
      • "type" - one of "created", "deleted", "renamed", "changed", "unchanged".
      • "old_filename" - the filename at was_index, or null if "type" is "created".
      • "new_filename" - the filename at now_index, or null if "type" is "deleted".
      • "lines" - an Array of Hashes, each with "type" ("added", "deleted", "same", or "section").
      • "line_counts" - a Hash with "added", "deleted", and "same" counts.
  • example

    $ curl \
      --data '{"id":"4ScKVJ","was_index":3,"now_index":4}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/diff_lines | jq .
    {
      "diff_lines": [
        {
          "type": "changed",
          "old_filename": "hiker.py",
          "new_filename": "hiker.py",
          "lines": [
            { "type": "same",    "line": "class Hiker:", "number": 1 },
            { "type": "section", "index": 0 },
            { "type": "deleted", "line": "    pass",     "number": 2 },
            { "type": "added",   "line": "    def answer(self):", "number": 2 },
            { "type": "added",   "line": "        return 42",    "number": 3 }
          ],
          "line_counts": { "added": 2, "deleted": 1, "same": 1 }
        },
        ...
      ]
    }

GET diff_summary

  • description

    • The same as diff_lines except the returned Hashes do not include the "lines" key.
  • parameters

    Name Type Description
    id String The kata id.
    was_index Integer The event index of the first set of files.
    now_index Integer The event index of the second set of files.
  • returns

    • an Array of Hashes with "type", "old_filename", "new_filename", and "line_counts" (no "lines").
  • example

    $ curl \
      --data '{"id":"4ScKVJ","was_index":3,"now_index":4}' \
      --fail \
      --header 'Content-type: application/json' \
      --silent \
      --request GET \
        https://${DOMAIN}:${PORT}/diff_summary | jq .
    {
      "diff_summary": [
        {
          "type": "changed",
          "old_filename": "hiker.py",
          "new_filename": "hiker.py",
          "line_counts": { "added": 2, "deleted": 1, "same": 1 }
        },
        ...
      ]
    }

Probe

Operational health checks, plus the git sha of the running image.

GET alive?

  • description
    • Liveness probe - is the service alive?
  • parameters
    • none
  • result
    • true
  • example
    $ curl --fail --silent --request GET https://${DOMAIN}:${PORT}/alive? | jq .
    {
      "alive?": true
    }

GET ready?

  • description
    • Readiness probe - is the service ready to handle requests?
  • parameters
    • none
  • result
    • true when the service is ready
    • false when the service is not ready
  • example
    $ curl --fail --silent --request GET https://${DOMAIN}:${PORT}/ready? | jq .
    {
      "ready?": false
    }

GET sha

  • description
    • The git commit sha used to create the Docker image.
  • parameters
    • none
  • result
    • the 40 character commit sha string.
  • example
    $ curl --fail --silent --request GET https://${DOMAIN}:${PORT}/sha | jq .
    {
      "sha": "41d7e6068ab75716e4c7b9262a3a44323b4d1448"
    }

laptop_id

The 64-char lowercase-hex id of the writer, used by the browser's read-side poll for unintended "mobbing" detection. It is two 32-char halves: the first 32 identify the browser (laptop) profile, the last 32 identify the writing tab (its tab_id), so the poll can tell one tab from another as well as one laptop from another. (A non-JS client that sends no tab_id falls back to its plain 64-char browser cookie.) The saver stamps a valid laptop_id onto the committed event verbatim; a value that is not 64 lowercase-hex characters is not trusted and is not stored, so the event reads as having an unknown writer.

Accepted by kata_file_create, kata_file_delete, kata_file_rename, kata_file_edit, kata_ran_tests, kata_predicted_right, kata_predicted_wrong, kata_reverted and kata_checked_out.


tab_seq

The writing tab's own monotonic event counter, minted in the browser and counting every event the tab fires (its first event is 1, the next 2, and so on). Together with laptop_id it forms the (laptop_id, tab_seq) idempotency key: the saver stamps it onto the committed event, and a later write carrying a (laptop_id, tab_seq) that is already committed is a no-op, so a redelivered write is never committed twice.

Accepted by kata_file_create, kata_file_delete, kata_file_rename, kata_file_edit, kata_ran_tests, kata_predicted_right, kata_predicted_wrong, kata_reverted and kata_checked_out.


JSON in

  • All methods pass their argument in a json hash in the http request body.
  • If there are no arguments you can use '' (which is the default for curl --data) instead of '{}'.

JSON out

  • All methods return a json hash in the http response body.
  • If the method does not raise, a string key equals the method's name. eg
    $ curl --silent -X GET https://${DOMAIN}:${PORT}/ready? | jq .
    {
      "ready?": true
    }
  • If the method raises an exception, a string key equals "exception", with a json-hash as its value. eg
    $ curl --data 'not-json-hash' --silent -X GET https://${DOMAIN}:${PORT}/run | jq      
    {
      "exception": {
        "path": "/run",
        "body": "not-json-hash",
        "class": "SaverService",
        "message": "...",
        "backtrace": [
          ...
          "/usr/bin/rackup:23:in `<main>'"
        ]
      }
    }