Obs.status, updating automatically?

I’m adding obs.status as part of TRUNK-4976. The quick summary is that it allows us to represent if an obs’s value is:

  • PRELIMINARY - This is an initial or interim observation: data may be incomplete or unverified.
  • FINAL - The observation is complete.
  • AMENDED - Subsequent to being Final, the observation has been modified subsequent. This includes updates/new information and corrections.

I’m about to implement code such that when you modify an obs whose status is final (which triggers a void-and-create-new), the new obs will automatically have status=amended and you cannot easily bypass this.

Thoughts? Does anyone thinks the API should make it easy for you to edit a final obs without changing its status?

In practice what this means is that these calls will result in a new obs with status=amended [edited: originally a typo said final]

Obs existing = service.getObs(123); // given this has final status
existing.setValueNumeric(70);
Obs amended = service.saveObs(existing, "changing the value");

POST .../obs/uuid_of_existing_obs_with_final_status
{ "valueNumeric": 70 }

Further, this does not do what you expect:

Obs existing = service.getObs(123); // given this has final status
existing.setValueNumeric(70);
existing.setStatus(Obs.Status.FINAL);
Obs amended = service.saveObs(existing, "changing the value");
// returned value has status of AMENDED

POST .../obs/uuid_of_existing_obs_with_final_status
{ "valueNumeric": 70, "status": "FINAL" }
// newly-created obs has status of AMENDED

If you really want to bypass this, you’d still be able to do one of these:

Obs existing = service.getObs(123); // given this has final status
Obs newObs = existing.newInstance();
newObs.setPreviousVersion(existing);
newObs.setValueNumeric(70);
newObs.setStatus(Obs.Status.FINAL);
service.saveObs(newObs);
service.voidObs(existing);

POST .../obs
{
  "valueNumeric": 70,
  "status": "FINAL",
  "previousVersion": "uuid_of_existing_obs_with_final_status"
  // and all the rest of the fields
}

Any objections?

At first glance, allowing you to bypass this behavior would require a bunch of hacky code under the hood, and I see zero reason to do that.

PS- @wyclif, as a tangent, I think that:

  • the javadoc on ObsService.saveObs is wrong
  • ObsServiceTest.saveObs_shouldAllowChangingOfEveryPropertyOnObs() is no longer testing what its name says (and the @should annotation is misleading)

I guess these were never updated after we changed the API to make it automatically do a void-and-create-new when you try to modify an obs.

If you can confirm that these are wrong, I’ll go ahead and fix them.

By the way, this proposed behavior is included in the 2.1.0-beta release I did yesterday.

I think I agree, but I’m a bit confused by this part:

I thought editing an obs with status=FINAL would result in an obs with status=AMENDED. Was that a typo in your post? Or am I missing something?

I was hoping that the API wouldn’t blindly force status=AMENDED if the status itself was changed. This is less important while we only support PRELIMINARY, FINAL, and AMENDED statuses. Assuming we support status=CANCELLED in the future, we’d probably want revising a status from FINAL to CANCELLED to result in status=CANCELLED instead of becoming status=AMENDED.

Oops, yes, that was a typo. Those calls do result in an obs with status=AMENDED.

It’s straightforward to make the logic recognize changes (e.g. recognize they’re changing from FINAL to CANCELLED), and we can do this in the future. What would be a pain, given our current code, is noticing if they’re actively trying to keep it the same (e.g. track that the user explicitly called setStatus(FINAL) vs the just being done by Hibernate).

Yes, the javadocs for saveObs seem a little off