Grow Together (2021 remix)

10 January 2022

Hey kids, it’s time for a Coupling yearly round-up, as has now become tradition. Lots of technical changes this year! I’ll list those in a moment, but first, lets talk numbers.

Numbers

We had 994 pair assignments in 2021. This is down from the 1106 we had in 2020, but honestly not as low as I expected. The social network of people using the app has been fluctuating given a large number of people changing jobs, changing places they live, and changing teams, so I was anticipating some disappointing numbers.

So I was pleasantly surprised this morning when use continued to track! In terms of active teams, we had 20 teams that had over ten pair rotations. Ten of them had over 40 spins, and 5 had more than 50! That means long-running teams, using it regularly, and hopefully getting real value from it. I looked a little closer and found many of these teams have been using the app for years now.

I’m truly honored that they continue to find it useful, and will do everything in my power to respect the trust they’ve given to the tool. :heart:

Players-wise, teams that had steady use varied between a low of 4, and a high of 10 players, with multiple teams in that 7-10 range. Kind of stands to reason that if you’re floating a larger team, the tool would be extra useful. Five pairs is a rad size to a team honestly, and if the vibe is good, it can be super fun!

It looks like people are generally using the “pin” feature sparingly, with most teams not using them at all. This is unsurprising - it’s a niche feature by design. It looks like a few teams were making active use of them though, consistently keeping one in play. And there are a few teams that were using them further - one team consistently uses 3 pins, and another consistently uses… drumroll please… seven. SEVEN! I haven’t looked, but I imagine they’ve made them highly entertaining. I’ll note, the teams that use them this much are also power users, so in raw pin count, they boosted the numbers substantially.

Features

This is a side-project for me, and a place to practice and demonstrate technical ideas before recommending them to teams I work on. That said, there were a number of upgrades performed in 2021 that I want to highlight:

User-facing features:

  1. The copy button! In case you haven’t noticed already, there’s a button that allows you to get an image of the pair assignments that you can then paste in your preferred message system. It has variable browser support, and doesn’t work perfectly, but even so, I found it personally extremely useful. Hopefully you will too!
  2. An animated demo! Ok, this feature isn’t actually complete yet… I need to spit-polish it a little more. But I wanted to put together an example of how you use the app, much like the “demo” that plays when you leave yourself on the title screen of Super Mario Bros. If you want a preview of the feature, you can follow this link https://coupling.zegreatrob.com/demo. Send me notes about things that are weird so I can clean em up. Animation is fun!
  3. Autosave! I’m slowly changing the UI to prefer to save first, clean up later. Partly because this way it’s a little safer when dealing with humans who forget to click things and partly because…
  4. Multi-user support has begun! Some of you may have noticed that if you have two instances of Coupling looking at a tribe, and then one of them spins, they both will show the results of the spin immediately. Even more, if someone drags and drops a player from one pair to another, both Couplings will show that update too! Isn’t websocket technology wonderful? I’d still like to add more to this in the future, but that’s a feature I’ve wanted to put in for years and… now it is there.

And, for the real nerdos out there, technical backend features:

  1. All API calls are now GraphQL based - now everything you can do with Coupling, you can also do manually through the GraphQL API. There’s even a playground for it that you can find by clicking the GraphQL logo. Power to the people - if you want to use this to affect your tribe, you absolutely can.
  2. Along the same lines, changed as much GraphQL as possible from being in Kotlin source code to being in GraphQL files. Why? Well, I wanted to make it insanely easy to read and reason about the graph in its native tongue. There’s good editor support, and, darn it, I think it was just a good idea. I did this both for the schema, and also many of the queries that the client application uses.
  3. Changed the deployment model entirely. Coupling used to be deployed on AWS ECS, as one big docker image. Now, the application has been split into two deployments…
  4. The first is an immutable web app. The Coupling client is built and deployed to an S3 bucket, in a directory indicating its version number (for example, https://assets.zegreatrob.com/coupling/1.0.451/assets/favicon.ico). This client has zero configuration.
  5. The second is a graphql webservice and websocket handler on an AWS Lambda. This contains ALL configuration, including a reference to the version of the Coupling client that should be presented. It rewrites the index file from the client to inject (client-safe) configuration information. The websocket bit was the hardest part, of course.
  6. Switching to this deployment style is not only systemically lovely (and it really is), but it’s reduced my AWS bill by 100x. Not an exaggeration. Dynamodb, Lambdas, and S3 buckets are dirt cheap. And performance is essentially unchanged… I’d wager most users didn’t notice that there was a switcheroo.
  7. Started doing all development locally using HTTPS, including in CircleCI build jobs. Caddy is my new best friend.
  8. Switched over to using client-side based auth with a different Auth0 client, and securing the Graph API with Auth0 JWT token validation. The API no longer manages sessions at all. That is lovely.
  9. Removed the test-runtime-only alternate authentication method. That’s a hack that’s been in since the earliest days of Coupling, and it made me very happy to delete it. So clean.
  10. Switched to using the KTOR client. In my secret heart of hearts, I’d love to have a multiplatform safe SDK for Coupling, and this is one step toward that goal.
  11. Made further strides in JSON logging all the things… especially all the test runs. Getting real observability into test runs over time is going to be the next big thing, and I want to be on the cutting edge of making that available.
  12. And finally… I kept pace with all of the major updates in my dependencies. Kotlin had some big updates this year. My auto-update jobs did excellent work to highlight when some new versions of libraries were problematic (AKA would need elbow grease in order to work), and did even better work updating things without needing RoB-intervention. Keeping libraries up to date is something most software teams fail to do, so I’m very proud to have built a system that makes it crazy easy to do, even in my free time.

Ok. That’s enough for this update. But it’s been a year, so you deserved a nice big one. I hope you are all healthy, wealthy, and playing nicely with each other.

That’s the #1 rule of pairing, after all.

  • RoB