# Engineering@Stord
Engineering insights, practices, and culture from the team building Stord's Cloud Supply Chain platform.
# Blog
# Example
This is an example page.
```elixir
@doc """
Syntax highlighting works for elixir, woo.
"""
@spec test_fn(String.t()) :: String.t()
def test_fn(word) do
%{
key: word
}
|> Map.get(:key)
|> Kernel.to_string()
end
```
```ts twoslash
type Fruit = "🍎" | "🍌";
let fruit: Fruit = "🍌";
if (true) {
fruit = "🍎";
}
const result = fruit;
// ^?
```
# Talks
Stord engineers sharing what we've learned with the broader community.
***
## Elixir's Configuration Layers: A Visual Journey
**Stephanie Lane** · ElixirConf US 2025
A visual walkthrough of how Elixir's layered configuration system works — from compile-time to runtime — and the mental models that make it click.
***
## Seizing the Means of Computation with Local AI
**Jeremy Kahn** · [GOTO Accelerate Chicago 2026](https://gotochgo.com/accelerate-chicago-2026/sessions/4041/seizing-the-means-of-computation-with-local-ai) · June 23, 2026
Running open-source AI models on your own hardware is no longer a hobbyist curiosity — it's a practical alternative to cloud APIs. This talk covers how to get started with local AI using free software tools, ditching API bills, rate limits, and data-privacy concerns in the process.
*Video coming soon.*
# API First Design - It's working!
::authors
## What does it mean
API first design is the approach of looking at the coarse-grained business transactions that need to happen on your business entities, which can happen from a user interface or from direct service-to-service integrations, and designing your API contracts to meet this diverse set of business needs.
## What are the benefits
We didn't necessarily start out saying we were going to do API first design, but we quickly came to realize how it empowers us to support robust integrations and user interfaces.
When building one of the first end-to-end Cloud Supply Chains, you need to be flexible when it comes to system integrations, because the real-world processes vary greatly when you are a company that sells beds compared to a company that sells hand-sanitizers. In addition, it is paramount that our Customers have real-time visibility across their supply chain, so the user interface is also an important stakeholder in our design.
Using an API first design has allowed both our UI and our Integration layer to co-exist and benefit from one another.
## Tools we use
Some of the key tools we use for our API design
* For the API design, mocking, examples, and document we use [Postman](https://www.postman.com/?ref=stord.engineering)
* We leverage the RESTful style in our API design
* To avoid [bikeshedding](http://bikeshed.com/?ref=stord.engineering), we leverage the [JSON:API specification](https://jsonapi.org/?ref=stord.engineering) to structure our request and response objects.
* We use [Open API](https://swagger.io/specification/?ref=stord.engineering) to annotate our APIs so that we can quickly generate clients and use the generated client code when running API and component tests

We use Postman for our API design and documentation
## So what, who cares?
[T](https://www.stord.engineering/publishing-options/)o be honest, we didn't at first. As I mentioned before, we didn't start out saying we were going to do an API first design. But the more we began to reap the benefits, whereby the UI and the Integration layer were leveraging the same APIs, the more we realized we need to make this our de facto practice. And now it is!
# Top 3 Youtube videos to learn about STORD
::authors
Noticing a trend in the candidates that I've spoke with recently, I wanted to put together this quick post of recommended YouTube videos. The past three out of four candidates have told me that they got a lot of value out of watching some of our Youtube videos. After I heard this a third time, I asked what were their favorites when trying to learn more about STORD, and compiled this list for you.
Fastest overview of STORD's solutions to the supply chain problems
The above video was updated from the [STORD overview in 2020](https://www.youtube.com/watch?v=amgT05ngKe4\&ref=stord.engineering)
What does Omnichannel mean?
And if you just want to see why our CEO, Sean Henry, inspires us on a regular basis, then check out his TedxEmory talk
# How do you point stories?
::authors
Wonder how we point stories? Well wonder no more! This article talks about how we point stories at STORD...and also covers the WHY
# Why point stories?
Good question! We want to provide point estimates instead of time estimates (even though points are a proxy for duration, bear with me here) because humans are bad at estimating but good at relative sizing.
If you put 100 dogs in a room, then asked 5 different people to sort them into buckets of extra small, small, medium, large, and extra large -- you'd likely get about the same groupings for each person.
That's because people are good at relative sizing, which is why we use the Fibonacci sequence. The difference between a 1 and a 2 is clear, and a 2 and 3...but a 3 and a 4? So the next sequence is 5. A difference between a 3 and a 5 is clear. The next sequence is 8. A difference between 3, 5 and 8 is clear when you compare sizes of things.
If you spend so much time estimating, then you'll have wasted time that could be spent actually doing the work, and the estimates will likely be wrong anyway (because humans are bad at estimating, but good at relative sizing).
Here's a list of benefits for pointing work that will deliver value:
* Allows us to set *attainable* goals, and strive to accomplish them
* Helps set expectations for how many sprints it might take for a team to accomplish an epic of work. This helps with planning -- the product and UX team know when they need to focus on getting the next epics and stories ready
* Let's the team establish a velocity based on a level of consistency when understanding the work to be done to deliver against the value of the story (it typically takes a new team a few sprints to establish)
* The team can get aligned on what it will take to get something 'done' by agreeing on the points to complete it.
* It can uncover risks or issues when estimates are higher than expected -- and uncovering such things early on is a good thing!!
Here what points are NOT:
* a time estimate that team must hit
## How do you story point?
Because story points represent the relative size of effort to complete a story, a team's estimate must include everything that can affect the effort. That could include:
* The amount of work to do
* The complexity of the work
* Any risk or uncertainty in doing the work
When estimating with story points, be sure to consider each of these factors.
Here's an example using a simple HTML form.
* You have story that requires building a form with 10 fields, and they are all text inputs -- this is a pretty easy effort, no complexity to speak of, and low risk
* Now take that same 10 field form, but instead of all text field inputs, now the form has a file-upload widget, a slider, some checkboxes, a text area, radio boxes, and textfields. Okay, so now the complexity has gone up and there is likely some risk in how these fields will interact.
* Let's go back to the same simple form with all text field inputs, but now we have 100 fields! The complexity didn't change, there could be some risk with the browser even rendering that many fields, and the level of effort surely went up to deal with 100 fields instead of 10.
That's why a story's SIZE should be determined by its:
1. Level of effort
2. Complexity
3. Uncertainty/Risk
Remember the earlier example where we were sorting all the dogs in a room?...think of size in that literal way, like the size of the dogs. When the team points a story of 3 points...and then another story that's 3 points. Would say they are the same size? Try to think of the comparison in these physical terms.
Hope that clears up how STORD does story points
# Updated: Our Path to Continuous Delivery
::authors
The concept seems so simple at first. You write some code, make sure it passes tests locally and when integrated with the rest of the codebase, then deploy it to staging, make sure the tests pass in staging, and then deploy it to production (also testing the code is working in production too). Then repeat. Easy peasy, lemon squeezy, right?
## Not so simple
To really do continuous delivery, at its core, you need...
continuous integration and continuous deployment pipelines
a full suite of tests that you trust – you trust that if the tests all pass in lower environments, then you are ready to push the code to production
like minded people that want to focus more time on value delivery and less time on toil
Sounds easy, but anyone that's needed to set this up from scratch at your company knows it is far from easy. But it's often our most challenging accomplishments – the ones where the we had to overcome very difficult obstacles – that fill us with the most pride. I'm excited to say that we accomplish full continuous delivery at STORD, and I was beaming with pride when we did it!
What we've done, and what we have left to do
We started building the second version of our platform in January 2020. We took the learnings from our flag-ship MVP application, that was a monolith, and started building out our next generation application using microservices. I bring this up because testing is a key element toward continuous delivery. Testing gets harder and harder the more responsibilities an application has, so microservices –done right– can help out a lot here because you can keep your services focused and therefore easier to cover their responsibilities with tests.
A complex system is made up of simple working parts, so at the end of the day our microservices need to come together to create our Cloud Supply Chain, which is a complex system. Therefore, we need suites and layers of testing in order to reach the level of confidence in our testing such that we can trust our deployments to go straight to production.
At STORD, we have a good set of unit and integration tests – for both our backend and front-end applications. These quick running tests run within our continuous integration tool (Circle CI).
The next layer of tests we have are Controller tests. Controller tests allow us to test a service in isolation, and mock out any external calls. The mocking can be done with Elixir, and so we can run these controller tests in a similar way that we do Integration tests.
After that, we need have end-to-end tests, which can cross the boundaries of many services. These end-to-end tests can be driven through API calls or through the UI. We use Cypress for creating and running our end-to-end tests.
Since STORD uses Docker containers and Kubernetes (GKE on Google Cloud Platform), we also have probe tests ...startup probes to test the configuration is correct, and readiness and liveliness probes to ensure the container is ready to serve and remains ready to serve within its cluster.
With all these test suites working in concert, we can build the same level of confidence, if not more so, as when a person does a manual set of deployments and tests themselves throughout multiple environments.
The next layer of testing that we want to add is Contract tests. A way to know that your consumers of your API are not impacted by any changes to the service backing the API. If so, then maybe you need to create a new version or refactor your changes so that your changes can be backwards compatible.
Figure 1 below is a picture of STORD's vision to achieve full continuous delivery. You'll notice that the code is going through the same steps it would as if an human is moving the code from their desktop, up through the various environments, and out to production. Just replace what you do today with automation – same environments, same deployments, and same testing. We have the technology, I assure you that this can be done!
## Separating a Deployment from a Release
Separating a deployment from a release is a key milestone in achieving Continuous Delivery. We do this using our Feature Flags tool (LaunchDarkly)
Feature flags allow us to practice trunk-based development, and avoid branch merging hell. But it also allows us to do deployments during the day, when the team is around to support the deployment if something goes wrong, instead of late nights and weekends. And since deployments are separate from releases, just because the deployment had issues, doesn't mean the customers are experiencing any issues on the currently release that they are using.
## We did it!
It took us a few quarters to get there, but we finally implemented our full vision for continuous delivery.
## Ready to help us build a Cloud Supply Chain?
We have a great team and we are making great strides. We are also experiencing triple digit, year-over-year growth due the acceleration of ecommerce by COVID. Having a Cloud Supply Chain gives companies key business capabilities – speed, flexibility, and cost savings. Please checkout our careers page to see how you can help us!
# Sharing with the community
::authors
We had a couple of recent examples of our team sharing with the community that I wanted to highlight real quick.
One of our engineers recently spoke at [Elixir Wizards Conference 2021](https://www.youtube.com/playlist?list=PLCv-QRhbg07E3pe58eQauGibLv0A1fYm8\&ref=stord.engineering), you can checkout his talk [here](https://www.youtube.com/watch?v=SnoJmrBSAA4\&list=PLCv-QRhbg07E3pe58eQauGibLv0A1fYm8\&index=10\&ref=stord.engineering)
Another one of our engineers recently had one their open source contributions to New Relic's tracing agent for Elixir approved...yes!
And I recently had a chance to speak on SmartLogic's Elixir Wizards podcast... the main show was Maxim Fedorov, Core infrastructure Lead at What'sApp, and I was marked as a bonus mini-feature starting around 39 minutes in.... [https://www.facebook.com/smartlogic/posts/10157944281762676/](https://www.facebook.com/smartlogic/posts/10157944281762676/)
Go team!
# "What's your techstack?"
::authors
It is important to have a shared understanding of where we are headed as it pertains to the engineering practices at STORD. Whether you are a veteran team member or ramping-up as a new hire, you need to understand what we are working towards as an Engineering department.
The purpose of this article is to detail our vision for STORD's Engineering principles and practices.
# KEY PRINCIPLES
Systems View or OneOps - Emphasize the flow of work through the build and deployment value stream
* OneOps means we care about the flow of value from the company's hypothesis about our feature until it is delivered to our customers and providing value.
* OneOps means we all care and think about quality, deployment, reliability and maintenance just as much as we do about meeting the functional requirements.
* We take a systems view, we care about optimizing for the whole system and not for individual parts.
* We have agile process that allow us to stay nimble toward change, and we continue to look for ways to improve
Ownership - We own our code from our desktops to production, and we keep working to remove manual handoffs between teams (by automating or providing self-service tools).
* On-Call - We have a Engineering-wide system to handle, and take ownership over, production issues
* Documentation - We document our designs and interfaces to help others as well as ourselves (Entity Relationship Diagrams, Data Dictionary, API Documentation, Technical Design Notes, Playbooks, How-To Articles, etc.). We read feature documentation to best understand the 'the what' and 'the why' behind our work, and we do not hesitate to ask questions when we do not understand the purpose of our work
* SLOs and Error Budgets - We understand what is expected of our services availability, and when we expend our error budget, then we prioritize efforts to getting the service back into expected service levels
Continuous Delivery - continuous flow of work that is in a deployable state and constantly shipped to production
* Flow - Seek to reduce handoffs to QA or Operations or Security. Focus on automation and visibility (feedback) as code flows from desktop to production
* Enablement - Seek to enable teams with all the resources they need in order succeed on their own and to minimize handoffs. There will be experts in certain areas (front-end, operations, database, architecture, security) that help team members from not having to know everything. Best practices need to scalable and codified by providing turnkey services for teams in such a way that they team's work is still able to flow from initial branch to deployed in production
* Trunk-based development - avoid big merges and favor the flow of small batches of work by using abstractions, feature flags, and incremental database changes. Focus on small batches of work (avoid multitasking and large risks)
Feedback - Seek to provide feedback to enable flow
* Feedback is most valuable when it is fed back quickly. Getting feedback weeks or months later is less effective than right away.
* Testing at many levels (unit, integration, feature) is a great way to get feedback quickly and learn about how a change might have caused unintended consequences. How stressful would it be to work in a place that didn't have a strong culture for testing, and you just had to 'hope' that your code didn't break anything else?
* Examples of feedback - notices when tests fail, logs when there are issues, metrics on service health, current status of key process indicators (KPIs), and PR reviews before merging into master.
* For individuals seeking feedback, the best way to get feedback is to ask for it! It makes it easier for the feedback giver to be asked for it rather than for the feedback giver to find the opportune time and approach to give unsolicited feedback. Ask "What ways do I contribute best to the team and organization?" Ask "What can I do to be even more successful in helping the team and organization reach its goals?"
* Continuous Integration is about providing fast feedback on code quality and security after changes are made using tests at multiple levels (unit, integration, and feature tests) and linters
Empowered - emphasize experimentation and learning
* Learning is encouraged, failure is embraced, and team mates are not afraid to speak up
* Sharing lessons learned with one another.
* Empowered to do Pair programming, Mob programming, or even get or more people together to collaborate on a PR review. Feel empowered to do what you think is best for the team to achieve its sprint goals
* Meet as soon as possible after a major incident - blameless post-mortems so we can learn and prevent it from happening again; we are not there to point fingers and we are there to learn from our mistakes.
* Speak up about Enablers so we can keep improving and chip away at tech debt
* When failure is feared and avoided, then innovation is typically the first thing to suffer. To have an innovative culture, we need to embrace failure so we can learn from it.
* You are empowered to stop the flow of work at any time so that we can come together to fix a problem and learn as a team. It is beneficial to do that before moving forward with a defect, and potentially making the system worse, that will be realized in the future
* How do you incorporate experimentation? Focus on outcomes. Light from electricity was Edison's desired outcome...he went through hundreds of experiments to reach this outcome. Also, focus on tackling high risk efforts early and often. First stories of the sprint should often be the most risky. Because, the sooner you de-risk something the better. And oftentimes in our line of work, it is knowledge risk that we need to de-risk.
# Key practices that support our principles
## Continuous Integration / Continuous Delivery
We deploy during the work day, not at night or on the weekend
* Eliminate as much risk as possible.
* Keep batches of work small
We focus on automated tests as a key way to enable continuous integration and delivery --it's foundational, and delivers fast feedback.
* We know we've added enough tests when we've significantly reduced the probability of a customer finding a bug in production.
* Tests are run and must pass prior to landing in master
* "Hey, if you've written a function, it should have a test" -Halt
When we break the build, we make it a top priority to fix it.
* The build breaking is the equivalent of [pulling the andon cord](https://www.sixsigmadaily.com/what-is-an-andon-cord/?ref=stord.engineering), and needs to be fixed as a top priority.
When we find a bug, create a test for it first. We "shift-left", meaning if we have a feature test for it and still find a bug, then we create an integration or unit test for it to find the issue sooner
We "Fix forward" because we have a fast MTTR (mean-time-to-resolution)
* We have fast build times (code checkin to master to residing in production is less than 15 minutes), so we fix forward with quick mean-times-to-resolution
Writes end-to-end tests for the critical path flows -- our customers should not be finding bug before we do for features that are in the critical path of value for our customers
## [Trunk-based development](https://trunkbaseddevelopment.com/?ref=stord.engineering)
We favor short-lived feature branches (short = lives only for a couple of days at most).
* We create smaller stories to keep the branches open for short periods of time (measured by Cycle time -- time from branch created to merged), and this results in smaller PR reviews. Smaller PR reviews often result in deeper and more meaningful reviews compared to "monster" reviews.
We avoid long-lived branches and associated merge pains; reduce risk and keep the team flowing.
* Teams should become adept with the [branch by abstraction](https://trunkbaseddevelopment.com/branch-by-abstraction/?ref=stord.engineering) technique
* Other techniques for making small changes that build up to a big feature
> For the code, we use feature flags [feature flags](https://trunkbaseddevelopment.com/feature-flags/?ref=stord.engineering) in day to day development to allow for hedging on the order of releases. Set the feature flag at the high level of the entry point for the feature or enabler.
> For the database, we make [incremental changes](https://medium.com/better-programming/evolving-a-database-schema-10b7f4094d14?ref=stord.engineering) -- it's not easy at first, it takes practice; worth the effort and risk reduction to keep teams flowing. Enables deployments during the day
We ensure that when our pull-requests get merged into master (trunk), that they are in a production-ready state that can be deployed, not necessarily released, to production;
## Ownership - Teams Own their Services from their desktops to production
We care about deployability and releasability
* No manual steps, no asking operations "Can you just do X just this one time after this goes out?")...No, follow the established patterns for releases and don't consider a body of work done until it can be released without manual intervention.
We care about maintainability
* No manual steps to resolve issues, no asking operations "Can you please run this command one-time for us?" -- No, create tools to deal with maintenance needs
We care about performance
* We use infrastructure as Code to build our environments, and that includes the ability to stand up and tear down performance environments for teams to test performance of their services using production-like environments
We have a system to handle On-Call issues
* Playbooks are kept for the person On-Call to perform a set of steps based on the alerts that occur for the services they own
* Incident Reviews - Culture of blameless post-mortem for the purpose of learning and to avoid repeating the same mistake (typically improved by updating processes or adding more automation to a manual process).
* On-Call contacts outside of work hours should be exceptionally rare, because we don't lean on this system as a solution to on-going problems. Instead, we prioritized the items coming out of the On-Call Incident Reviews to automate and improve processes, so we don't get called again outside of regular hours
* When support issues come up within a sprint, the On-call person is the first person that the issue should be discussed with for research and triage.
We succeed with team members that are on-site and remote.
Cross team communication
* You are expected to communicate between teams -- not just with teams inside technology (engineering, product, design, integrations, sre), but also outside of technology (operations, sales, supplier relations, marketing, etc.)
* We value direct communication between the people that are doing the work and know the most about it. Talk directly to the people you need to talk with, AND loop in your manager and others that should be in the know so that they can help and support this cross-team effort.
Be Proactive
* You see, don't just say something, but do something -- take care of it, make a ticket, raise it as an issue
* Research something you don't know, take it upon yourself to understand how something works.
> "Okay, I was looking at this...I saw there was an error, an idea, or a library that would make it easier...and did it."
* There's the work that's in front of you, that you are expected to do and there's the freedom to do the right thing. This is why we don't have a large bug backlog, because we take care of our code as soon as possible.
## SLOs and Error Budgets
We have Service Level Objective (SLO) targets for service availability --- which is a percentage of the successful calls to a service divided by the total calls to that service. (scheduled maintenance, at least 1 week prior, does not count towards down time)
* The SLO targets should be set by the business owners. It is ultimately a business decision, not a technical one.
We understand that SLOs provide clear expectations from the business to the technology team on a Service's availability requirements.
We understand that "[error budgets](https://techbeacon.com/enterprise-it/why-you-need-error-budget-how-make-it-work?ref=stord.engineering)" are the cumulative amount of time that a Service is allowed to be unavailable. Once an error budget is exceeded (or prior to the error budget getting exceeded), the team must be given time to invest in Enablers instead of Features, so that the SLOs can be met again. *Otherwise, the business needs to lower the SLOs to increase the error budget.*
* ***New to the 'error budget' concept? It's a newish thing, so *[*here's a quick reference*](https://techbeacon.com/enterprise-it/why-you-need-error-budget-how-make-it-work?ref=stord.engineering)* for you to get up to speed on it.***
We need our services to have appropriate logging messages and levels (info, warnings, and errors), because this helps debug issues in production quickly.
We need our services to have operating metrics to track historic trends to help us with SLO tracking, post-mortems, and to foresee issues.
We understand that no service has a 100% availability, and therefore calls to services must be retried at least 2 times (so 3 attempts overall) with exponential backoff on each retry.
## Documentation
We codify our [Technical designs](https://stord.atlassian.net/wiki/spaces/Tech/pages/18677781/Technical+Design+Docs?ref=stord.engineering) with documentation to include the context and decisions made at that time.
We read product documentation (e.g., PRDs) so that we can understand the purpose of our work, and comment and ask questions when we do not understand the purpose of our work. We don't hesitate to get items clarified, because others might have a similar question to ours.
We document APIs for services when we agree upon interfaces, because it validates one another's understanding and allows both teams to reference this key interface that one or more teams rely on.
* Documenting service interfaces (and setting up consumer driven tests) is the best way to ensure that teams that are working in parallel are able to stay in sync.
* When you document your understanding between teams, then you have to update the interface documentation if any changes are made to the implementation, and then you can notify the other teams that depend on it.
The number one question
***
The number one question from candidates talking to our team for the first time is, "What's your tech stack?" To preempt that question, I'm going to break it down here for you, and provide some history or reasons why.
## Top to bottom
I like to answer this question by starting at the bottom of the stack, and working my way up the top.
## Infrastructure
We run on Google Cloud Platform. I've grown up with this cloud native platform since a year after it started, and I love the simple pricing as wall as the breadth of the platform. Google certainly had a lot of work to do in order to catch up to AWS and Microsoft, and it is squarely in 3rd place with a $11 billion in annual revenue run rate. The $100k in start-up credits certainly helped seal the deal!
We run Docker and Kubernetes (Google Kubernetes Engine - GKE) for our containers and container orchestration, along with Google Container Registry to store our container images. We also leverage Istio for our service mesh.
To enable infrastructure as code, we use Terraform and Helm charts (for GKE configuration). Continuous Integration and Continuous Deployment is handled by CircleCI and Harness, respectively.
## Storage
The key areas of storage for us are Cloud SQL (Postgres), BigQuery, and Google Cloud Storage (GCS). Love the ease of setting up these databases, having encryption at rest and intransit for all of our data, regular backups for disaster recovery, and replication to separate our transactional datastore (Cloud SQL) from our reporting and analytics data warehouse (BigQuery)
## Integration
Integration is a critical requirement in Supply Chains. We leverage Boomi for ETL between EDI, APIs and our normalized JSON data models -- both into and out of our application. Kafka handles our asynchronous communications between services and between the core application and our integration layer. We use Confluent Cloud for managing our Kafka Clusters.
## Application
We develop in Elixir (and use the MVC framework: Phoenix) on the backend, and React with Typescript on the front-end. Team has a number of Ruby developers, and when we took our MVP application far enough, and started rebuilding our platform starting in Jan 2020, we made the move to Elixir, which is a pretty natural migration for Ruby developers.
Both the integration layer and the front-end interact with our application over RESTful APIs that use the JSON:API specification for the request/response data structures.
We utilize a microservices architectural pattern because building platform to handle an end-to-end Cloud Supply Chain is far to complex and vast to do as a monolith.
Agile / Scrum
***
Our teams do daily standups to see how they can either ask for help or help others on the team to complete the sprint goals. Additionally, report on if any team members are blocked, or foresee any issues or risks with hitting the sprint goals.
Our teams groom stories with acceptance criteria that the team can understand well enough to point work -- there can be some unknowns, and that should be reflected in the point estimate, along with complexity.
* When the team just has no idea, then a spike story can be used to capture the necessary knowledge needed to point it.
* Teams have 'steps of doneness' to align on foundational acceptance criteria, what it means for a story/task to be done, that applies to all stories/tasks (rather than the team adding such foundational ACs to every story/task)
We use story points to represent the size of an effort, because humans are not good at estimating time, but are good at estimating relative size (relative, as in relation to other stories the team has done before). Story size is based on three items: level-of-effort, complexity, and risk/unknowns.
Our teams plan sprints based on the goals of the sprint, and average team velocity -- the empirical story point velocity that the team has performed in the past, on average.
* Goal is to have consistency in points completed per sprint, not to have an ever increasing number of points per sprint get completed.
* Do take into account planned time off or holidays when planning a sprint
Our teams groom entire epics of work so that they can provide an estimate of when the work will get completed based on their backlog and average sprint velocity.
Our teams demonstrate their work to the key stakeholders to demonstrate the work completed, and to get feedback from working software
Our teams perform retrospectives to learn from one another.
* We try to make one improvement per sprint.
* Making a 2 percent improvement per sprint would net a 52% improvement each year for an entire team of people, and that's not including compounding, so it's actually higher than that.
## One last thing..
It is important to have a shared understanding of where we are headed as it pertains to the engineering practices at STORD. Whether you are a veteran team member or ramping-up as a new hire, you need to understand what we are working towards as an Engineering department. Please see and understand where we are headed and help us get there as fast as we can!
# Vision for STORD Engineering: Principles and Practices
::authors
It is important to have a shared understanding of where we are headed as it pertains to the engineering practices at STORD. Whether you are a veteran team member or ramping-up as a new hire, you need to understand what we are working towards as an Engineering department.
The purpose of this article is to detail our vision for STORD's Engineering principles and practices.
# KEY PRINCIPLES
Systems View or OneOps - Emphasize the flow of work through the build and deployment value stream
* OneOps means we care about the flow of value from the company's hypothesis about our feature until it is delivered to our customers and providing value.
* OneOps means we all care and think about quality, deployment, reliability and maintenance just as much as we do about meeting the functional requirements.
* We take a systems view, we care about optimizing for the whole system and not for individual parts.
* We have agile process that allow us to stay nimble toward change, and we continue to look for ways to improve
Ownership - We own our code from our desktops to production, and we keep working to remove manual handoffs between teams (by automating or providing self-service tools).
* On-Call - We have a Engineering-wide system to handle, and take ownership over, production issues
* Documentation - We document our designs and interfaces to help others as well as ourselves (Entity Relationship Diagrams, Data Dictionary, API Documentation, Technical Design Notes, Playbooks, How-To Articles, etc.). We read feature documentation to best understand the 'the what' and 'the why' behind our work, and we do not hesitate to ask questions when we do not understand the purpose of our work
* SLOs and Error Budgets - We understand what is expected of our services availability, and when we expend our error budget, then we prioritize efforts to getting the service back into expected service levels
Continuous Delivery - continuous flow of work that is in a deployable state and constantly shipped to production
* Flow - Seek to reduce handoffs to QA or Operations or Security. Focus on automation and visibility (feedback) as code flows from desktop to production
* Enablement - Seek to enable teams with all the resources they need in order succeed on their own and to minimize handoffs. There will be experts in certain areas (front-end, operations, database, architecture, security) that help team members from not having to know everything. Best practices need to scalable and codified by providing turnkey services for teams in such a way that they team's work is still able to flow from initial branch to deployed in production
* Trunk-based development - avoid big merges and favor the flow of small batches of work by using abstractions, feature flags, and incremental database changes. Focus on small batches of work (avoid multitasking and large risks)
Feedback - Seek to provide feedback to enable flow
* Feedback is most valuable when it is fed back quickly. Getting feedback weeks or months later is less effective than right away.
* Testing at many levels (unit, integration, feature) is a great way to get feedback quickly and learn about how a change might have caused unintended consequences. How stressful would it be to work in a place that didn't have a strong culture for testing, and you just had to 'hope' that your code didn't break anything else?
* Examples of feedback - notices when tests fail, logs when there are issues, metrics on service health, current status of key process indicators (KPIs), and PR reviews before merging into master.
* For individuals seeking feedback, the best way to get feedback is to ask for it! It makes it easier for the feedback giver to be asked for it rather than for the feedback giver to find the opportune time and approach to give unsolicited feedback. Ask "What ways do I contribute best to the team and organization?" Ask "What can I do to be even more successful in helping the team and organization reach its goals?"
* Continuous Integration is about providing fast feedback on code quality and security after changes are made using tests at multiple levels (unit, integration, and feature tests) and linters
Empowered - emphasize experimentation and learning
* Learning is encouraged, failure is embraced, and team mates are not afraid to speak up
* Sharing lessons learned with one another.
* Empowered to do Pair programming, Mob programming, or even get or more people together to collaborate on a PR review. Feel empowered to do what you think is best for the team to achieve its sprint goals
* Meet as soon as possible after a major incident - blameless post-mortems so we can learn and prevent it from happening again; we are not there to point fingers and we are there to learn from our mistakes.
* Speak up about Enablers so we can keep improving and chip away at tech debt
* When failure is feared and avoided, then innovation is typically the first thing to suffer. To have an innovative culture, we need to embrace failure so we can learn from it.
* You are empowered to stop the flow of work at any time so that we can come together to fix a problem and learn as a team. It is beneficial to do that before moving forward with a defect, and potentially making the system worse, that will be realized in the future
* How do you incorporate experimentation? Focus on outcomes. Light from electricity was Edison's desired outcome...he went through hundreds of experiments to reach this outcome. Also, focus on tackling high risk efforts early and often. First stories of the sprint should often be the most risky. Because, the sooner you de-risk something the better. And oftentimes in our line of work, it is knowledge risk that we need to de-risk.
# Key practices that support our principles
## Continuous Integration / Continuous Delivery
We deploy during the work day, not at night or on the weekend
* Eliminate as much risk as possible.
* Keep batches of work small
We focus on automated tests as a key way to enable continuous integration and delivery --it's foundational, and delivers fast feedback.
* We know we've added enough tests when we've significantly reduced the probability of a customer finding a bug in production.
* Tests are run and must pass prior to landing in master
* "Hey, if you've written a function, it should have a test" -Halt
When we break the build, we make it a top priority to fix it.
* The build breaking is the equivalent of [pulling the andon cord](https://www.sixsigmadaily.com/what-is-an-andon-cord/?ref=stord.engineering), and needs to be fixed as a top priority.
When we find a bug, create a test for it first. We "shift-left", meaning if we have a feature test for it and still find a bug, then we create an integration or unit test for it to find the issue sooner
We "Fix forward" because we have a fast MTTR (mean-time-to-resolution)
* We have fast build times (code checkin to master to residing in production is less than 15 minutes), so we fix forward with quick mean-times-to-resolution
Writes end-to-end tests for the critical path flows -- our customers should not be finding bug before we do for features that are in the critical path of value for our customers
## [Trunk-based development](https://trunkbaseddevelopment.com/?ref=stord.engineering)
We favor short-lived feature branches (short = lives only for a couple of days at most).
* We create smaller stories to keep the branches open for short periods of time (measured by Cycle time -- time from branch created to merged), and this results in smaller PR reviews. Smaller PR reviews often result in deeper and more meaningful reviews compared to "monster" reviews.
We avoid long-lived branches and associated merge pains; reduce risk and keep the team flowing.
* Teams should become adept with the [branch by abstraction](https://trunkbaseddevelopment.com/branch-by-abstraction/?ref=stord.engineering) technique
* Other techniques for making small changes that build up to a big feature
> For the code, we use feature flags [feature flags](https://trunkbaseddevelopment.com/feature-flags/?ref=stord.engineering) in day to day development to allow for hedging on the order of releases. Set the feature flag at the high level of the entry point for the feature or enabler.
> For the database, we make [incremental changes](https://medium.com/better-programming/evolving-a-database-schema-10b7f4094d14?ref=stord.engineering) -- it's not easy at first, it takes practice; worth the effort and risk reduction to keep teams flowing. Enables deployments during the day
We ensure that when our pull-requests get merged into master (trunk), that they are in a production-ready state that can be deployed, not necessarily released, to production;
## Ownership - Teams Own their Services from their desktops to production
We care about deployability and releasability
* No manual steps, no asking operations "Can you just do X just this one time after this goes out?")...No, follow the established patterns for releases and don't consider a body of work done until it can be released without manual intervention.
We care about maintainability
* No manual steps to resolve issues, no asking operations "Can you please run this command one-time for us?" -- No, create tools to deal with maintenance needs
We care about performance
* We use infrastructure as Code to build our environments, and that includes the ability to stand up and tear down performance environments for teams to test performance of their services using production-like environments
We have a system to handle On-Call issues
* Playbooks are kept for the person On-Call to perform a set of steps based on the alerts that occur for the services they own
* Incident Reviews - Culture of blameless post-mortem for the purpose of learning and to avoid repeating the same mistake (typically improved by updating processes or adding more automation to a manual process).
* On-Call contacts outside of work hours should be exceptionally rare, because we don't lean on this system as a solution to on-going problems. Instead, we prioritized the items coming out of the On-Call Incident Reviews to automate and improve processes, so we don't get called again outside of regular hours
* When support issues come up within a sprint, the On-call person is the first person that the issue should be discussed with for research and triage.
We succeed with team members that are on-site and remote.
Cross team communication
* You are expected to communicate between teams -- not just with teams inside technology (engineering, product, design, integrations, sre), but also outside of technology (operations, sales, supplier relations, marketing, etc.)
* We value direct communication between the people that are doing the work and know the most about it. Talk directly to the people you need to talk with, AND loop in your manager and others that should be in the know so that they can help and support this cross-team effort.
Be Proactive
* You see, don't just say something, but do something -- take care of it, make a ticket, raise it as an issue
* Research something you don't know, take it upon yourself to understand how something works.
> "Okay, I was looking at this...I saw there was an error, an idea, or a library that would make it easier...and did it."
* There's the work that's in front of you, that you are expected to do and there's the freedom to do the right thing. This is why we don't have a large bug backlog, because we take care of our code as soon as possible.
## SLOs and Error Budgets
We have Service Level Objective (SLO) targets for service availability --- which is a percentage of the successful calls to a service divided by the total calls to that service. (scheduled maintenance, at least 1 week prior, does not count towards down time)
* The SLO targets should be set by the business owners. It is ultimately a business decision, not a technical one.
We understand that SLOs provide clear expectations from the business to the technology team on a Service's availability requirements.
We understand that "[error budgets](https://techbeacon.com/enterprise-it/why-you-need-error-budget-how-make-it-work?ref=stord.engineering)" are the cumulative amount of time that a Service is allowed to be unavailable. Once an error budget is exceeded (or prior to the error budget getting exceeded), the team must be given time to invest in Enablers instead of Features, so that the SLOs can be met again. *Otherwise, the business needs to lower the SLOs to increase the error budget.*
* ***New to the 'error budget' concept? It's a newish thing, so *[*here's a quick reference*](https://techbeacon.com/enterprise-it/why-you-need-error-budget-how-make-it-work?ref=stord.engineering)* for you to get up to speed on it.***
We need our services to have appropriate logging messages and levels (info, warnings, and errors), because this helps debug issues in production quickly.
We need our services to have operating metrics to track historic trends to help us with SLO tracking, post-mortems, and to foresee issues.
We understand that no service has a 100% availability, and therefore calls to services must be retried at least 2 times (so 3 attempts overall) with exponential backoff on each retry.
## Documentation
We codify our [Technical designs](https://stord.atlassian.net/wiki/spaces/Tech/pages/18677781/Technical+Design+Docs?ref=stord.engineering) with documentation to include the context and decisions made at that time.
We read product documentation (e.g., PRDs) so that we can understand the purpose of our work, and comment and ask questions when we do not understand the purpose of our work. We don't hesitate to get items clarified, because others might have a similar question to ours.
We document APIs for services when we agree upon interfaces, because it validates one another's understanding and allows both teams to reference this key interface that one or more teams rely on.
* Documenting service interfaces (and setting up consumer driven tests) is the best way to ensure that teams that are working in parallel are able to stay in sync.
* When you document your understanding between teams, then you have to update the interface documentation if any changes are made to the implementation, and then you can notify the other teams that depend on it.
## Agile / Scrum
Our teams do daily standups to see how they can either ask for help or help others on the team to complete the sprint goals. Additionally, report on if any team members are blocked, or foresee any issues or risks with hitting the sprint goals.
Our teams groom stories with acceptance criteria that the team can understand well enough to point work -- there can be some unknowns, and that should be reflected in the point estimate, along with complexity.
* When the team just has no idea, then a spike story can be used to capture the necessary knowledge needed to point it.
* Teams have 'steps of doneness' to align on foundational acceptance criteria, what it means for a story/task to be done, that applies to all stories/tasks (rather than the team adding such foundational ACs to every story/task)
We use story points to represent the size of an effort, because humans are not good at estimating time, but are good at estimating relative size (relative, as in relation to other stories the team has done before). Story size is based on three items: level-of-effort, complexity, and risk/unknowns.
Our teams plan sprints based on the goals of the sprint, and average team velocity -- the empirical story point velocity that the team has performed in the past, on average.
* Goal is to have consistency in points completed per sprint, not to have an ever increasing number of points per sprint get completed.
* Do take into account planned time off or holidays when planning a sprint
Our teams groom entire epics of work so that they can provide an estimate of when the work will get completed based on their backlog and average sprint velocity.
Our teams demonstrate their work to the key stakeholders to demonstrate the work completed, and to get feedback from working software
Our teams perform retrospectives to learn from one another.
* We try to make one improvement per sprint.
* Making a 2 percent improvement per sprint would net a 52% improvement each year for an entire team of people, and that's not including compounding, so it's actually higher than that.
## One last thing..
It is important to have a shared understanding of where we are headed as it pertains to the engineering practices at STORD. Whether you are a veteran team member or ramping-up as a new hire, you need to understand what we are working towards as an Engineering department. Please see and understand where we are headed and help us get there as fast as we can!
# What exactly is 'The Cloud Supply Chain' that STORD is building?
::authors
STORD is focused on leading the paradigm shift to the Cloud Supply Chain -- it is currently our #1 Tenet; our tenets drive our quarterly goals across the company.
Okay, sounds pretty cool, right? But you might be wondering, "What exactly is the Cloud Supply Chain?" And you wouldn't be alone because it was a top question from our engineering team members as well.
Given this is our #1 Tenet, I knew that I had to address this question in our Technology All-Hands meeting, which we have every two months to ensure alignment on key topics such as this one. This article walks through how I answered this question during the recent Technology All-Hands meeting.

Figure 1: Remember the shift to Cloud Computing?
First, I started off with a whimsical comic strip (see Figure 1). It's a comic strip that I made, so it's probably not very funny, but I've learned that we humans pay more attention to words in pictures, so I went for it!
The point here is that we should think about the shift to the Cloud Supply Chain in very much the same way that we made the shift to Cloud Computing!
## I still remember! We used to actually setup servers!
Shortly after I finished college in 1996, I then worked at internet startup in 1997. As software engineers, we used to set up servers!! I'm serious!
* We had to make a business case for another server, and get the purchase order approved
* We had to purchase the server
* Then wait weeks for the server to arrive
* When it arrived, then we had to get people to help move it into the server room (which, of course, means that we had a server room and a dedicated internet connection)
* Then we had to decide how to setup the disc array. RAID 0+1, anyone?
* Next we install the OS, and patch it
* Configured the network cards
* Got it on the network, punched a hole through the firewall
* Created the system users and groups, and set the permissions
* Started installing all the software necessary (utilities, web servers, databases, certificates, etc.)
* And don't forget to schedule backups!
IT TOOK A DAYS \*(weeks if you including getting the approval and waiting for the delivery) \*!!

Image 1: Are you kidding me?!
WHY did we go through that pain? You know the real reason? So that we could run our Web application on top of that Server, that's why!! We didn't want a server, what we really wanted was to run our Web application that we were building to delivery value to our customers.
TODAY....you can get a server setup in one command using AWS, Google Cloud Platform, or Azure. It literally takes you minutes to setup a server today.
Cloud computing
* YOU pay for what you use
* YOU focus on your business -- meaning, in this example, you focus on that Web Application not on setting up servers.
But while it might seem like a no-brainer today to use Cloud Computing, think about that mindshift back then when it was new. If your server was down, then your Web application was down, and your customers upset (as well as lost customers). That's no small ask to have companies trust some new offering from someone else to handle the availability and reliability of the very servers that your Web application needs to function.
That same thinking applies to the Cloud Supply Chain! In fact, ...
### That's what the Cloud Supply Chain is all about!
Product companies that sell physical products WANT to focus on delighting their customers. They don't want to focus on the headaches of managing a supply chain.
Pretend for a moment, that you are the CEO of a company that makes products. You notice that your Customers have the same problem...and you have the solution!
* You make a product to solve a problem
* You market your solution!
* People like your solution and you are selling it!
* SO MUCH FUN!
* ...but now what? There's a lot to a Supply Chain

Figure 2: There's a lot to a Supply Chain!
Ready to deal with the following Supply Chain challenges?
* Finding warehouses to use that are close to your customers and keep your shipping costs down. You'll likely need multiple warehouse locations to keep shipping costs down and to meet your Customer's expectation to ship next day or two-day.
* You need to hire a freight company to move your product from the factory or port to these warehouses on a regular basis.
* Don't forget to keep track of inventory at all these locations
* Be sure to have a consolidated view of your orders and inventory across your eCommerce system, your marketplaces (e.g., selling on Amazon and Walmart), your B2B customers and more.
* What about returns? Do you have a plan to handle them as well?
### The Cloud Supply Chain is what STORD does best, so our Customers can focus on what they do best - selling their Product
For a monthly, pay-as-you-go fee, STORD takes care of our Customer's Supply Chain challenges.
* STORD centralizes all your orders (across eCommerce, marketplaces, and ERPs) into one Central Orders Hub system
* STORD decides which warehouse to use to ship one or more line items in that order using our Distributed Order Management and Inventory Management systems
* STORD will pick, pack, and ship that product to include branding the labels and packaging using our Facility Management systems
* STORD will tell you when to order more of a product so that you don't run out, using our Demand Planning systems
### Connect once, ship many
You only need to connect to STORD once, and we'll take care of the rest. We have customers that have over 36 warehouse with us, and are still using the same single connection to STORD.
TENET #1: We must lead the paradigm shift to the Cloud Supply Chain.
Here are some concrete examples of the type of mind shifts our Customers make when they select STORD as their Cloud Supply Chain
| "Where should I put my warehouse?" | →Mindshift→ | "How can I service my customers with same day and two day delivery?" |
| "what is my capital expenditure to add more capacity in freight and warehousing?" | →Mindshift→ | "How can I grow my revenue and reduce fixed costs?" |
| "How long will it take to setup a new warehouse?" | →Mindshift→ | "How can I leverage the Cloud Supply Chain to innovate and compete?" |
### Cloud Supply Chain Characteristics
* Pay-as-you-go pricing → Pay us monthly and per order delivered
* No fixed capex → Elastic capacity to scale up or down with STORD
* Faster time to market → Delivery anywhere in the US; Setup in days
* Speed of innovation → Spend more time in key areas of your business
* Focus on your competitive advantage → Delight your customers
## Do you know what 'The Cloud Supply Chain' means now?
The intent of this article was to explain what is 'The Cloud Supply Chain.' Hopefully this article helped you better understand the paradigm shift our Customers are making when they choose STORD to run their Cloud Supply Chain.
### Ready to help us build a Cloud Supply Chain?
We have a great team and we are making great strides. We are also experiencing triple digit, year-over-year growth due the acceleration of ecommerce by COVID. Having a Cloud Supply Chain gives companies key business capabilities -- speed, flexibility, and cost savings. Please checkout [our careers page](https://www.stord.com/careers) to see how you can help us!
# What's the culture like at Stord?
::authors
I prioritize the blog posts based on the questions I get during the interview process. "What's the culture like on the Stord engineering team?" is a frequently asked question that is due for a blog post, and here it is!
This topic about culture also came up internally when I was chatting with a engineer about a candidate we made an offer to recently. The candidate had another offer so we were not sure if they would join us. The engineer was excited about this candidate and asked if I could send a note about the intangibles of working at Stord, like our culture. This engineer went on to say that our culture is a reason they picked Stord over their other offers. I instantly asked this person to tell me how they would describe it, and they responded promptly over Slack with...
* Autonomy, and with a strong sense of direction from the leadership team
* Challenging, solving actual problems that impact the business and our ability to deliver
* Growth, our problems in one year will be completely different from those we have today, prevents stagnation and acceptance of the status quo
* Teamwork or enablement "never heard the one word answer of 'no' when presenting a suggestion, we do not have that type of culture."
I was so happy to get this in writing, because I knew it was going to make creating this blog post that much easier, but also because it was from someone on the team experiencing the culture! My additions to this list would be that we are also a low-ego and supportive group that is focused on delivering value to our customers.
One thing that we are doing differently at Stord than I have seen elsewhere, is that we host 'office hours' regularly across multiple disciplines. If you are stuck or just wanting to learn more from experts, then you can join office hours (we have a Google Calendar that lists the office hours and the associated Zoom links to join) for:
* Elixir development
* Site Reliability Engineering / DevOps
* Frontend development (React) and Cypress Testing
* Application architecture
* and Visual Design
Nearly each of these listed is provided at least once a day, with some of them twice a day. People just show up and ask questions of the expert hosts. And if nobody shows up, then there are typically a couple experts hosts that join office hours, so they just collaborate on some key items or challenges they have been working on. Office Hours is a great demonstration of the supportive aspect of our culture.
## Ready to help us build a Cloud Supply Chain?
I hope this blog post gives you some insight into our culture here at Stord. We have a great team and we are making great strides. We are also experiencing triple digit, year-over-year growth due the acceleration of ecommerce by the pandemic. Shippers need a Cloud Supply Chain because it provides their customers -- speed, flexibility, and cost savings.
Please checkout [our careers page](https://www.stord.com/careers) to see how you can help us!
# Why did STORD choose Elixir?
::authors
A top 5 question from candidates is ‘Why did you choose Elixir?' To answer this question, I was able to dig up the email that our CTO sent to the team in January 2020, the same month we decided to kick off a new greenfield effort to construct our Cloud Supply Chain platform that STORD continues to build upon today.
Here it is...
\========================
From: Jacob Boudreau
Date: Jan 15, 2020
To: Stord Engineering
Hey Team,
As you may all know, with the new work to build out a Cloud Supply Chain platform, we opened the possibility of using another language and framework besides Ruby and Rails. Over the past couple of weeks, I have been weighing this decision heavily to determine our path forward.
After a significant amount of review of possible language choices for the next adventure in STORD's future, I have concluded we will move forward with [Elixir](https://elixir-lang.org/?ref=stord.engineering) (+ the [Phoenix framework](http://www.phoenixframework.org/?ref=stord.engineering)) for the work of building out the Cloud Supply Chain.
This decision came after hearing a multitude of thoughts and inputs from a variety of individuals (including several of you!), exploring ecosystems of a variety of languages and frameworks, looking at language and framework trends from various surveys and reports over the prior 5 years (including Octoverse, StackOverflow, IEEE, and others), and personally experimenting with the languages and frameworks. These languages and frameworks included: Ruby/Ruby on Rails, Python, Go and various associated frameworks (Go-kit, Martini, Gin), Javascript and Node, Typescript and Node, and Elixir and Phoenix.
There were a variety of takeaways, but the some of the reasoning for moving forward with Elixir are briefly jotted below:
* Scalability - The models of concurrency and built-in distribution mechanisms of Erlang, that Elixir is built on, allow for significant scalability.
* Flexibility - Elixir is a versatile language --- practical for web applications (with the [Phoenix framework](http://www.phoenixframework.org/?ref=stord.engineering)), for real-time systems, and for embedded systems (with [Nerves](https://nerves-project.org/?ref=stord.engineering)).
* Short-term and Long-term Productivity (On-going developer happiness) - Elixir was created by a member of the Rails core team (José Valim) and brings with it some of the syntactical pleasantries of Ruby (and Phoenix carries similarities to Rails and follows an MVC structure), but differently than Ruby some of its inherent paradigms force a simpler, cleaner, explicit code base.
* Optimized for Distributed Systems - Elixir is built on-top of Erlang which was purpose built for massive, fault-tolerant, distributed systems.
* Paradigms - Elixir drives towards modular, self-contained code and Domain Driven Design with various paradigms and capabilities it employs.
While the above were some of the various reasons I believe Elixir will work well for us, I would be remiss to not mention that those are by no means indicative that Elixir is the safest choice. Arguably all other languages explored would be safer from an ecosystems/wide-scale adoption perspective. However, given the space to optimize for the next 5-10 years while balancing immediate quick iteration, I believe Elixir will put us in a strong technical position irrespective of relative positioning to other languages. I see us building strength in the paradigms and benefits of Elixir becoming an underlying technical advantage of STORD.
I wanted to provide notice as early as the decision was final to provide everyone time to explore Elixir and Phoenix; in the meantime, please don't hesitate to message me with any questions on the decision. Given that this will be new territory for basically the entire team, I want to ensure everyone's equipped with the context and knowledge to succeed. We will ensure the provision of material / resources to help each of you quickly ramp in this new space.
Excited for us to excel and accelerate into building a leading industry platform to lead the paradigm shift to the Cloud Supply Chain.
Onward,
Jacob