Happy New Year! I bet no one who’s followed this blog before expected another post so soon. Well, I promised I’d stay in touch, and here I am. Coming up: the power of connections, and my first real job. Let’s dive in.

Background

It was 5 minutes before my business administration class on some Monday in November. I got a call from a friend, Adrian Casares. He came up a lot in my last post- he’s been one of my closest friends over the past few years, and we’ve worked on large projects together (see: Scorecard). While we had both worked on that extension together, he also had his own Chrome Extension: Canvas+. In fact, it had garnered over 50,000 users. However, that was nothing compared to the 2 million a fellow Canvas extension, BetterCampus, had.

Well, turns out the folks behind BetterCampus had contacted him looking for young talent to help them get out a big update by the new year. Adrian has other things going on, but he gave me first dibs to be recommended to them. I talked to Jake (the BetterCampus CEO), did a little interviewing, and haggled a contract. But I was still left with a decision: this was my first major commitment (legally, in fact), and requires some sacrifice of free time. Also, taxes >:(. But I couldn’t pass up this opportunity—within a week I signed on as a Software Engineering Consultant.

Odd Jobs

In the beginning, I wasn’t quite sure how much time I’d be able to commit. How excited I’d be to work, how difficult the work would be, nothing at all. I spent the first few days just familiarizing myself with the toolchains and existing codebase. I had two things going for me: incredible response times from Jake and George over Discord, and a very well managed project todo board.

So I started with random odds and ends. Tasks that didn’t sound too big, but took me across the codebase’s repos from small UI fixes that no one had gotten around to yet, to logical bugs too small for one of the main devs to look at, but annoying to those who encountered it, and eventually to reworking the visuals of core sections of the app. This was a symbiotic process; I got familiar while not being overloaded all at once, and I helped clean up various tasks, while feeling good about contributing something and getting tangible things done.

That culminated in my largest odd job; making the BetterCampus sidebar use the user’s school colors. The default Canvas sidebar has a background color set by the school. One of BetterCampus’ issues was that users felt the new sidebar was too different too fast, and didn’t want to use it. So, we wanted to make it feel more like the default and use that color. Well, this required looking into how the CSS was managed, looking at dark mode injections, stateful CSS, understanding how Canvas uses CSS variables, etc. While not super technically challenging, it certainly helped showcase how much I had learned about the codebase in my short time there.

It was tricky. Not everything was well defined, and I had to make decisions about how to implement things (obviously light mode should have the default colors, but how do we make a dynamic dark mode?). I didn’t want to just be a code monkey; I was a user of the extension, and a dev with years of experience building products. They hired me for my mind, not my ability to type. That said, I was still new to the ecosystem, and had less specialized experience than those already here. So, I used my experience to bring forward a few options for implementation, learned how to synthesize the pros and cons, and brought them to Jake & George for consideration.

Ultimately, I’m quite proud of that small little tweak I implemented; it makes the extension feel so much better in such a small way. And once it goes into production, every time I see it, I’ll know that I contributed that. But soon enough, the odd jobs came to an end as they assigned me to a real project.

Insights

This was a full-stack initiative to bring analytics to users about their time spent on Canvas. From a business perspective, it’s crucial to get this startup off the ground. I had found myself working on the very core of what BetterCampus is soon to be. Well, there’s ~two (sometimes three) halves to any full-stack project: frontend and backend. While I’m proficient in both, I’m certainly quicker, and prefer, backend work. Thankfully, there was plenty of work to go around, and they were happy to accommodate my preference. This was a whole new side to the codebase I had yet to touch much, and what’s more, I was building something from the ground up. No more tinkering with existing code—I was on my own.

As with any major project, I took it piecemeal. There’s three steps to collecting and storing analytics (the displaying part is the frontend I wasn’t touching): collecting and storing as you might expect, as well as accessing- providing the routes through which the theoretical frontend would get the data. Well before knowing how to store the data, I first had to know what the data exactly was. I started with collection.

Without getting into the specifics (NDA and all), this required deepening my understanding of web extension hooks and creative problem solving to find the most efficient way to collect each piece of data. Jake provided me with a list of metrics he’d like to display, which I boiled down into a list of analytics from which those metrics could be derived: time, submissions, stuff like that. Along with that meant learning about how Canvas stores data, and using their GraphQL database access API to grab some of it. It’s always safer to use data from a database, rather than trying to scrape it manually.

Ok. I had scripts that injected when the right pages loaded and grabbed the stats we needed. But wait! Before moving on, there is an extremely important step. Analytics are challenging to test in a development environment; there are lots of edge cases that can’t be seen, and authentic data is hard to get. However, this data was going to be crucial to the business model, and it needed to be accurate. So writing each script, I tested it as thoroughly as possible. This is called white-box testing: if every small component works with 100% accuracy, theoretically, the entire system should be accurate as well.

Alright now we’re ready to move on! Storage. Now initially you may think this would be solely on BetterCampus’ servers. But wait! There’s a wrinkle. See, we’re not legally allowed to retain data until the user opts in. So before getting into any SQL chicanery, we must first deal with local storage in JSON. Alright, so the system is in place; every few hours it tries to upload to the server, if that fails, it stores the record locally then tries again next time (with all the previous records that were missed as well). That way, we can never miss data. If it’s ever unsuccessfully uploaded, it’s stored locally.

Finally, the true backend begins. We’re working with a lot of data here, so SQL is the data storage of choice. I have some experience, but had to shake off the cobwebs. With a little help from George on writing in line with existing code, I got to work. This required constant adjustment and tinkering as we realized that we needed to store this data or that. Fortunately, once I got a hang of it, it wasn’t a very complex process, thanks to the tools they already had set up. The final step was designing and implementing the API endpoints used to upload and request the data.

This wasn’t a complex process per-say, but just like collection, every endpoint required constant testing and validation to ensure every little piece of the puzzle fit together just right. We added safeties to comply with data protection laws of aggregate data, and tried to predict what we’d need in the future. I tried to make it as flexible as possible because I almost certainly wouldn’t be there anymore when it was put to use. The final step, never acknowledged but almost as important as the rest altogether? Documentation.

Documentation is what separates a mere project for oneself from a live codebase maintained by dozens of hands. I had to build code that would stand the test of time, and not require careful inspection to use. So, I wrote up detailed documentation of each API endpoint, the exact data collected, precisely how the database was structured. No developer looks forward to this part, but it is somewhat satisfying to tally up the work you’ve done. And with that, Insights was completed.

Wrap-up

Well, I didn’t really expect to get as into this product as I did, and I certainly didn’t expect to give it a couple of six-hour days. But it was so much fun, and so so rewarding to work on a real product. I decided to let my contract come to a close on 1/5, as was the default with no extension. Not because I didn’t like the work, but moreso to devote my time elsewhere for this upcoming semester. I really do believe in their vision and product, and am so grateful for the opportunity to dip my toes into the fast-paced world of a tech startup in which the oldest contributor was 25.

I can’t wait to see my work put up, and hopefully any students reading this download the extension and find some use out of it. I certainly have. This experience has only solidified my conviction to develop the digital tools this world so desperately needs and deepened my excitement to work in the real world (not that I haven’t produced impact projects before, but not to millions… yet). Hopefully BetterCampus and I will cross paths again in the future. They’re a great team.

As for me, I have much on the horizon (as always). I’ve recently started developing a new videogame for Dusk Blossom Games (because why not), am settling into a new semester of college (this time, with more balance! …I hope), and am looking forward to a 12-week internship at Cloudflare this summer (who let that happen?? still feels unreal). And of course, politics always looms in my mind. I’m entirely confident that I’ll have some more adventures to report in a few months. If you liked this, toss your email in below. Or don’t. Doesn’t really matter to me.