Wrap Up on the Contextual Guidance API
Given all the background thought I've done on the contextual guidance API, it was a breeze to implement. Planning before coding really does pay off!
The table I'm using to store the data for the tool looks like this:

As you can see, I've simplified things and haven't gone the route of more advanced, multivariate analysis on usage patterns for a users within an application. I certainly could have, but given that determining a user's experience level with an application is an act of generalization and not a precise science, this seemed right. Or maybe I'm lazy, or like things simple, or both.
In addition to a totalVisits value, I'm storing two date values per user, per application, per section of the application (if that's passed). This allows me to place some context on the user's activity within the application. Instead of just saying "oh, well, they haven't visited this application in 30 days, they should be given the beginner materials again," I can instead say "Well if they haven't visited in more than 30 days, but less than 90, and their total visits were greater than 50, give them the intermediate materials because they probably remember some of what's going on here." Again, in an ideal setup, I should look at not only the number of visits (or visits per section), but average visits over periods of time, the length of breaks between visits, and the exact actions they took within the application to provide them with highly specific contextual guidance. I think that for my users and my applications, being able to look at their activity within sections of a complex application given a rudimentary temporal context will be just fine. If anything, this simpler version of the logic will result in a more consistent display of help/guidance as the user moves from beginner to intermediate user to expert. When you try to get super-specific about guessing what a user is trying to do and provide help each step of the way, you are in danger of ending up with Clippy.
There will be one more related post about the API. It has to do with the magic of upserts and how I thought moving some business logic in to the query itself would save me code, but may not have.

