2017-02-21 Meeting notes

Date

7am PST

https://www.uberconference.com/villagereach-isg

Optional dial in:
Dial in: 213-493-0531
PIN: 74762

Attendees

Goals

  • Dev forum topics:
    • (tick) Discuss DELETE as archive example
    • stock management design
    • pagination
    • versioning

Discussion items

TimeItemWhoNotes
5mReview agenda / startJosh
 55mDiscuss archive for deleteJosh inline below in example

Delete as Archive example


A HTTP DELETE operation could be utilized as an archive operation.  Or rather, since DELETE is idempotent, the DELETE operation shouldn't be used, and instead for most Reference Data entities, the more relevant business and technical operation is to archive them.


How this works:

  • DELETE operations shouldn't be allowed
  • Resources should support archiving/de-activating them.  Resources such as /api/facilities/{id} do this via facility start/stop dates, or program supported active dates.  /api/users/{id} does this via the field active.
  • Resource search endpoints would by default return only non-archived items.  Consequently there would need to be special search endpoints or query parameters to find archived items (edge case).
    • NOTE:  schedule or period search or products endpoints MAY use search to get a specific resource.  i.e. we should check that we don't use the search endpoint internally to the service to find a specific resource because with this default convention we may not find what we're looking for and therefore a GET/PUT/POST would return a 404.  We should check these search endpoints for what they do when they look for a specific resource when we implement the archive operation for that resource.
  • Consumers of resources would have to understand that the resource may become archived.


Simple example with an Orderable:


An Orderable in OpenLMIS is an abstract representation of something that may be ordered, inventoried, etc.  A key component of Orderables, is that while the Orderable may represent a CommodityType or a TradeItem, it has a implementation unique Product Code - one that is often printed on paper forms at rural health facilities.


Suppose that the resource /api/orderables/4 was Product Code P040 which was the CommodityType Malaria Prophylaxis in the UNSPSC classification system:


DELETE:

  • DELETE /api/orderables/4
  • further calls to GET /api/orderables/4 returns a 404 Not Found - client services and/or systems would be left with no other detail than what would be found in the Audit Log
  • A client could create a wholly new Orderable, with Product Code P040, for the Trade Item Advil Extra Strength
  • Historical paper forms which might list P040, could inadvertently be used to request/inventory Advil Extra Strength when the intention was to request/inventory Malaria Prophylaxis.


Archiving:

  • A normal PUT/POST /api/orderables/4 could update the client-aware feature of archiving that particular resource - i.e. a simple boolean field (archived/non-archived), a date range for being active, something more complex like multiple date ranges.  This domain knowledge is specific to the Resource.
  • further calls to GET /api/orderables/4 would never return a 404 - client services and/or systems would not be left hanging.
  • A client creating a new Orderable with product code P040 would get an error message - P040 has already been used and may never mean anything different


Deleting Reference Data is a particularly bad idea - not only will referential integrity within Reference Data often prevent it, but cross-service or even cross-system references can break silently and expensively.  Away from Reference Data, many Resources, such as Stock Card line items, simply can't be deleted for principles of accountability.


NOTE on deleteing a Requisition in v2:  v2 deleted an initiated Requisition when something like the Req. Template or approved products changed.  The goal was to remove Requisitions that we're recently created using essentially an outdated set of information.  e.g.  the template changed, so don't fill in that new Requisition rural health clinic, you have the old template.  Another addition was a DB-level constraint for ensuring that a Requisition was unique by Facility, Program, Period, etc.  If an "archived" flag were added, that constraint would have to expand to understand that archived flag.

Josh's proposal:  in v3 we should be following our more domain-oriented design, and encapsulating that knowledge of how/when a domain object is archived within the domain class and have that reflected in the Repositories operations.  In the above the domain class would have the knowledge on how/when to archive and its repository would provide for search operations and enforce uniqueness rules.  Uniqueness rules can be aided by JPA annotations such as @Table, custom repository implementations or perhaps less favorably by @PrePersist type annotations.


Action items

  •  

OpenLMIS: the global initiative for powerful LMIS software