I wanted to open this thread to test the waters for a couple of (I feel) key improvements to the core farmOS datamodel that should be considered for a version 3 (or 4?) of farmOS.
Make quantities immutable and enforce that a single quantity is referenced by at most one log.
Rational: This makes changes to quantities more atomic and guarantees that the log’s changed timestamp is always updated when one or more of its quantities are changed.
Soft Entity Deletion
Make entity deletion an admin only action and provide a soft-delete (a.k.a. tombstone) mechanism for regular users (farm_manager, farm_worker). The logical choice here seems to be introducing deleted as a new status value - in addition to active and archived. (I’m open to other ideas - such as a dedicated boolean field too.)
Rational: This makes it easier for API clients to determine why an entity no longer “exists” - i.e. replication issue, database rollback, actual deletion, etc. It also makes data-loss easier to avoid in the case of a rogue user - i.e. rather than needing to get the data from a recent backup, it just becomes a matter of rolling the entity/entities back to an earlier - not “deleted” - revision.
On a recent call I remember we talked about maybe having a more formal proposal mechanism - like PEP. “farmOS Enhancement Proposals” (FEP) anyone ?
I’d be happy to pilot such a mechanism if there’s interest… regardless of that I’d welcome any/all feedback on the above proposals.
Curious to understand how this helps with complexity… removing ERR would be nice, but do we create something more complex in its place? Right now to modify a quantity you must update the log.quantityrevision_id after modifying the quantity entity. With this proposal you would need to create a new quantity as a “copy” of the “old” quantity with intended changes, remove the old quantity from the log.quantity field, and add the new quantity to log.quantity. Does that sound right?
I was only referring to the extra “API surface complexity” that the ERR module adds by requiring the revision ID be specified in addition to the entity ID. That is an outlier in terms of the rest of our data model. Only requiring the entity ID would bring it in line with everything else, but there’s a lot more complexity added in other code to enforce immutability I agree. Whether or not that’s justified is up for discussion.
Quick note for future reference/detail: @paul121 and I were discussing in chat about some boilerplate PHP methods on the Asset/Log/(others?) entity type classes like getName() and getOwner() that might be worth deprecating in 2.x and removing in 3.x. They were created initially because it’s standard practice in custom Drupal entity types, but they aren’t really necessary and aren’t really justified - we could reduce the API surface a bit by removing them. Plus the getOwner() field is misleading… it returns the uid of the entity, not the owner field values that we add via the farm_owner module.
I suggest that if something is not removed from the database, it should not be called “deleted” - brainstorming around alternatives:
In my humble opinion, being new to FarmOS but having a long stance as a farmer trying to go digital, I have to say that a farm manager or dedicated farm worker would like to see a button labeled [delete] associated to such user function.
Farmers are radical in regard to the hard facts of life. For example, when they hung a sheep for eating, they have “killed” the sheep, not “archived” it. Therefore, they would like to press a button labeled [dead] [killed] [shot] or, close enough, [deleted], reserving [archived] for when declaring they have put its carcass in the freezer only
Beyond joke, archived signifies to me that the thing is still there, somewhere. When a farm manager or diligent farm worker erases an asset because the flood took it away or because it was a mistake entry all together, they want to press the sure [delete] button.
For programmers, the action behind the label could be called soft delete, archived, or whatever the committee votes the best option. But I propose the UI label should be hard and clear of doubts —for it was done and recorded as such.
I’m a Beef farmer and i disagree with a lot of that.
I don’t think animals sold or slaughtered should be considered deleted, there are a few reasons why an animal needs to remain in an achieved state, such as:
Compliance, records such as drugs given to the animal post termination needed for Inspectors.
Lineage, animals used in breeding still have relationships with animals still on farm.
Profit monitoring, weights prices for animals sold remain important.
Perhaps better language could be used for a UI button to Archive, but I believe the current mechanism is universal to all Asset types, so slaughter/kill might not make sense to a Tillage/veg farmers assets. Also slaughter is not always the right answer for a Livestock farmer either, it could be Slaughtered / Sold / Dropped Dead or even only temporarily archived in the case of Contract Rearing or simply an animal sold and bought back in future.
There is currently a delete Asset option (which can remove an Asset created in error)
Archive Asset is different and better describes an Asset that did exist but is no longer on farm.
Personally I think there is room for a few additional Log types, including Animal Death, and Animal Sales, and Animal Purchases and I have added these to my own self hosted instance through a custom module. Also @wotnak has made a nice termination module which can be used to make logs terminating (ie logs can archive the asset when they are created)
I agree 100% with what you said above (I am learning here)
I am interested in the custom module you developed for your self hosted beef farm instance. Perhaps there is room for same-industry farmers to collaborate in building modules such as yours, specific for a particular industry.
Always happy to share and/or collaborate, not an expert myself but getting to grips with the ins and outs thanks to the help I have received here.
Not much development needed to create new log types, Its a cut paste and minor modification of existing types. If you are self hosting your own farmOS instance make sure to have a separate Dev instance for experimenting with before commiting anything to your production instance.
Feel free to start a new topic to discuss what you’d like to achieve or just add to any relevant threads already started.