Stop Trying To Build Everything From Scratch

How outsourcing one part of an application pushed me to the finish line in five days.

B2B communication is exceptionally inefficient. Sure, we're to the point where it's easy to be "paperless," - but if the exchange of information is still primarily document-based, is that really paperless? Or is it just a different delivery system? We spend so much time just moving papers around, electronic or not. There has to be a better way.

As CTO of an industrial distribution company, it's my job to find ways to utilize technology that improve our efficiency. If a task is repeatable, it can be automated. If it's automated, it takes us less time. Time is money. Time is profit. For wholesale distributors, profitability is what makes or breaks the business.

During a given week, we interact with a few hundred suppliers and constantly exchange information to ensure our systems are up to date with theirs. Since none of our suppliers use one standard ERP or give us access to any open APIs, it's all manual work. It's paying people to sit in chairs and enter data. Not ideal by any means, but I can't go along changing how someone else operates their business, only ours. I decided we needed a more efficient way for our suppliers to access information from us, but it couldn't add any additional tasks for my team. I needed something that "just works."

Design

I decided that giving our suppliers completely transparent access to our system was the solution, but how do we get there? What does that look like? I started by asking myself questions to help identify the bare requirements:

  • What data do we need to display?
  • What functions will be helpful to the end-user?
  • Why would they care?

Okay, we're making progress. Now, how do I do this with code? Writing an API to fetch the data I need from our ERP is easy, but how do I share it securely? I can't have one supplier sniffing the data of another's, so I needed to find a way to authenticate them easily. I don't want to create hundreds of users and give anyone outside of our team direct access to our server, that's a disaster waiting to happen. I just wanted something simple.

I became so clouded by the authentication issue that it limited me from making any progress and set my motivation to complete the project to essentially zero. This is a problem I often face as a software developer. I need to remind myself: I solve problems. Solving a problem requires action. Waiting for a problem to solve itself when it can't isn't action.

I often look at problems as if they are a thunderstorm: it has a lot of roar, but if you sit and wait, eventually the storm passes, and you're left with sunshine and calm winds.

Finally, I humbly came down and pulled myself out of the typical developer hero complex of "I have to build everything from scratch." What a trap, and in my opinion, one of the main reasons why many great ideas end up dead. A lot of people are full of amazing ideas: I'm sure you have tons of them, but where we often fail is the ability to execute. I thought: "Why pull my hair out with designing authentication when there are already solutions out there waiting for me?"

I chose Netlify Identity because it was right there in front of my face every time I log in to their service. After a few minutes of reading through the docs, my motivation meter struck 10 and I began building.

Build

Once I mapped out the general framework in my head, building the app only took a few days. I chose Vue as I already had a bunch of components from other projects I could reuse that were still fresh in my brain. I wrote the new API functions I needed from our ERP, which is built on Frappe Framework. Once the wheels got turning, development was rapid and extremely satisfying. This is why I love building with the JAMStack: simple designs offer fast results.

Netlify Identity brings you a full suite of authentication services with very minimal effort. It's far from perfect, but if you already pay for the Business Plan on Netlify like I do, it's included... so why not go for it? I love the simplicity of accessing the user context to authenticate Netlify Functions or creating workflows for validating a user upon signup. Like this one:

// identity-validate.js
const { default: axios } = require('axios')
require('dotenv').config()

const { BASE_URL, KEY, SECRET } = process.env

exports.handler = async (event) => {
  const body = JSON.parse(event.body)

  try {
    // match user's email with a supplier

    let supplier = await axios({
      method: 'post',

      url: `${BASE_URL}/api/get_supplier`,

      headers: {
        'content-type': 'application/json',

        authorization: `Token ${KEY}:${SECRET}`,
      },

      data: {
        email: body.user.email,
      },
    })

    // stop the validation if supplier is not found, otherwise return a successful response code

    return {
      statusCode: supplier.data.message.error ? 403 : 200,
    }
  } catch (err) {
    return {
      statusCode: err.statusCode || 500,
    }
  }
}

In a few lines of code, the registration process is handled without any manual intervention from my team. That's called a win.

Using gotrue-js (repo), I made a simple auth component that handles registration, login, and password resets all-in-one. Protecting routes with vue-router makes navigation a breeze. All that's left is just getting the data to look nice. In all, I spent less than a week putting together the app, and deploying it on Netlify took all of 5 minutes.

Benefit

It's been two weeks since our soft beta launch, and so far, about 10% of our suppliers have utilized the portal. Based on prior experiences, I expected about zero of them to even click the link, so I'll take 10% all day, and we're just getting started. My team is spending less time tackling issues or replying to suppliers with information they now have available to them 24/7. Suppliers can serve themselves without waiting for another stupid email response. We can spend more time helping our customers and generating sales, which overall improves our profitability. The supplier wins => the customer wins => we all win.