Skip to content

Instantly share code, notes, and snippets.

@ptpaterson
Created September 27, 2017 03:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ptpaterson/6f573d2aa01fc9e028194c457374b646 to your computer and use it in GitHub Desktop.
Save ptpaterson/6f573d2aa01fc9e028194c457374b646 to your computer and use it in GitHub Desktop.

TLDR:

  • Big problem
  • Need arbitrary data linked to arbitrary data
  • Need to bootstrap auth, permissions, integrations
  • Problem well defined with real-life use cases, but solution not set in stone. Base assumptions need challenged

I only after initially posting discovered that Amazon Aurora is sitting on the back-end, which means relational tables. The implementation that I am working on has been focusing on some tricks that No-SQL makes easy.

What I basically need, but am avoiding with No-SQL, is the entity–attribute–value model. I have a big collection of "items" which will all have some basic information, but each item may contain a mish-mash of other arbitrary data. And this data is (sometimes) hierarchical... it's a mess, and I beginning to wonder if a baas is ever going to work for me, but let's go through the exercise... (On that topic, I'd love to talk more with others about my particular problem... anyway)

My application wants to provide a lot of user customization in an unopinionated way - the root of my mess.

Consider a portal where customers, sales reps, service tech's, machine operators, engineers, et al. can submit a variety of issues, and/or track corrective actions. The user of the portal wishes to reference an arbitrary amount of information of an unknowable type nature. The app can guide them through picking, but the database needs to handle storage of the random nature of the submission. Until now, I have completely avoided how to address this in relational tables. Here is what some data might end up like:

{
  "items": [
    {
      "_id": "GUID of Issue 1",
      "itemNumber": "BizID of Issue 1",
      "issueType": "Design Error",
      "issueDescription": "Part A is totally impossible to fabricate!",
      "action": "Revise Part A",
      "issueReferences": [
        { "_id": "GUID of Work Order A", "note": "How it was released" },
        { "_id": "GUID of Part B", "note": "part that was designed wrong" },
        { "_id": "GUID of Assembly C", "note": "Assembly that couldn't be put together" },
        { "_id": "GUID of Employee D", "note": "Person responsible for terrible design" }
      ]
    },
    {
      "_id": "GUID of Issue 2",
      "itemNumber": "BizID of Issue 2",
      "issueType": "Customer Complaint",
      "issueDescription": "Screen goes blank when I unplug it.  This is the SECOND TIME!",
      "action": "Train customer not to unplug it... again",
      "itemReferences": [
        { "_id": "GUID of Customer E", "note": "Who had the problem" },
        { "_id": "GUID of Issue F", "note": "previous related issue" },
        { "_id": "GUID of Employee G", "note": "Technician sent to conduct training" }
      ]
    }
  ]
}

An assembly like Assembly C, above, needs links to it's children, such as Part B. Parts needs to know which assemblies and drawings in which it is used. Sometime a part may need to be fabricated in house. Sometimes a part can be purchase and we need to know the vendor information - sometimes either fabricate or purchase is an option. All Items need to know what issues they are referenced in. Users might want to know the list of tasks that are assigned to them, or what training they have had, or what training they are signed up for!

For any individual issue document, it looks like it could make sense to define a finite set of types. However, I have A LOT of examples in front of me where trying to capture all of the possibilities just doesn't make sense. Either:

  1. Configuration is too tedious and time consuming, so you settle for a simple config, become dissatisfied, complain a lot, and move on to a different product (or just complain for forever).
  2. Many hours are spent on configuring all of the special cases. Now we have dozens of options to choose from and it's hard to tell the difference from one to other, so you just pick one that looks right, but it's not, your data becomes crap, and you complain a lot, and move on to a different product (or stay and bad-mouth the product all over town)

Main value prop is quick, intuitive, flexible, living configurations, so these are non-starters...

and so on... It's not a small problem.

With vanilla Mongo and GraphQL, I can create an Item and use mutations to compose a more complex object that implements a number of interfaces. The client should then be able to query a list of generic Item links, determine the type or types of the object, and send new queries with the right fragments for the interfaces - a bit of a graphql anti-pattern to send multiple queries, but if the server can catch the previous db call, then it still at least has the field values ready to send.

I've got the problem decently well defined, but there's a lot to bootstrap up here with auth and permissions and integrations...

SO! Anyway you see this happening in Graph.Cool? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment