Skip to content

RUP Versioning

Caleb Sharp edited this page Jan 14, 2020 · 1 revision

All RUPs are versioned, implemented as follows:

  • API functions as a normal REST API (so POST requests just create a new record, PUT updates, DELETE updates. These would be updating the "draft" current version
  • Separate endpoint to commit the "draft" changes and give them a new version. It would duplicate all the data into rows with the same canonical IDs.
  • Another table that tracks plan versions. When a new version is committed, a row will be added with an incremented version number and a column that points to the row ID of the duplicated plan. Then if you want to retrieve a specific version of a plan you could look it up in this table and use the row ID of the respective plan. All relations between the plan and its subtables would be kept.
  • A row in the plan_version table with the version column set to -1 is considered to be the current draft version
  • New/changed endpoints
    • POST /api/v1/plan/:id/version: create a new version based off of the current version
  • Consumers of the API shouldn't have to worry about id vs canonical_id; it should be handled transparently by the API. Any "id"s used by the client will actually be the canonical_id, since id is meant for internal use. This means response bodies containing an id field will actually have the value of the canonical_id.
  • Important: CRUD operations should be done by the client before creating a new version.

Creating a new version:

  • there already exists a special 'current version' row in the plan_version table, with a version value of -1. Any POST/PUT/DELETE requests on a plan or its child resources will affect the plan referenced by the plan_id of the current version.
  • When a new version is created the plan referenced by the current version row is duplicated, along with it's related tables. Important: the canonical_id field of each resource is kept the same when duplicated. This allows requests made by a client to point to the "same" resource each time across versions, even though internally the duplicated rows will have different IDs.
  • Then, a new plan_version entry is created with a plan_id that references the original copy of the duplicated plan. The version column should be incremented from the last version.
  • The current version row is modified so that its plan_id references the duplicated copy of the plan.

When retrieving resources:

  • Example: GET /plan/3/plant-community (this endpoint doesn't actually exist, but works as an example of the steps the API would take)
    1. Looks up the plan_version record with version=-1 and canonical_id=3 to get the current version of the plan.
    2. Uses the value of plan_id to find the actual plan record.
    3. Finds the plant communities where plan_id is the same as ID from the version record and returns them to the user.
    • The steps would be very similar to retrieving an old version, except the value for version would be some user-specified value instead of -1.
    • Also similar steps for POST/PUT/DELETE requests, except the API would mutate the resource instead of just returning them. Since the versioning workflow is handled primarily by a separate endpoint, other endpoints can be implemented in almost the same way as they normally would. A function such as getCurrentPlan(canonicalId) could be created to abstract steps 1-2.

When a plan is created:

  • The plan is created as before by inserting a new record in the database
  • The canonical_id of the plan is set to the auto-generated ID provided by postgres (ensures it's unique)
  • A current version record is created for the plan.

When any versioned record is created (other than a plan):

  • Created with a relationship to the plan of the current version
  • canonical_id of the record is set to the ID of the autogenerated ID provided by postgres

Tables that have a canonical_id column, and that need to be duplicated (ie. tables that are versioned):

  • plan
  • pasture
    • plant_community
      • indicator_plant
      • monitoring_area
        • monitoring_area_purpose
      • plant_community_action
  • grazing_schedule
    • grazing_schedule_entry
  • additional_requirement
  • minister_issue
    • minister_issue_action
    • minister_issue_pasture
  • management_consideration
  • invasive_plant_checklist
Clone this wiki locally