now that this has been in use for a few months, generally feeling good
about it. this refactors to use some more concrete types (note using
TypedDict generally because most of this is uncontrolled input from
third-party json). otherwise this should not change anything regarding
functionality, just implementation.