Monday, October 1, 2018

The Next Chapter

After getting certified to integrate with Metrc, I built a multi-tenant service which allowed me to explore a variety of issues faced by Cannabis companies.



All of the tools and apps were based on real world problems, gleaned from conversations and interactions with people working in Marijuana businesses. Some of these ended up being useful, and others ended up having limited value. Since the entire endeavor provided an endless stream of challenges and puzzles to solve, it was a huge success.

While I have every intent to continue writing software in my spare time, I want to experiment with new architectures and technologies. Migrating the current server and all of it's functionality is a possibility, but would take a lot of effort and time. Since this is my hobby, and something I do for fun rather than profit, I'd prefer bypassing the heavy lifting and getting right to the fun stuff.

So, I've wound down the service. Everything was written so it can run on-premise, or on a company-specific hosted account. There may still be some maintenance work to do, but I'm trying to find alternative solutions for any businesses still needing functionality.

Again, this does not mean an end to writing software to solve Cannabis related problems. It means the freedom to try something new. I've learned I don't want to run my own company. But I do want to continue solving problems and creating solutions. So, I'm not sure what I'll build next, but as long as it's challenging, I'm up for it!

Thursday, April 26, 2018

CA evaluation completed

I just completed the CA evaluation for Metrc. While I had hoped the third time would be a charm, and things would go smoothly, it was not to be. I probably spent a total of 4 hours getting through this . . . ouch! I’ll share some of the challenges I ran into, if for no other reason, so that I can learn from it.

To find usable tags, you need to parse several files. However, it’s not obvious what licensee type is represented by each file. This has tripped me up before. The solution here is to use facilities/v1/ to list all license numbers and types.

I initially thought there was nothing populated in the db. After all, last year the sandbox was reset, and there wasn’t enough data to be able to do anything. Without any starting inventory, the API can be really hard to use.

But the problem this time is "API Program Bulletin 17". Since you only get back items which have changed in the past 24 hours by default, initially finding inventory via curl calls makes the system seem empty. I suppose that makes it less likely you’ll stomp on someone else’s data.

Trying to do anything with rooms/v1/ resulted in a “401 Unauthorized” error regardless of which
licensee I tried. I ended up emailing metrc to find “they have been working on some problems” related to rooms. Fortunately, I was given a license number that worked. However, this would bite me later!

I temporarily stumbled over “changegrowthphase” vs “changegrowthphases”. This is not the first time I’ve been bit by this, and it's not a big deal. But still, it was a head scratcher until I realized what was wrong.

The next hurdle was discovering one of the Grower accounts had only 4 plant tags left. Of course, I had used this account to set up strains and items. But without tags, I wasn’t going to get much done. This is where the bulk of my time was spent: first in haphazardly guessing which tags were available, and ultimately in some code to automate finding free tags.

Once I could better analyze tag usage, I switched to another grower license which had many tags available. However, I would soon discover this new licensee was affected by the Rooms issue I ran into earlier. So now I had tags, but no rooms. I tried guessing some room names so I could move product around, but ended up having to ask metrc for a list of room names I could use.

I made a mistake (again) in not reading what should be included in each response. I recorded tags and/or ids as I went, but before I could submit, I had to revisit most of the sections to get other information. For example, some sections require name, date or licensee number. It wasn’t difficult to backfill the data, but would have been more efficient had I captured it right off the bat.

At the end of the evaluation, I had a shiny new tool that lets me check a list of Plant or Package tags and see which are already used. While I’ve built this before (at least for Packages), that was before Bulletin 17, when it was possible to get “allPackages” at once. So I’ve rewritten the tool to work with both types of tags, and to check each individually. This should make life easier during the next evaluation . . . which will likely be for Michigan.

Sunday, March 18, 2018

What's the Metrc API good for?

I've been asked repeatedly whether the Metrc API can be used to do various things. It seems reasonable that a "seed to sale" system would provide the ability to track inventory and provide information useful for a number of reporting functions. Unfortunately, I invariably end up being the bearer of bad news.

The Metrc API is a mechanism to report some compliance data to the State. That's it! If you want to use it for anything else, that's your prerogative, but don't be surprised if your project fails. Would you use a screwdriver to drive nails? Cook your Thanksgiving turkey with a bunsen burner? Commute to work on a Big Wheel? You get the idea.

At first glance, you might think the API is poorly designed. Posting data returns a 200, but absolutely nothing else. Fetching data returns only records which have changed in the past 24 hours. The documentation shows a single sample request payload, with no additional information. Terms such as Tag and Label are synonymous, but not interchangeable. Rooms represent an arbitrary area rather than a space which is separated from the rest of the building. And while you can "delete" Items and Strains, you "post" to destroy Plants and Packages.

But if you remember what the API is designed to do, you realize these features are actually benefits. While most API's return at least the identifier of the object created with a "post", this forces your system to hold the response in memory, and then parse it. So, by not returning a payload on success, Metrc is keeping your system light and nimble.

Since you'll need that identifier later, as soon as your "post" completes, you'll need to do a "get" in order to find the new record you've just created. Metrc makes this easier by returning records sorted by "last modified" date, so your record is probably one of the first. Not only does Metrc make it easy to find your new record, by getting the record you can rest assured other threads will now be able to retrieve the record as well. And by limiting the "get" response to only records that have changed in the past 24 hours, your system doesn't have to deal with an abundance of records.

Again, if you decide to use the API for things it was not designed for, you'll end up causing yourself pain. If you want to see all of the Plants or Package a licensee has, you'll need to page through all of the records, again sorted by "last modified" date. Since you only get a 24 hour period for each "get", you'll need to make 30 calls to see anything that's changed in the past month. If the licensee has anything in inventory that hasn't been modified in longer than a month, you'll need to go back farther. If you're trying to get the inventory of a licensee who's been in business for a year, you'll need to make 365 calls, or risk not getting all the relevant data.

The documentation indicates you get records back based on the last modified date. However, there's no information about defaults or what happens if you provide incorrect values. But that's why vendors must be certified! Anyone authorized to use the API must go through training, so the documentation can be more of a "refresher" rather than a "how to" helper. The training also makes things like inconsistent naming, nonintuitive concepts and oddly assembled endpoints a non-issue.

As long as you use the Metrc API for what it's intended to provide, and only what it's intended to provide, you'll be a happy camper. You can think of the Metrc API as a one way door where data goes in. However, once it's in there, don't expect or try to get it back out. You've been warned.